double CorrectPlayer::Stand(Hand player, int upcard, Shoe& shoe, int numBets) { if (player.Total() > 21) { double ev = -1.0 * numBets; if (allBusted) ev += restEV_allBust; else ev += 1.0*Dealer::ProbBust(upcard, shoe) + restEV_noAllBust; return ev; } double ev = 1.0; if (player.Total() < 17) { for (int i=17; i<=21; i++) { ev -= 2.0 * Dealer::ProbTotal(upcard, i, shoe); } } else { double prob_dealer_win = 0.0; for (int i=player.Total()+1; i<=21; i++) { prob_dealer_win += Dealer::ProbTotal(upcard, i, shoe); } double prob_tie = Dealer::ProbTotal(upcard, player.Total(), shoe); ev -= prob_tie + 2.0*prob_dealer_win; } ev *= numBets; if (allBusted) ev += numBusted * Dealer::ProbBust(upcard, shoe); ev += restEV_noAllBust; return ev; }
double Dealer::ProbTotalBrute(Hand hand, int total, Shoe shoe, int depth) { // stop on soft >= 18 // stop on hard >= 17 if (hand.Total() >= 17 && !hand.Soft()) { if (hand.Total() == total) return 1.0; else return 0.0; } if (hand.Total() >= 18 && hand.Soft()) { if (hand.Total() == total) return 1.0; else return 0.0; } double total_prob = 0.0; // only upcard dealt and it is A or 10 // if it is A, next card cannot be 10 // if it is 10, next card cannot be A if (depth == 0 && (hand.Total() == 10 || hand.Total() == 11)) { if (hand.Total() == 10) { for (int i=2; i<=10; i++) { double tmp = shoe[i]/(double)(shoe.Total()-shoe[1]); if (tmp > 0.0) { shoe.DealCard(i); total_prob += tmp*Dealer::ProbTotalBrute(hand+i, total, shoe, depth+1); shoe.AddCard(i); } } } else { for (int i=1; i<=9; i++) { double tmp = shoe[i]/(double)(shoe.Total()-shoe[10]); if (tmp > 0.0) { shoe.DealCard(i); total_prob += tmp*Dealer::ProbTotalBrute(hand+i, total, shoe, depth+1); shoe.AddCard(i); } } } return total_prob; } for (int i=1; i<=10; i++) { double tmp = shoe.CardProb(i); if (tmp > 0.0) { shoe.DealCard(i); total_prob += tmp*Dealer::ProbTotalBrute(hand+i, total, shoe, depth+1); shoe.AddCard(i); } } return total_prob; }