Unity_2기 내일배움캠프 TIL

Unity_2기 2주차 (231109)

잼잼재미 2023. 11. 9. 18:03

오늘은 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