public override void PlayHands(int iterations, StatisticsMgr stats) { Dealer dlr = new Dealer(stats); while (--iterations >= 0) { var hands = dlr.DealHands(new NaiveHand()); hands.Item1.Hit(dlr); if (!hands.Item1.IsBust) { hands.Item2.Hit(dlr); } if (hands.Item1.IsBust) { stats.Losses++; } else if (hands.Item1.IsBlackJack && !hands.Item2.IsBlackJack) { stats.Wins++; } else if (hands.Item2.IsBust) { stats.Wins++; stats.WinsByBust++; } else if (hands.Item1.SumCards > hands.Item2.SumCards) { stats.Wins++; } else if (hands.Item2.SumCards > hands.Item1.SumCards) { stats.Losses++; } } }
// this method will play a series of hands, using a specific behavior public override void PlayHands(int iterations, StatisticsMgr stats) { Dealer dlr = new Dealer(stats); BettingBehavior betting = new BettingBehavior(); // this is done like this to avoid re-allocating hands ModifiedBettingHand bettingHand = new ModifiedBettingHand(); // doing this here to avoid allocations Hand[] playerHands = new Hand[2]; while (--iterations >= 0) { betting.DetermineBet(stats); bettingHand.Reset(); dlr.DealHands(bettingHand); // tweak the stats before the doubledown bet foreach (Card playerCard in dlr.PlayerHand.Cards) { // this records the card displayed, emulating a user that is // counting the last 12 cards or so. Counting more cards would // result in better performance. stats.DiscardCard(playerCard); } stats.DiscardCard(dlr.DealerHand.Cards[1]); stats.BlackJacks += (dlr.PlayerHand.IsBlackJack) ? 1 : 0; // apply the hit logic to the player's hand. This will also // split if necessary dlr.PlayerHand.Hit(dlr, betting); // dealer only hits if the player doesn't go bust if (!dlr.PlayerHand.IsBust || (dlr.PlayerSplitHand != null && !dlr.PlayerSplitHand.IsBust)) { dlr.DealerHand.Hit(dlr); } if (iterations % 1000000 == 0) { Debug.WriteLine("\tProfits: {0} Bet: {1}", stats.Profit, betting.Bet); } playerHands[0] = dlr.PlayerHand; if (null != dlr.PlayerSplitHand) { // if the hand was split, add the split hand results as well playerHands[1] = dlr.PlayerSplitHand; } else { playerHands[1] = null; } foreach (var playerHand in playerHands) { if (null == playerHand) { continue; } // keep track of the total amount bet since it's dynamic stats.CumulativeBet += playerHand.Bet; if (playerHand.IsBust) { stats.Profit -= playerHand.Bet; stats.RecordLoss(); stats.LossesByBust++; if (playerHand.IsDoubledDown) { stats.LossesByDoubleDown++; } if (playerHand.IsSplit) { stats.LossesBySplit++; } } else if (playerHand.IsBlackJack && !dlr.DealerHand.IsBlackJack) { // blackjack pays 3 to 2 stats.Profit += (int)(1.5 * playerHand.Bet); stats.RecordWin(iterations); if (playerHand.IsSplit) { stats.WinsBySplit++; } } else if (!playerHand.IsBlackJack && dlr.DealerHand.IsBlackJack) { stats.Profit -= playerHand.Bet; stats.RecordLoss(); if (playerHand.IsDoubledDown) { stats.LossesByDoubleDown++; } if (playerHand.IsSplit) { stats.LossesBySplit++; } } else if (dlr.DealerHand.IsBust) { stats.Profit += playerHand.Bet; stats.RecordWin(iterations); stats.WinsByBust++; if (playerHand.IsDoubledDown) { stats.WinsByDoubleDown++; } if (playerHand.IsSplit) { stats.WinsBySplit++; } } else if (playerHand.SumCards > dlr.DealerHand.SumCards) { stats.Profit += playerHand.Bet; stats.RecordWin(iterations); if (playerHand.IsDoubledDown) { stats.WinsByDoubleDown++; } if (playerHand.IsSplit) { stats.WinsBySplit++; } } else if (dlr.DealerHand.SumCards > playerHand.SumCards) { stats.Profit -= playerHand.Bet; stats.RecordLoss(); if (playerHand.IsDoubledDown) { stats.LossesByDoubleDown++; } if (playerHand.IsSplit) { stats.LossesBySplit++; } } } // now keep track of the last few discarded cards from both players int index = 0; foreach (Card dlrCard in dlr.DealerHand.Cards) { // skip the card that was initially shown because it was counted // earlier if (index++ == 1) { continue; } stats.DiscardCard(dlrCard); } } }