public PlayHandOutcome PlayHand(Hand handPlayer, Hand handDealer, double betSize, CardShoe shoe, ref int numberOfSplits) { int trueCount = 0; if (shoe.Count != null) { trueCount = shoe.Count.TrueCount; } bool surrenderDone = false; bool splitDone = numberOfSplits > 0; var playHandOutcome = new PlayHandOutcome(); handPlayer.BetSize = betSize; // consider insurance first double insuranceBet = 0; if (Configuration.GameRules.InsuranceAllowed && handDealer.IsAce(0) && !splitDone) { bool takeInsurance = Strategy.GetInsuranceDecision(handDealer, trueCount); if (takeInsurance) { insuranceBet = 0.5 * betSize; } } // player's hand play bool continuePlay = true; while (handPlayer.Value() < 21 && !surrenderDone && !handDealer.IsBlackjack() && continuePlay) { Permits permits = new Permits(handPlayer, Configuration, numberOfSplits); if (shoe.Count != null) { trueCount = shoe.Count.TrueCount; } StrategyDecisionType decision = Strategy.GetDecision(handPlayer, handDealer, trueCount, permits, Random); switch (decision) { case StrategyDecisionType.STAND: continuePlay = false; break; case StrategyDecisionType.HIT: handPlayer.Hit(shoe); break; case StrategyDecisionType.DOUBLE: handPlayer.DoubleDone = true; betSize *= 2; handPlayer.Hit(shoe); continuePlay = false; break; case StrategyDecisionType.SPLIT: var splitHands = handPlayer.Split(shoe); numberOfSplits++; var playHandOutcomeSplit1 = PlayHand(splitHands[1], handDealer, betSize, shoe, ref numberOfSplits); var playHandOutcomeSplit2 = PlayHand(splitHands[0], handDealer, betSize, shoe, ref numberOfSplits); playHandOutcome.AddHands(playHandOutcomeSplit1.HandsPlayed); playHandOutcome.AddHands(playHandOutcomeSplit2.HandsPlayed); double betTotal = playHandOutcomeSplit1.BetTotal + playHandOutcomeSplit2.BetTotal + insuranceBet; playHandOutcome.BetTotal = betTotal; playHandOutcome.InsuranceBet = insuranceBet; return playHandOutcome; case StrategyDecisionType.SURRENDER: surrenderDone = true; break; case StrategyDecisionType.NA: throw new Exception("Strategy decision was not determined!"); } } // return outcome playHandOutcome.HandsPlayed.Add(handPlayer); playHandOutcome.BetTotal = betSize + insuranceBet; playHandOutcome.InsuranceBet = insuranceBet; playHandOutcome.SurrenderDone = surrenderDone; return playHandOutcome; }
public double PayoffHand(PlayHandOutcome playHandOutcome, Hand handDealer, CardShoe shoe) { var insurancePayoff = PayoffInsurance(handDealer, playHandOutcome.InsuranceBet); int handsTotal = playHandOutcome.HandsPlayed.Count; bool splitDone = handsTotal > 1; if (playHandOutcome.SurrenderDone) { if (handsTotal > 1) { throw new Exception("Surrender done while hand has been split - should not happen!"); } var betSize = playHandOutcome.HandsPlayed[0].BetSize; return -0.5 * betSize + insurancePayoff; } // dealer's hand play while (((handDealer.Value() <= 16) || (handDealer.Value() == 17 && handDealer.IsSoft() && !Configuration.GameRules.DealerStandsSoft17)) && !playHandOutcome.AllHandBust()) { handDealer.Hit(shoe); } int dealerTotal = handDealer.Value(); double payoff = 0; foreach (var handPlayed in playHandOutcome.HandsPlayed) { var betSize = handPlayed.BetSize; if (handPlayed.DoubleDone) { betSize *= 2; } int playerTotal = handPlayed.Value(); if (handPlayed.IsBlackjack() && !handDealer.IsBlackjack() && !splitDone) { // blackjack won payoff += 1.5 * betSize; } else if (playerTotal > 21) { // player bust payoff -= betSize; } else if (dealerTotal > 21) { // dealer bust payoff += betSize; } else if (playerTotal > dealerTotal) { // player won payoff += betSize; } else if (dealerTotal > playerTotal) { // dealer won payoff -= betSize; } else { // push payoff += 0; } } return payoff + insurancePayoff; }