[TIL] C# - day 22 - 2

뭉크의 개발·2023년 8월 17일
0

C# - Camp

목록 보기
6/18
post-thumbnail

🐧 들어가기 앞서

블랙잭 게임 제작하기!


🐧 블랙잭 게임

요구사항

  • 블랙잭 게임은 1명의 플레이어와 1명의 딜러가 참여합니다.
  • 게임 시작 시, 플레이어와 딜러는 각각 두 장의 카드를 받습니다.
  • 플레이어는 21점이 넘지 않는 한 계속해서 카드를 더 받을 수 있습니다.
  • 딜러는 카드 합이 17점이 되거나 넘을 때까지 계속해서 카드를 받아야 합니다.
  • 카드를 더 이상 받지 않는 플레이어와 딜러 중 카드 합이 21점에 더 가까운 쪽이 승리합니다. 21점을 초과하면 패배합니다.
  • Card, Deck, Hand, Player, Dealer, Blackjack 등의 클래스를 활용해 구현해야 합니다.

🐧 생각한 것

기능 구현

블랙잭에는 생각보다 처리해야 할 일이 많다.

첫 두 장의 카드를 받은 뒤,

플레이어 옵션

  1. Stand -> 더 이상 카드를 받지 않음

  2. Hit -> 숫자 21전 까지 카드를 더 받을 수 있다.

  3. Bust -> Hit 중 숫자가 21초과시 패배한다.

  4. Split -> 같은 숫자, 다른 모양 (6 스페이드, 6 하트)

    게임 진행 패를 2개로 할 수 있다.
    2개 모두 딜러보다 21에 가까우면 2배 승리
    1 승 1 패 -> 원금
    2개 모두 딜러가 21에 가까우면 2배 패배

  5. Surrender -> 첫 카드 두 장을 받고, 베팅의 50%을 지불하면, 즉시 포기할 수 있다.

  6. Double Down -> 첫 카드 두 장을 받고, 판돈을 두 배로 올릴 수 있다. 단, 카드는 한 장만 더 받는다.

딜러 옵션

  1. 카드의 숫자 합이 17 이상 될 때 까지 카드를 받아야 한다. (무조건)

  2. 또는 16 이하면 더 받는다.

  3. 만약 Bust 옵션이면 플레이어가 승리한다.

  4. 딜러의 첫 카드가 10, J, Q, K, A 이면 블랙잭인지 확인할 수 있다.

    딜러가 블랙잭이면 -> 플레이어 패배
    플레이어가 블랙잭이면 -> 딜러 패배
    둘 다 블랙잭이면 -> Push (무승부)

  5. 딜러가 A이면, Insurance 옵션을 발동할 수 있다.

    플레이어가 찬성하면, 플레이어는 베팅 금액의 절반을 지불한다.
    만약, 딜러가 블랙잭(10, J, K, Q)면 원금만 받는다.
    블랙잭이 아니라면 그대로 게임을 진행한다. (Insurance는 딜러에게)
    만약 플레이어가 블랙잭이면 Even Money를 선언하는데
    딜러가 블랙잭이면 Push
    블랙잭이 아니면 2.5배를 받는다. (Insurance는 딜러에게)


🐧 전체 코드

using System.Diagnostics.CodeAnalysis;
using static BlackJackGame.Program;

namespace BlackJackGame
{
    internal class Program
    {
        public int _player = 0;
        public int _dealer = 1;
        public enum Suit { Spades, Hearts, Diamonds, Clubs }
        public enum Number { Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten = 10, Jack=10, Queen=10, King=10, Ace=11 }
        static void Main(string[] args)
        {
            Hand _h = new Hand();

            
            _h.StartGame();

            
        }

        public class Deck
        {
            private List<(Number, Suit)> _deck = new List<(Number, Suit)>();

            public Deck()
            {
                Initdeck();
            }
            
            // Fisher - Yates
            public void DeckShuffle(List<(Number, Suit)> _deck)
            {
                Random _random = new Random();
                int _n = _deck.Count; // 현재 덱의 개수
                while (_n > 1) // 한 장 남을 때 까지
                {
                    _n--; // 현재 처리할 아이템 인덱스
                    int _k = _random.Next(_n + 1); // 현재 덱의 개수 보다 작은 숫자, _k에 할당
                    (Number, Suit) _temp = _deck[_k]; 
                    _deck[_k] = _deck[_n];
                    _deck[_n] = _temp;
                }

            }

            public void Initdeck()
            {
                foreach (Number _n in Enum.GetValues(typeof(Number)))
                {
                    foreach (Suit _s in Enum.GetValues(typeof(Suit)))
                    {
                        _deck.Add((_n, _s));
                    }
                }
                DeckShuffle(_deck);


                // 덱 출력 
                foreach (var _card in _deck)
                {
                    Console.WriteLine($"Number:{_card.Item1}, Suit:{_card.Item2}");
                }
            }

            public (Number, Suit) DrawCard()
            {
                if (_deck.Count > 0)
                {
                    (Number, Suit) card = _deck[0];
                    _deck.RemoveAt(0);
                    return card;
                }
                else
                {
                    // 오류 처리
                    Console.WriteLine("덱에 카드가 없습니다.");
                    return default((Number, Suit)); //
                }
            }
        }

        public class Hand
        {
            protected List<(Number, Suit)> _playerHand = new List<(Number, Suit)>();
            protected List<(Number, Suit)> _dealerHand = new List<(Number, Suit)>();

            public int HandSum(List<(Number, Suit)> hand)
            {
                int sum = 0;
                foreach (var card in hand)
                {
                    sum += (int)card.Item1;
                }
                return sum;
            }

            public void StartGame()
            {
                Deck _d = new Deck();

                _d.Initdeck();

                for (int i = 0; i < 2; i++)
                {
                    _playerHand.Add(_d.DrawCard());
                    _dealerHand.Add(_d.DrawCard());
                }
                Console.WriteLine("플레이어 카드");
                foreach(var _pCard in _playerHand)
                {
                    Console.WriteLine($"Number : {_pCard.Item1}, Suit : {_pCard.Item2}");
                    
                }

                Console.WriteLine("딜러 카드");
                foreach (var _dCard in _dealerHand)
                {
                    Console.WriteLine($"Number : {_dCard.Item1}, Suit : {_dCard.Item2}");
                }

                int playerSum = HandSum(_playerHand);
                int dealerSum = HandSum(_dealerHand);

                if (playerSum > 21)
                {
                    Console.WriteLine("플레이어 버스트! 딜러 승리");
                } else if (dealerSum > 21)
                {
                    Console.WriteLine("딜러 버스트! 플레이어 승리");
                }
                else
                {
                    Console.WriteLine("Hit");
                }
            }
        }
    }
}

🐧 내일 할 일

우선 블랙잭의 덱, 덱 셔플, 플레이어와 딜러의 패, Bust, Hit을 구현했다.

나머지는 내일,,,

내일 12시에 개인 과제가 출제 되는데,

과제 부터 건드려야겠다.

그전에 최대한 구현하기!

0개의 댓글