private void Settlement(ref BlackjackHandData blackjackHandData) { Player.hand.SetHandValues(); Dealer.hand.SetHandValues(); //SETTLE SPLIT HAND if (Player.splitHand != null) { if (Player.splitHand.handValues.Last() > Dealer.hand.handValues.Last()) { Console.WriteLine("Game Result: Player Wins Split Hand"); Player.Chips += Player.SplitHandStake * 2; //Player Wins Split Hand blackjackHandData.SplitGameResult = "W"; } else if (Player.splitHand.handValues.Last() < Dealer.hand.handValues.Last()) { Console.WriteLine("Game Result: Dealer Wins Split Hand"); blackjackHandData.SplitGameResult = "L"; } else { Console.WriteLine("Game Result: TIE Split Hand"); Player.Chips += Player.SplitHandStake; blackjackHandData.SplitGameResult = "D"; } } //If player hand value > dealers player wins if (Player.hand.handValues.Last() > Dealer.hand.handValues.Last()) { Console.WriteLine("Game Result: Player Wins"); Player.Chips += Player.Stake * 2; //Player Wins blackjackHandData.GameResult = "W"; } //If player hand value < dealers player wins else if (Player.hand.handValues.Last() < Dealer.hand.handValues.Last()) { Console.WriteLine("Game Result: Dealer Wins"); blackjackHandData.GameResult = "L"; } //If player hand value == dealers player ties else { Console.WriteLine("Game Result: TIE"); Player.Chips += Player.Stake; blackjackHandData.GameResult = "D"; } Console.WriteLine($"Player Chips:\t{Player.Chips}"); }
/// <summary> /// Launches simulation with chosen parameters /// </summary> public void RunGame() { //Game is initialised InitialiseGame(_options.StrategyName); //Create file and write first line //File saved in data folder string filename = $"{Player.StrategyName}_hands({_options.HandsToBePlayed})shuffleFrequency({_options.CardCountWhenToShuffle})deckSize({_options.DeckSize}).csv"; StreamWriter f = InitialiseStreamWriter(filename, _options.FilePath); //BlackjackHandData blackjackHandData = new BlackjackHandData(); //A card is burnt _burntCards.Add(Deck.Cards.Pop()); //Play n hands, where n is the amount of hands to be played chosen by user for (int i = 0; i < _options.HandsToBePlayed; i++) { BlackjackHandData blackjackHandData = new BlackjackHandData(); Console.WriteLine($"-------------------------------------------------Hand Number:\t{HandsPlayed}---------------------------------------------------");//CONSOLE HAND SEPARATOR //shuffle check Shuffles first turn available when cards left are smaller than the number specified if (Deck.Cards.Count < _options.CardCountWhenToShuffle) { Deck = new Deck(_options.DeckSize); //Shuffle deck and burn a card Deck.FisherYatesShuffle(); _burntCards.Clear(); _burntCards.Add(Deck.Cards.Pop()); //Update count according to burnt card Player.UpdateCount(Deck, _burntCards, Dealer.upCard); } //Write pre hand counts to console Console.Write("Pre hand counts:\t"); foreach (var t in Player.Count) { Console.Write($"{t}\t"); } Console.WriteLine(); //Store counts and deck has for file blackjackHandData.FirstCountBeforeHand = Player.Count[0]; blackjackHandData.CurrentTurnDeckHash = Deck.GetDeckHash(); blackjackHandData.AmountOfCardsInDeckBeforeTurn = Deck.Cards.Count; blackjackHandData.PlayersDecisions = ""; blackjackHandData.PlayersSplitHandDecisions = ""; blackjackHandData.DealersDecisions = ""; blackjackHandData.DoesPlayerSplit = "N"; blackjackHandData.PlayerStartingChips = Player.Chips; //Get Bet function Player.AddBet(Player.CalculateBet(_options.MinBet, _options.MaxBet), ref Player.Stake); //Save data blackjackHandData.CountZeroAtTimeOfBet = Player.Count[0]; blackjackHandData.CountOneAtTimeOfBet = Player.Count[1]; blackjackHandData.PlayerStake = Player.Stake; //Write player stake to console Console.WriteLine($"Player's starting stake:\t{Player.Stake}"); //Deal Cards DealHand(); //Save Data blackjackHandData.PlayersStartingHandPreSplit = Player.hand.ToString(); //Set Starting Hand Values for file blackjackHandData.PlayersStartingHardHandValue = Player.hand.handValues.First();//FOR FILE blackjackHandData.PlayersStartingSoftHandValue = Player.hand.handValues.Count > 1 ? Player.hand.handValues.Last() : 0; //Dealer reveals upcard //Reference to first card in hand Dealer.upCard = Dealer.hand.cards[0]; Console.WriteLine($"Dealer's Up Card is: {Dealer.upCard}"); Console.WriteLine($"Player's cards are: {Player.hand}"); //Check naturals UpdateHandValues(); Player.UpdateCount(Deck, _burntCards, Dealer.upCard); if (!CheckNaturals(ref blackjackHandData)) { //Player reacts, can double down or split here Player.React(Dealer.upCard, ref Player.CurrentState, Player.hand, Player.Count); //PLAY SPLIT HANDS if (Player.CurrentState == PlayerState.Split) { PlaySplitHand(ref blackjackHandData); } //PLAY REGULAR HAND Player.React(Dealer.upCard, ref Player.CurrentState, Player.hand, Player.Count); //IF PLAYER SPLIT ACES, STAND if (Player.splitHand != null && Player.splitHand.cards.First().Face == Face.Ace) { Player.CurrentState = PlayerState.Stand; } blackjackHandData.PlayersDecisions += Player.CurrentState + "/";//FOR FILE //IF PLAYER DOUBLE DOWNS, STAND OR BUST if (Player.CurrentState == PlayerState.DoubleDown) { Player.AddBet(Player.Stake, ref Player.Stake); HitPlayer(Player); Console.WriteLine($"Player DOUBLES DOWN:\t{Player.hand.cards.Last()}"); Console.WriteLine($"Player's stake after DD:\t{Player.Stake}"); Console.WriteLine($"Player's Hand:\t{Player.hand}\t{Player.hand.handValues.Max()}"); //STAND IF DOUBLE DOWN AND PLAYER < 21 Player.CurrentState = Player.hand.handValues.First() <= 21 ? PlayerState.Stand : PlayerState.Bust; } //WHILE PLAYER ISN'T BUST OR STANDING while (Player.CurrentState != PlayerState.Bust && Player.CurrentState != PlayerState.Stand) { if (Player.CurrentState == PlayerState.Hit) { HitPlayer(Player); Console.WriteLine($"Player Hits:\t{Player.hand.cards.Last()}\t{Player.hand.handValues.Last()}"); if (Player.hand.handValues.First() > 21) { Player.CurrentState = PlayerState.Bust; } } Player.React(Dealer.upCard, ref Player.CurrentState, Player.hand, Player.Count); blackjackHandData.PlayersDecisions += Player.CurrentState + "/";//FOR FILE } Console.WriteLine($"PLAYER REACTS:\t{Player.CurrentState}\t{Player.hand.handValues.Last()}"); //If player is bust, player loses his bet and hand is over if (Player.CurrentState == PlayerState.Bust) { //PLAYER LOSES Console.WriteLine($"Dealer's Hand:\t{Dealer.hand}\t{Dealer.hand.handValues.Max()}"); Console.WriteLine("Game Result: Dealer Wins"); Player.Stake = 0; blackjackHandData.GameResult = "L"; Console.WriteLine($"Player Chips:\t{Player.Chips}"); } else { //DEALER PLAYS HAND IF PLAYER DOESN'T LOSE Console.Write("Dealer has: "); Dealer.hand.WriteHandAndHandValue(); //If not dealer reacts Dealer.React(); blackjackHandData.DealersDecisions += Dealer.CurrentState + "/";//FOR FILE while (Dealer.CurrentState != PlayerState.Bust && Dealer.CurrentState != PlayerState.Stand) { if (Dealer.CurrentState == PlayerState.Hit) { HitPlayer(Dealer); Console.WriteLine($"Dealer draws: {Dealer.hand.cards.Last()}\t{Dealer.hand.handValues.Max()}"); } Dealer.React(); blackjackHandData.DealersDecisions += Dealer.CurrentState + "/";//FOR FILE } Console.WriteLine($"DEALER REACTS:\t{Dealer.CurrentState}\t{Dealer.hand.handValues.Last()}"); //If dealer is bust and player is not, player wins if (Dealer.CurrentState == PlayerState.Bust) { Console.WriteLine("Game Result: Player Wins"); Player.Chips += Player.Stake * 2; blackjackHandData.GameResult = "W"; if (Player.splitHand != null && Player.splitHandState != PlayerState.Bust) { Console.WriteLine("Game Result: Player Wins Split Hand"); Player.Chips += Player.SplitHandStake * 2; blackjackHandData.SplitGameResult = "W"; } //Player wins Console.WriteLine($"Player Chips:\t{Player.Chips}"); } //SETTLEMENT else { Settlement(ref blackjackHandData); } } } //END HAND GAMEPLAY //If there was a split hand this turn, document split hand values if (Player.splitHand != null) { blackjackHandData.PlayersStartingSplitHand = Player.splitHand.cards[0] + " " + Player.splitHand.cards[1]; blackjackHandData.PlayersStartingSplitHardHandValue = Player.splitHand.handValues.First().ToString(); blackjackHandData.PlayersStartingSplitSoftHandValue = Player.splitHand.handValues.Last().ToString(); blackjackHandData.PlayersEndSplitHand = Player.splitHand.ToString(); blackjackHandData.PlayersEndSplitHandValue = Player.splitHand.handValues.Last().ToString(); } //If no split hand change all split hand values to N/A else { blackjackHandData.PlayersStartingSplitHand = "N/A"; blackjackHandData.PlayersStartingSplitHardHandValue = "N/A"; blackjackHandData.PlayersStartingSplitSoftHandValue = "N/A"; blackjackHandData.PlayersEndSplitHand = "N/A"; blackjackHandData.PlayersEndSplitHandValue = "N/A"; blackjackHandData.PlayersSplitHandDecisions = "N/A"; blackjackHandData.PlayersStartingHandPreSplit = "N/A"; blackjackHandData.SplitGameResult = "N/A"; } blackjackHandData.FirstCountAfterHand = Player.UpdateCount(Deck, _burntCards, Dealer.upCard).First(); //Write all relevant information to file after every hand f.WriteLine(blackjackHandData.GetHandDataAsString(Player, HandsPlayed, Dealer, Deck)); //Cleanup hand and Update Counts CleanupHand(); Player.UpdateCount(Deck, _burntCards, Dealer.upCard); //If human is playing await input if (_options.HumanPlayer) { Console.ReadKey(); Console.Clear(); } HandsPlayed++; } //Close file when all hands are played and write simulation summary to file f.Close(); Console.WriteLine("-----------------------------------------------------------------------------------------------------------------------");//CONSOLE HAND SEPARATOR Console.WriteLine($"Strategy:\t{_options.StrategyName}"); Console.WriteLine($"Deck Size:\t{_options.DeckSize}"); Console.WriteLine($"Hands Played:\t{HandsPlayed}"); Console.WriteLine($"Final Chip Count:\t{Player.Chips}"); Console.WriteLine("-----------------------------------------------------------------------------------------------------------------------");//CONSOLE HAND SEPARATOR }
private bool CheckNaturals(ref BlackjackHandData blackjackHandData) { if (Player.hand.handValues.Contains(21)) { //Player has natural and dealer doesn't if (!Dealer.hand.handValues.Contains(21)) { Console.WriteLine("Player Has a Natural"); if (blackjackHandData != null) { blackjackHandData.PlayersDecisions = "PLAYER_NATURAL"; } Console.WriteLine("Game Result: Player Wins"); Player.Chips += (int)(Player.Stake * 2.5); Player.Stake = 0; //Player wins if (blackjackHandData != null) { blackjackHandData.GameResult = "W_N"; } return(true); } //Player and dealer have natural else { Console.WriteLine("Player Has a natural"); Console.WriteLine("Dealer Has a natural"); if (blackjackHandData != null) { blackjackHandData.PlayersDecisions = "PLAYER_NATURAL"; } if (blackjackHandData != null) { blackjackHandData.DealersDecisions = "DEALER_NATURAL"; } Console.WriteLine("Game Result: TIE"); Player.Chips += Player.Stake; //TIE if (blackjackHandData != null) { blackjackHandData.GameResult = "D_N"; } return(true); } } else if (Dealer.hand.handValues.Contains(21)) { //Dealer has natural and player doesn't if (!Player.hand.handValues.Contains(21)) { Console.WriteLine("Dealer Has a natural"); if (blackjackHandData != null) { blackjackHandData.DealersDecisions = "DEALER_NATURAL"; } Console.WriteLine("Game Result: Dealer Wins"); Player.Stake = 0; //Player loses if (blackjackHandData != null) { blackjackHandData.GameResult = "L_N"; } return(true); } //Player and dealer have a natural else { Console.WriteLine("Player Has a Natural"); Console.WriteLine("Dealer Has a natural"); Console.WriteLine("Game Result: TIE"); if (blackjackHandData != null) { blackjackHandData.PlayersDecisions = "PLAYER_NATURAL"; } if (blackjackHandData != null) { blackjackHandData.DealersDecisions = "DEALER_NATURAL"; } Player.Chips += Player.Stake; //TIE if (blackjackHandData != null) { blackjackHandData.GameResult = "D_N"; } return(true); } } return(false); }
private void PlaySplitHand(ref BlackjackHandData blackjackHandData) { blackjackHandData.PlayersDecisions += Player.CurrentState + "/"; //FOR FILE blackjackHandData.DoesPlayerSplit = "Y"; //FOR FILE //Splitting the hands Player.splitHand = new Hand(); Player.splitHand.cards.Add(Player.hand.cards.Last()); Player.hand.cards.Remove(Player.splitHand.cards.First()); HitPlayer(Player); HitPlayer(Player.splitHand); //Write split hands to console Console.WriteLine($"Player's Hand:\t{Player.hand}"); Console.WriteLine($"Player's Split Hand:\t{Player.splitHand}"); //Add splitBet stake so player is playing two hands for twice his stake Player.AddBet(Player.Stake, ref Player.SplitHandStake); Console.WriteLine($"Player Split Hand Stake:\t{Player.SplitHandStake}"); //Playing the split hand //Split aces forces stand rule if (Player.hand.cards.First().Face == Face.Ace && Player.splitHand.cards.First().Face == Face.Ace) { Player.CurrentState = PlayerState.Stand; Player.splitHandState = PlayerState.Stand; blackjackHandData.PlayersDecisions += Player.CurrentState + "/"; //FOR FILE blackjackHandData.PlayersSplitHandDecisions += Player.splitHandState + "/"; //FOR FILE } else { Player.React(Dealer.upCard, ref Player.splitHandState, Player.splitHand, Player.Count); blackjackHandData.PlayersSplitHandDecisions += Player.splitHandState + "/";//FOR FILE } //Player doubles down on split hand if (Player.splitHandState == PlayerState.DoubleDown) { //Double his split hand stake Player.AddBet(Player.SplitHandStake, ref Player.SplitHandStake); Console.WriteLine($"Player's split stake after double down:\t{Player.SplitHandStake}"); //Hit player HitPlayer(Player.splitHand); Console.WriteLine($"Player split double downs with:\t{Player.splitHand.cards.Last()}"); //If player < 21 STAND if (Player.hand.handValues.First() <= 21) { Player.splitHandState = PlayerState.Stand; blackjackHandData.PlayersSplitHandDecisions += Player.splitHandState + "/";//FOR FILE } //If player > 21 BUST else { Player.splitHandState = PlayerState.Bust; blackjackHandData.PlayersSplitHandDecisions += Player.splitHandState + "/";//FOR FILE } } //While the player isn't standing or busting while (Player.splitHandState != PlayerState.Bust && Player.splitHandState != PlayerState.Stand) { //Hit player is it reacts hit if (Player.splitHandState == PlayerState.Hit) { Player.WriteCurrentState(); HitPlayer(Player.splitHand); //BUST CHECK if (Player.splitHand.handValues.First() > 21) { Player.splitHandState = PlayerState.Bust; } Console.WriteLine($"Player's split hand:\t{Player.splitHand}\t{Player.splitHand.handValues.Last()}"); } Player.React(Dealer.upCard, ref Player.splitHandState, Player.splitHand, Player.Count); blackjackHandData.PlayersSplitHandDecisions += Player.splitHandState + "/"; } //If player busts on split hand, lose split hand stake if (Player.splitHandState == PlayerState.Bust) { Player.SplitHandStake = 0; blackjackHandData.SplitGameResult = "L"; } }