오늘은 C# 3주차 강의 마지막에 있는 숙제를 했다.
오늘의 목표는 스네이크 게임, 블랙잭 게임 두가지를 하는 것이었는데,
스네이크 게임 만들기는 아직 내가 배운 내용으로는 조금 부족하다고 생각했다.
내일 Unity_2기 동기생의 스네이크 게임 발표가 있는데, 그 발표를 듣고 방향성을 정해야할 것 같다.
그래서 먼저 블랙잭 게임을 한번 만들어봤다.
시작하기에 앞서, 블랙잭 게임을 처음 들어봤다.
그래서 구글링을 통해 게임 규칙을 찾아 봤다.
● 블랙잭 게임 Rule
1. 딜러와 플레이어의 각각 카드 숫자 합이 높으쪽이 승리합니다.
2. 우선 플레이어에게 카드 2장, 딜러에게 카드 1장을 줍니다.
3. 카드는 A 1개, 2 ~ 9 가 1개 씩, 10 이 4장 있습니다.
4. A 카드를 뽑으면 카드의 숫자를 1이나 11 중 선택할 수 있습니다.
5. 한장을 더 받으려면 Hit, 그만 받으려면 Stay를 선택합니다.
6. 이때, 플레이어의 카드의 합이 21이 넘으면 패배합니다.
7. Stay를 선택하면 딜러가 딜러의 카드의 합이 17 이상일 때 까지 카드를 뽑습니다.
8. 딜러와 플레이어의 카드 숫자 합을 비교합니다.
● 전체코드
using System.Collections.Generic;
internal class Program
{
static int input;
static string[] cards = { "A", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "10", "10", "10" };
static string empty;
static int playerCardSum = 0;
static int dealerCardSum = 0;
static List<string> playerCards = new List<string>();
static List<string> dealerCards = new List<string>();
static void Main(string[] args)
{
Console.WriteLine("=======================================================================================");
Console.WriteLine("<블랙잭 RULE>");
Console.WriteLine("1. 딜러와 플레이어의 각각 카드 숫자 합이 높으쪽이 승리합니다.");
Console.WriteLine("2. 우선 플레이어에게 카드 2장, 딜러에게 카드 1장을 줍니다.");
Console.WriteLine("3. 카드는 A 1개, 2 ~ 9 가 1개 씩, 10 이 4장 있습니다.");
Console.WriteLine("4. A 카드를 뽑으면 카드의 숫자를 1이나 11 중 선택할 수 있습니다.");
Console.WriteLine("5. 한장을 더 받으려면 Hit, 그만 받으려면 Stay를 선택합니다.");
Console.WriteLine("6. 이때, 플레이어의 카드의 합이 21이 넘으면 패배합니다.");
Console.WriteLine("7. Stay를 선택하면 딜러가 딜러의 카드의 합이 17 이상일 때 까지 카드를 뽑습니다.");
Console.WriteLine("8. 딜러와 플레이어의 카드 숫자 합을 비교합니다.");
Console.WriteLine("=======================================================================================");
while (true)
{
Console.WriteLine("게임을 시작하려면 1을 입력해주세요.");
input = int.Parse(Console.ReadLine());
if (input == 1)
{
Console.Clear();
break;
}
else
{
continue;
}
}
Console.WriteLine("=======================================================================================");
Random random = new Random();
// 카드 셔플
for (int i = 0; i < cards.Length; i++)
{
int randomNum = random.Next(0, cards.Length); // 0 ~ 13 중 랜덤 생성
empty = cards[i];
cards[i] = cards[randomNum];
cards[randomNum] = empty;
}
// 플레이어 두장 뽑음
PlayerCardDraw(cards[0]);
PlayerCardDraw(cards[1]);
// 딜러 한장 뽑음
DealerCardDraw(cards[2]);
int num = 3; // 3번째 카드부터 뽑을 수 있음
// 플레이어 턴
Console.WriteLine("플레이어의 차례입니다.");
while (true)
{
Console.WriteLine("한장을 더 받으려면 1, 그만 받으려면 2를 입력해주세요.");
input = int.Parse(Console.ReadLine());
if (input == 1)
{
Console.WriteLine("=======================================================================================");
PlayerCardDraw(cards[num]);
if (playerCardSum > 21) return;
Console.WriteLine("=======================================================================================");
num++;
continue;
}
else if (input == 2)
{
break;
}
else
{
continue;
}
}
// 딜러 턴
Console.Clear();
Console.WriteLine("=======================================================================================");
Console.WriteLine("딜러의 차례입니다. 카드의 합이 17이상 일때까지 뽑습니다.");
while (true)
{
DealerCardDraw(cards[num]);
num++;
if (dealerCardSum >= 17)
{
break;
}
}
Console.Write("플레이어 카드 : ");
foreach (string card in playerCards)
{
Console.Write(card + " ");
}
Console.WriteLine();
Console.WriteLine($"플레이어 카드의 합 : {playerCardSum}");
Console.WriteLine();
Console.Write("딜러 카드 : ");
foreach (string card in dealerCards)
{
Console.Write(card + " ");
}
Console.WriteLine();
Console.WriteLine($"딜러 카드의 합 : {dealerCardSum}");
if(playerCardSum > dealerCardSum)
{
Console.WriteLine("플레이어가 승리하였습니다.");
}
else if (playerCardSum > dealerCardSum)
{
Console.WriteLine("무승부입니다.");
}
else
{
Console.WriteLine("딜러가 승리하였습니다.");
}
return;
}
static void PlayerCardDraw(string str)
{
Console.WriteLine("플레이어가 카드 1장을 뽑습니다.");
playerCards.Add(str);
if (str == "A")
{
while (true)
{
Console.WriteLine("A 카드를 뽑았습니다. 선택할 숫자를 1과 11중 입력해주세요.");
Console.WriteLine($"플레이어 카드의 합 : {playerCardSum}");
input = int.Parse(Console.ReadLine());
if (input == 1)
{
playerCardSum++;
break;
}
else if (input == 11)
{
playerCardSum += 11;
break;
}
else continue;
}
}
else
{
playerCardSum += int.Parse(str);
}
Console.Write("플레이어 카드 : ");
foreach (string card in playerCards)
{
Console.Write(card + " ");
}
Console.WriteLine();
Console.WriteLine($"플레이어 카드의 합 : {playerCardSum}");
Console.WriteLine();
if (playerCardSum > 21)
{
Console.WriteLine("카드의 합이 21이 넘었습니다. 딜러가 승리하였습니다.");
return;
}
}
static void DealerCardDraw(string str)
{
Console.WriteLine("딜러가 카드 1장을 뽑습니다.");
dealerCards.Add(str);
if (str == "A")
{
Console.WriteLine("=======================================================================================");
if (dealerCardSum + 11 < 17)
{
dealerCardSum += 11;
}
else
{
dealerCardSum += 1;
}
}
else
{
dealerCardSum += int.Parse(str);
}
Console.Write("딜러 카드 : ");
foreach (string card in dealerCards)
{
Console.Write(card + " ");
}
Console.WriteLine();
Console.WriteLine($"딜러 카드의 합 : {dealerCardSum}");
Console.WriteLine("=======================================================================================");
}
}
● 어려웠던 것
1. 카드셔플
static string[] cards =
{ "A", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "10", "10", "10" };
for (int i = 0; i < cards.Length; i++)
{
int randomNum = random.Next(0, cards.Length); // 0 ~ 13 중 랜덤 생성
empty = cards[i];
cards[i] = cards[randomNum];
cards[randomNum] = empty;
}
우선 카드숫자의 합계를 계산해야하기 때문에 14개의 string을 배열로 할당했다.
이 카드들을 셔플해야하는데, 여러가지 방법을 시도하다가 아주 간단한 방법을 찾았다.
랜덤값을 받아서, 배열의 첫번째부터 순서대로 랜덤값 순서에 있는 배열과 교환을하면 된다.
카드셔플을 구현하는데 가장 많은 시간이 걸렸던 것 같다.
2. 카드뽑기
static void PlayerCardDraw(string str)
{
Console.WriteLine("플레이어가 카드 1장을 뽑습니다.");
playerCards.Add(str);
if (str == "A")
{
while (true)
{
Console.WriteLine("A 카드를 뽑았습니다. 선택할 숫자를 1과 11중 입력해주세요.");
Console.WriteLine($"플레이어 카드의 합 : {playerCardSum}");
input = int.Parse(Console.ReadLine());
if (input == 1)
{
playerCardSum++;
break;
}
else if (input == 11)
{
playerCardSum += 11;
break;
}
else continue;
}
}
else
{
playerCardSum += int.Parse(str);
}
Console.Write("플레이어 카드 : ");
foreach (string card in playerCards)
{
Console.Write(card + " ");
}
Console.WriteLine();
Console.WriteLine($"플레이어 카드의 합 : {playerCardSum}");
Console.WriteLine();
if (playerCardSum > 21)
{
Console.WriteLine("카드의 합이 21이 넘었습니다. 딜러가 승리하였습니다.");
return;
}
}
static void DealerCardDraw(string str)
{
Console.WriteLine("딜러가 카드 1장을 뽑습니다.");
dealerCards.Add(str);
if (str == "A")
{
Console.WriteLine("=======================================================================================");
if (dealerCardSum + 11 < 17)
{
dealerCardSum += 11;
}
else
{
dealerCardSum += 1;
}
}
else
{
dealerCardSum += int.Parse(str);
}
Console.Write("딜러 카드 : ");
foreach (string card in dealerCards)
{
Console.Write(card + " ");
}
Console.WriteLine();
Console.WriteLine($"딜러 카드의 합 : {dealerCardSum}");
Console.WriteLine("=======================================================================================");
}
카드뽑기는 플레이어와 딜러 두가지로 함수로 정리했다.
두가지를 나눈 이유는 A카드를 뽑았을 때, 플레이어는 1과 11중 카드숫자를 내가 선택하도록 하였고,
딜러에게는 간단하게 수식으로 설정해서 간단한 AI(?)를 만들었다. (사실 딜러의 승률이 높진않다...)
그 외에는 카드의 순서대로 뽑아서 각각 리스트에 추가하는 것으로 비슷하게 구현했다.
3. string값 입력받기
while (true)
{
Console.WriteLine("게임을 시작하려면 1을 입력해주세요.");
input = int.Parse(Console.ReadLine());
if (input == 1)
{
Console.Clear();
break;
}
else
{
continue;
}
}
// 플레이어 턴
Console.WriteLine("플레이어의 차례입니다.");
while (true)
{
Console.WriteLine("한장을 더 받으려면 1, 그만 받으려면 2를 입력해주세요.");
input = int.Parse(Console.ReadLine());
if (input == 1)
{
Console.WriteLine("=======================================================================================");
PlayerCardDraw(cards[num]);
if (playerCardSum > 21) return;
Console.WriteLine("=======================================================================================");
num++;
continue;
}
else if (input == 2)
{
break;
}
else
{
continue;
}
}
다음과 같이 게임시작 문구를 띄우고 입력을 받아서 게임이 시작되도록 했다.
처음에는 input을 string으로 선언해서 input = Console.ReadLine(); 으로 문자를 바로 입력 받았는데,
이방법이 위 코드에서는 잘 실행이 되었는데 밑 코드에서는 오류가 났다.
코드를 맞게 작성한 것 같아서 한참을 고민하다가 input을 int로 선언해서 위와 같이 int.Parse로 변환하여 입력을 받으니
실행이 잘 됐다.
정확히 왜 오류가 났는지는 확실하게는 모르겠어서 유사한 상황들을 구글링을 통해 찾아볼 예정이다.
● 플레이
● 느낀점
이렇게 오늘 거의 대부분을 이 한가지 게임을 만드는데 사용했다.
사실 체감시간은 그렇게 오래 걸리지 않은 것 같았는데 대략 4시간 정도 걸린 것 같다.
이렇게 코딩에 몰두하는 동안 시간이 잘간다는 것은 어떻게 보면 나의 적성과 잘 맞는 것 같기도 하다.
아직 많이 부족하지만 확실히 스네이크 게임 만들기보다는 초반부터 방향성이 잘 잡힌 것 같았다.
구현하기 조금 까다로운 부분들은 하드코딩을 통해 조금씩 쉽게 진행한 것도 있는데 이러한 부분들은 점점 많은 실습들을 통해서 나의 스킬을 조금씩 늘려서 나중에 고칠 예정이다.
'Unity_2기 내일배움캠프 TIL' 카테고리의 다른 글
Unity_2기 3주차 (231113) (1) | 2023.11.13 |
---|---|
Unity_2기 2주차 (231110) (0) | 2023.11.10 |
Unity_2기 2주차 (231108) (0) | 2023.11.08 |
Unity_2기 2주차 (231107) (0) | 2023.11.07 |
Unity_2기 2주차 (231106) (0) | 2023.11.06 |