👾 내일배움캠프/🎮 TIL & WIL
내일배움캠프 (휴일) TIL - 블랙잭 C#
리리핸
2023. 8. 20. 23:59
수정 예정
using System;
using System.Collections.Generic;
using System.Numerics;
public enum Suit { Hearts, Diamonds, Clubs, Spades }
public enum Rank { Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace }
public class Card
{
public Suit Suit { get; private set; }
public Rank Rank { get; private set; }
public Card(Suit s, Rank r)
{
Suit = s;
Rank = r;
}
public int GetValue()
{
if ((int)Rank <= 10)
{
return (int)Rank;
}
else if ((int)Rank <= 13)
{
return 10;
}
else
{
return 11;
}
}
public override string ToString()
{
return $"{Rank} of {Suit}";
}
}
public class Deck
{
private List<Card> cards;
public Deck()
{
cards = new List<Card>();
foreach (Suit s in Enum.GetValues(typeof(Suit)))
{
foreach (Rank r in Enum.GetValues(typeof(Rank)))
{
cards.Add(new Card(s, r));
}
}
Shuffle();
}
public void Shuffle()
{
Random rand = new Random();
for (int i = 0; i < cards.Count; i++)
{
int j = rand.Next(i, cards.Count);
Card temp = cards[i];
cards[i] = cards[j];
cards[j] = temp;
}
}
public Card DrawCard()
{
Card card = cards[0];
cards.RemoveAt(0);
return card;
}
}
public class Hand
{
private List<Card> cards;
public Hand()
{
cards = new List<Card>();
}
public IReadOnlyList<Card> Cards => cards.AsReadOnly();
public void AddCard(Card card)
{
cards.Add(card);
}
public int GetTotalValue()
{
int total = 0;
int aceCount = 0;
foreach (Card card in cards)
{
if (card.Rank == Rank.Ace)
{
aceCount++;
}
total += card.GetValue();
}
while (total > 21 && aceCount > 0)
{
total -= 10;
aceCount--;
}
return total;
}
}
public class Player
{
public Hand Hand { get; private set; }
public Player()
{
Hand = new Hand();
}
public Card DrawCardFromDeck(Deck deck)
{
Card drawnCard = deck.DrawCard();
Hand.AddCard(drawnCard);
return drawnCard;
}
}
public class Dealer : Player
{
public void DealerTurn(Blackjack game, Player player)
{
Console.Clear();
Console.WriteLine("==============================");
Console.WriteLine("* 나의 합: " + player.Hand.GetTotalValue());
Console.WriteLine();
Console.WriteLine("* 딜러의 카드: ");
foreach (Card c in Hand.Cards)
{
Console.WriteLine(c.ToString());
}
while (Hand.GetTotalValue() < 17)
{
DrawCardFromDeck(game.deck);
Console.WriteLine(Hand.Cards[Hand.Cards.Count() - 1].ToString());
Thread.Sleep(1000);
}
Console.WriteLine();
Console.WriteLine("* 딜러의 합: " + Hand.GetTotalValue());
Console.WriteLine("==============================");
Console.WriteLine();
}
}
public class Blackjack
{
public Deck deck;
public Blackjack(Player player, Dealer dealer)
{
deck = new Deck();
StartGame(player, dealer);
}
public void StartGame(Player player, Dealer dealer)
{
dealer.DrawCardFromDeck(deck);
dealer.DrawCardFromDeck(deck);
player.DrawCardFromDeck(deck);
player.DrawCardFromDeck(deck);
Print(player, dealer);
Console.WriteLine();
}
public void Print(Player player, Dealer dealer)
{
Console.WriteLine();
Console.Clear();
Console.WriteLine("==============================");
Console.Write("* 딜러의 카드: ");
Console.WriteLine(dealer.Hand.Cards[0]);
Console.WriteLine();
Console.WriteLine("* 나의 카드: ");
foreach (Card c in player.Hand.Cards)
{
Console.WriteLine(c.ToString());
}
Console.WriteLine();
Console.WriteLine("* 나의 합: " + player.Hand.GetTotalValue());
Console.WriteLine("==============================");
Console.WriteLine();
}
}
class Program
{
static int winner;
static bool isRunning = true;
static void Main(string[] args) // 플레이어와 딜러를 블랙잭에서 객체화 게 나을지 고민해보기
{
Player player = new Player();
Dealer dealer = new Dealer();
Blackjack game = new Blackjack(player, dealer);
if (player.Hand.GetTotalValue() == 21)
{
winner = 4;
GameEnd();
}
while (isRunning)
{
Console.WriteLine("Hit(h) or Stay(s)? : ");
string input = Console.ReadLine();
Console.WriteLine(" ");
// 유효하지 않은 값 입력시 입력받기 반복
while (input != "h" && input != "s")
{
Console.WriteLine("잘못된 값을 입력하셨습니다.");
Console.WriteLine();
Console.WriteLine("Hit(h) or Stay(s)? : ");
input = Console.ReadLine();
Console.WriteLine();
}
//------------------------------
if (input == "h")
{
player.DrawCardFromDeck(game.deck);
game.Print(player, dealer);
}
else
{
dealer.DealerTurn(game, player);
// 카드 합 비교
Check(player, dealer);
if (!isRunning) continue;
if (player.Hand.GetTotalValue() > dealer.Hand.GetTotalValue()) winner = 2;
else if (player.Hand.GetTotalValue() == dealer.Hand.GetTotalValue()) winner = 3;
else winner = 1;
//-----------------------------
GameEnd();
continue;
}
Check(player, dealer);
}
}
public static void GameEnd()
{
Thread.Sleep(1000);
isRunning = false;
switch (winner)
{
case 1:
Console.WriteLine("******************************");
Console.WriteLine("******************************");
Console.WriteLine("********* GAME OVER *********");
Console.WriteLine("********* *********");
Console.WriteLine("********* YOU LOSE! *********");
Console.WriteLine("******************************");
Console.WriteLine("******************************");
break;
case 2:
Console.WriteLine("******************************");
Console.WriteLine("******************************");
Console.WriteLine("********* GAME OVER *********");
Console.WriteLine("********* *********");
Console.WriteLine("********* YOU WIN! *********");
Console.WriteLine("******************************");
Console.WriteLine("******************************");
break;
case 3:
Console.WriteLine("******************************");
Console.WriteLine("******************************");
Console.WriteLine("********* GAME OVER *********");
Console.WriteLine("********* *********");
Console.WriteLine("********* TIED! *********");
Console.WriteLine("******************************");
Console.WriteLine("******************************");
break;
case 4:
Console.WriteLine("******************************");
Console.WriteLine("******************************");
Console.WriteLine("********* BLACK *********");
Console.WriteLine("********* *********");
Console.WriteLine("********* JACK *********");
Console.WriteLine("******************************");
Console.WriteLine("******************************");
break;
}
Thread.Sleep(5000);
}
static void Check(Player player, Dealer dealer)
{
// 매 턴 플레이어 혹은 딜러의 카드 합이 21을 넘는지 확인
if (player.Hand.GetTotalValue() > 21)
{
isRunning = false;
winner = 1;
GameEnd();
}
else if (dealer.Hand.GetTotalValue() > 21)
{
isRunning = false;
winner = 2;
GameEnd();
}
}
}