Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////////////////////////////////////////////////////
- // STRATEGY.CPP
- //
- // Calculates basic strategy with exact expected values for various styles
- // of casino blackjack, using an infinite deck approximation.
- #include <stdio.h>
- #include <conio.h>
- #define TRUE 1
- #define FALSE 0
- #define max(x,y) (((x)>(y))?(x):(y))
- ////////////////////////////////////////////////////////////////////
- // User-configurable game options.
- int HIT_SOFT_17, // TRUE if dealer hits on soft 17
- PEEK_10, // TRUE if dealer peeks when showing a 10
- DOUBLE_ANY_2, // TRUE if doubling down is allowed on any 2
- // cards
- DOUBLE_AFTER_SPLIT, // TRUE if doubling down after splitting
- // pairs is allowed
- RESPLIT, // TRUE if re-splitting pairs is allowed
- RESPLIT_ACES; // TRUE if re-splitting aces is allowed
- ////////////////////////////////////////////////////////////////////
- // Dealer and player hands.
- class Hand {
- public:
- int count, // point total for the hand
- num_aces, // number of aces in the hand
- soft; // TRUE if the hand is "soft"
- // New() gets rid of all cards in the hand.
- void New() {
- count = num_aces = soft = 0;
- }
- // Deal() "deals" the given card into the hand.
- void Deal(int card) {
- count += card; // add to point total
- if (card == 1) { // aces are special
- num_aces++;
- if (count < 12) { // count as 11 if possible
- count += 10; // (a "soft" hand)
- soft = TRUE;
- }
- }
- if (count > 21 && soft) { // if count is too high to count ace
- count -= 10; // as 11, count it as 1
- soft = FALSE;
- }
- }
- // Undeal() removes the given card from the hand.
- void Undeal(int card) {
- count -= card; // decrease point total
- if (card == 1) { // if removing an ace
- num_aces--;
- if (!num_aces && soft) { // and the soft hand now has no
- count -= 10; // aces, make the hand "hard"
- soft = FALSE;
- }
- }
- if (count < 12 && num_aces && // if ace can now count as 11, make
- !soft) { // hand soft
- count += 10;
- soft = TRUE;
- }
- }
- };
- Hand dealer; int dealer_up_card; // dealer's hand, PLUS up card
- Hand player; // player's hand
- ////////////////////////////////////////////////////////////////////
- // Chance_Card() returns the probability of drawing the given card from the
- // deck (constant for infinite deck).
- long double Chance_Card(int card) {
- if (card == 10)
- return((long double)4/13); // 4 of every 13 is a 10
- else
- return((long double)1/13); // all others are 1 in 13
- }
- ////////////////////////////////////////////////////////////////////
- // Probability of every possible dealer hand for every possible up card. For
- // example, chance_dealer_count[6][21] is the probability of the dealer
- // standing on a count of 21 with 6 as an up card.
- long double chance_dealer_bust[11],
- chance_dealer_count[11][22],
- chance_dealer_blackjack[11];
- ////////////////////////////////////////////////////////////////////
- // Dealer() is called by Compute_Dealer() to recursively compute the
- // probability of every possible dealer hand.
- void Dealer(long double chance) {
- int card;
- if (dealer.count < 17 || // if dealer should hit
- (dealer.count == 17 && HIT_SOFT_17 && // (maybe on a soft 17)
- dealer.soft))
- for (card = 1; card <= 10; card++) { // deal every possible card
- dealer.Deal(card);
- Dealer(chance*Chance_Card(card)); // with a given probability
- dealer.Undeal(card);
- }
- else if (dealer.count > 21) // dealer busts
- chance_dealer_bust[dealer_up_card] += chance;
- // Dealer stands; note that blackjacks are handled by Compute_Dealer().
- else
- chance_dealer_count[dealer_up_card][dealer.count] += chance;
- }
- ////////////////////////////////////////////////////////////////////
- // Compute_Dealer() calls Dealer() to compute dealer probabilities for the
- // up card specified by dealer_up_card.
- void Compute_Dealer() {
- int card;
- // Reset all dealer probabilities.
- chance_dealer_bust[dealer_up_card] =
- chance_dealer_blackjack[dealer_up_card] = 0;
- for (dealer.count = 17; dealer.count <= 21; dealer.count++)
- chance_dealer_count[dealer_up_card][dealer.count] = 0;
- dealer.New(); dealer.Deal(dealer_up_card); // deal JUST the up card
- switch (dealer_up_card) {
- // Dealer ALWAYS checks for blackjack when showing an ace, so assume the hole
- // card is NEVER a 10.
- case 1 : for (card = 1; card < 10; // deal every card but a 10
- card++) {
- dealer.Deal(card);
- Dealer(Chance_Card(card)/ // chance of that card, GIVEN
- ((long double)1 - // that it's not a 10
- Chance_Card(10)));
- dealer.Undeal(card);
- }
- break;
- // If the dealer checks for blackjack when showing a 10, assume the hole card
- // is NOT an ace, as above.
- case 10 : if (PEEK_10)
- for (card = 2; card <= 10; card++) {
- dealer.Deal(card);
- Dealer(Chance_Card(card)/
- ((long double)1 - Chance_Card(1)));
- dealer.Undeal(card);
- }
- // If the dealer does NOT peek when showing a 10, the hole card could be an
- // ace, but handle it here.
- else {
- for (card = 2; card <= 10; card++) {
- dealer.Deal(card);
- Dealer(Chance_Card(card));
- dealer.Undeal(card);
- }
- chance_dealer_blackjack[dealer_up_card] =
- Chance_Card(1); // chance of blackjack =
- } // chance hole card is an ace
- break;
- // All other up cards are no problem.
- default : Dealer(1);
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Expected value of every possible player action for every possible
- // combination of player hand and dealer up card. For example:
- // stand[7][16] is the expected value of standing on a 16 against a dealer's
- // 7. Note that these values are the same for "hard" and "soft" hands.
- long double stand[11][22],
- // hit[6][0][12] is the expected value of hitting a HARD (that's the 0) 12
- // against a dealer's 6.
- hit[11][2][22],
- // double_down[6][1][18] is the expected value of doubling down on a SOFT
- // (that's the 1) 18 (i.e. A-7) against a dealer's 6.
- double_down[11][2][22],
- // split[7][9] is the expected value of splitting a pair of 9's against a
- // dealer's 7, BUT NOT SPLITTING ANY ADDITIONAL 9's YOU MAY DRAW.
- split[11][11],
- // resplit[7][9] is the expected value of splitting a pair of 9's against a
- // dealer's 7, AND RE-SPLITTING ANY ADDITIONAL 9's YOU MAY DRAW.
- resplit[11][11];
- ////////////////////////////////////////////////////////////////////
- // Compute_Gain() computes the expected value of standing, hitting, and
- // doubling down on the player's hand (given in the player instance of Hand)
- // against the dealer's up card (in dealer_up_card).
- void Compute_Gain() {
- int card;
- long double gain;
- // Calculate expected value of standing.
- stand[dealer_up_card][player.count] =
- chance_dealer_bust[dealer_up_card] - // win if dealer busts
- chance_dealer_blackjack[dealer_up_card]; // lose if dealer has BJ
- for (dealer.count = 17; dealer.count <= 21; // if dealer stands
- dealer.count++)
- if (player.count > dealer.count) // win if player's count
- stand[dealer_up_card][player.count] += // beats dealer's count
- chance_dealer_count[dealer_up_card][dealer.count];
- else if (player.count < dealer.count) // lose if dealer's count
- stand[dealer_up_card][player.count] -= // beats player's count
- chance_dealer_count[dealer_up_card][dealer.count];
- // Calculate expected value of hitting.
- hit[dealer_up_card][player.soft] // reset expected value
- [player.count] = 0;
- for (card = 1; card <= 10; card++) { // for all possible hit cards
- player.Deal(card); // deal the card
- ////////////////////////////////////////////////////////////////////
- // This is the heart of the algorithm. If the player didn't bust after
- // hitting, we need to know the expected value of the player's NEW hand. We
- // WILL know this, as long as we have made each of the calls to
- // Compute_Gain() (one for each possible player hand) IN THE RIGHT ORDER.
- if (player.count <= 21) // if player didn't bust
- gain = max( // get BEST expected value of
- stand[dealer_up_card][player.count], // the NEW hand (player can
- hit[dealer_up_card][player.soft] // either stand or hit)
- [player.count]);
- else // player always loses on a
- gain = -1; // bust
- player.Undeal(card);
- hit[dealer_up_card][player.soft] // weight value of new hand
- [player.count] += // with chance of drawing
- gain*Chance_Card(card); // that card
- }
- // Calculate expected value of doubling down. Note the expected value is
- // reset with the probability of the dealer having blackjack, and not 0. This
- // is because IF the dealer has blackjack, the player only loses his original
- // bet, and not his additional double down bet. Subsequent calculations don't
- // take this into account, so we make the correction at the outset.
- double_down[dealer_up_card][player.soft][player.count] =
- chance_dealer_blackjack[dealer_up_card];
- for (card = 1; card <= 10; card++) { // for all possible hit cards
- player.Deal(card); // deal the card
- if (player.count <= 21) // if player didn't bust
- gain = stand[dealer_up_card][player.count]*2; // player HAS to stand
- else
- gain = -2; // lose it all if hand busts
- player.Undeal(card);
- double_down[dealer_up_card][player.soft] // weight value with chance
- [player.count] += // of drawing that card
- gain*Chance_Card(card);
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Compute_Split() computes the expected value of splitting the given pair of
- // cards against the dealer's up card (in dealer_up_card).
- void Compute_Split(int pair_card) {
- int card;
- long double gain;
- split[dealer_up_card][pair_card] = // reset expected values
- resplit[dealer_up_card][pair_card] = 0;
- // We can assume the pair has already been split, and compute the expected
- // value of ONE of the two NEW hands. For an INFINITE deck, the expected
- // value of the split will simply be twice this value.
- player.New(); player.Deal(pair_card); // deal the split card
- for (card = 1; card <= 10; card++) { // for all possible second
- player.Deal(card); // cards, deal that card
- gain = stand[dealer_up_card][player.count]; // get EV of standing
- if (pair_card != 1) { // can't hit split aces!
- gain = max(gain, // otherwise, maybe hitting
- hit[dealer_up_card][player.soft][player.count]); // is better
- if (DOUBLE_AFTER_SPLIT &&
- (DOUBLE_ANY_2 || player.count == 10 || player.count == 11 ||
- (player.count == 20 && player.soft) ||
- (player.count == 21 && player.soft))) // or (if allowed) doubling
- gain = max(gain, // down
- double_down[dealer_up_card][player.soft][player.count]);
- }
- player.Undeal(card);
- split[dealer_up_card][pair_card] += // weight EV with chance of
- gain*Chance_Card(card); // drawing that card
- // If the hit card makes ANOTHER pair, and re-splitting IS ALLOWED, then the
- // EV of the new hand is exactly the value we are trying to calculate (this
- // is similar to the problem of integrating e^x sin x by parts)! So we "put
- // off" this calculation and "solve" for the EV when we're finished.
- if (card != pair_card)
- resplit[dealer_up_card][pair_card] += gain*Chance_Card(card);
- }
- // The expected value of the split is twice the value of one split hand;
- // however, as when doubling down, the player only loses his original bet if
- // the dealer has blackjack, so the same correction must be made.
- split[dealer_up_card][pair_card] *= 2;
- split[dealer_up_card][pair_card] +=
- chance_dealer_blackjack[dealer_up_card];
- // The expected value of splitting AND RE-SPLITTING is almost the same, mod a
- // "normalization" as a result of "solving" for the EV.
- resplit[dealer_up_card][pair_card] *= 2;
- resplit[dealer_up_card][pair_card] +=
- chance_dealer_blackjack[dealer_up_card];
- resplit[dealer_up_card][pair_card] /=
- (long double)1 - Chance_Card(pair_card)*2;
- }
- ////////////////////////////////////////////////////////////////////
- // Strategy() and Strategy_Split() return the character abbreviation for the
- // best action for the given player's hand and dealer's up card. Uppercase
- // means favorable for the player, lowercase means favorable for the house.
- char Strategy() {
- char strategy;
- long double s = stand[dealer_up_card][player.count],
- h = hit[dealer_up_card][player.soft][player.count],
- d = double_down[dealer_up_card][player.soft][player.count];
- if (!DOUBLE_ANY_2 && player.count != 10 && player.count != 11 &&
- !(player.count == 20 && player.soft) &&
- !(player.count == 21 && player.soft))
- d = -2;
- if (s > h && s > d)
- if (s < 0) strategy = 's'; else strategy = 'S';
- else if (h > d)
- if (h < 0) strategy = 'h'; else strategy = 'H';
- else
- if (d < 0) strategy = 'd'; else strategy = 'D';
- return(strategy);
- }
- char Strategy_Split(int card) {
- char strategy;
- long double s = stand[dealer_up_card][player.count],
- h = hit[dealer_up_card][player.soft][player.count],
- d = double_down[dealer_up_card][player.soft][player.count],
- t = split[dealer_up_card][card],
- p = resplit[dealer_up_card][card];
- if (!DOUBLE_ANY_2 && player.count != 10) d = -2;
- if (!RESPLIT || (!RESPLIT_ACES && card == 1)) p = -2;
- if (s > h && s > d && s > t && s > p)
- if (s < 0) strategy = 's'; else strategy = 'S';
- else if (h > d && h > t && h > p)
- if (h < 0) strategy = 'h'; else strategy = 'H';
- else if (d > t && d > p)
- if (d < 0) strategy = 'd'; else strategy = 'D';
- else if (t > p)
- if (RESPLIT)
- if (t < 0) strategy = 'p'; else strategy = 'P';
- else
- if (t < 0) strategy = 't'; else strategy = 'T';
- else
- if (p < 0) strategy = 't'; else strategy = 'T';
- return(strategy);
- }
- ////////////////////////////////////////////////////////////////////
- // Expected_Return() returns the expected gain against the dealer's up card.
- long double Expected_Return() {
- long double gain,total = 0;
- int card1,card2;
- for (card1 = 1; card1 <= 10; card1++)
- for (card2 = 1; card2 <= 10; card2++) {
- player.New(); player.Deal(card1); player.Deal(card2);
- gain = max(stand[dealer_up_card][player.count],
- hit[dealer_up_card][player.soft][player.count]);
- if (DOUBLE_ANY_2 || player.count == 10 || player.count == 11)
- gain = max(gain,
- double_down[dealer_up_card][player.soft][player.count]);
- if (card1 == card2) {
- gain = max(gain,split[dealer_up_card][card1]);
- if (RESPLIT && (RESPLIT_ACES || card1 != 1))
- gain = max(gain,resplit[dealer_up_card][card1]);
- }
- if (dealer_up_card == 1)
- gain = gain*((long double)1 - Chance_Card(10)) -
- Chance_Card(10);
- if (dealer_up_card == 10 && PEEK_10)
- gain = gain*((long double)1 - Chance_Card(1)) -
- Chance_Card(1);
- if (player.count == 21) {
- gain = (long double)3/2;
- if (dealer_up_card == 1)
- gain *= (long double)1 - Chance_Card(10);
- else if (dealer_up_card == 10)
- gain *= (long double)1 - Chance_Card(1);
- }
- total += gain*Chance_Card(card1)*Chance_Card(card2);
- }
- return(total);
- }
- ////////////////////////////////////////////////////////////////////
- // Main program.
- void main() {
- char key;
- int card;
- printf("\n\nBlackjack strategy calculator\n\n");
- // Set user-configurable game options.
- printf("Press 'H' if dealer hits on soft 17, 'Enter' otherwise: ");
- while ((key = getch()) != 'H' && key != 'h' && key != '\r');
- printf("%c\n",key);
- HIT_SOFT_17 = (key == 'H' || key == 'h');
- printf("Press 'P' if dealer peeks when showing a 10, 'Enter' otherwise: ");
- while ((key = getch()) != 'P' && key != 'p' && key != '\r');
- printf("%c\n",key);
- PEEK_10 = (key == 'P' || key == 'p');
- printf("Press 'D' if doubling down is allowed on any two cards, ");
- printf("'Enter' otherwise: ");
- while ((key = getch()) != 'D' && key != 'd' && key != '\r');
- printf("%c\n",key);
- DOUBLE_ANY_2 = (key == 'D' || key == 'd');
- printf("Press 'D' if doubling down after splitting is allowed, ");
- printf("'Enter' otherwise: ");
- while ((key = getch()) != 'D' && key != 'd' && key != '\r');
- printf("%c\n",key);
- DOUBLE_AFTER_SPLIT = (key == 'D' || key == 'd');
- printf("Press 'R' if re-splitting pairs is allowed, 'Enter' otherwise: ");
- while ((key = getch()) != 'R' && key != 'r' && key != '\r');
- printf("%c\n",key);
- RESPLIT = (key == 'R' || key == 'r');
- RESPLIT_ACES = FALSE;
- if (RESPLIT) {
- printf("Press 'A' if re-splitting aces is allowed, 'Enter' otherwise: ");
- while ((key = getch()) != 'A' && key != 'a' && key != '\r');
- printf("%c\n",key);
- RESPLIT_ACES = (key == 'A' || key == 'a');
- }
- printf("\n");
- // Compute basic strategy for every possible dealer up card.
- for (dealer_up_card = 1; dealer_up_card <= 10; dealer_up_card++) {
- // Compute probabilities of all possible dealer hands with the given up card.
- Compute_Dealer();
- player.New();
- // Compute expected value of HARD hands first, in DECREASING order. We have
- // to stop at 11, because we could hit a 10 with an ace and have a SOFT 21.
- for (player.count = 21; player.count >= 11; player.count--)
- Compute_Gain();
- // Now compute expected value of all SOFT hands, also in DECREASING order.
- player.num_aces = player.soft = 1;
- for (player.count = 21; player.count >= 12; player.count--)
- Compute_Gain();
- player.New();
- // Finish up the hard hands.
- for (player.count = 10; player.count >= 4; player.count--)
- Compute_Gain();
- // Now compute expected value of splitting all pairs.
- for (card = 1; card <= 10; card++)
- Compute_Split(card);
- }
- ////////////////////////////////////////////////////////////////////
- // Display results to output file.
- char filename[80];
- FILE *file;
- printf("Enter output filename: ");
- scanf("%s",filename);
- file = fopen(filename,"w");
- // Display strategy table for hard hands.
- fprintf(file," Basic Strategy Table\n\n");
- fprintf(file," Dealer's up card\n");
- fprintf(file,"Hard hands | 2 3 4 5 6 7 8 9 10 A\n");
- fprintf(file,"-----------|----------------------------------------\n");
- player.New();
- for (player.count = 4; player.count <= 21; player.count++) {
- fprintf(file,"%6d |",player.count);
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file," %c",Strategy());
- dealer_up_card = 1; fprintf(file," %c\n",Strategy());
- }
- // Display strategy table for soft hands.
- fprintf(file,"\n Dealer's up card\n");
- fprintf(file,"Soft hands | 2 3 4 5 6 7 8 9 10 A\n");
- fprintf(file,"-----------|----------------------------------------\n");
- player.New(); player.soft = TRUE;
- player.count = 12; fprintf(file," A- A |");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file," %c",Strategy());
- dealer_up_card = 1; fprintf(file," %c\n",Strategy());
- for (player.count = 13; player.count <= 21; player.count++) {
- fprintf(file," A-%2d |",player.count - 11);
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file," %c",Strategy());
- dealer_up_card = 1; fprintf(file," %c\n",Strategy());
- }
- // Display strategy table for pairs.
- fprintf(file,"\n Dealer's up card\n");
- fprintf(file," Pairs | 2 3 4 5 6 7 8 9 10 A\n");
- fprintf(file,"-----------|----------------------------------------\n");
- player.New(); player.Deal(1); player.Deal(1);
- fprintf(file," A- A |");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file," %c",Strategy_Split(1));
- dealer_up_card = 1; fprintf(file," %c\n",Strategy_Split(1));
- for (card = 2; card <= 10; card++) {
- player.New(); player.Deal(card); player.Deal(card);
- fprintf(file,"%5d-%2d |",card,card);
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file," %c",Strategy_Split(card));
- dealer_up_card = 1; fprintf(file," %c\n",Strategy_Split(card));
- }
- // Display legend.
- fprintf(file,"----------------------------------------------------\n");
- fprintf(file,"S Stand\n");
- fprintf(file,"H Hit\n");
- fprintf(file,"D Double down\n");
- if (RESPLIT) {
- fprintf(file,"T Split (and re-split)\n");
- fprintf(file,"P Split (only once)\n\n");
- }
- else
- fprintf(file,"T Split\n\n");
- fprintf(file,"Uppercase indicates action is favorable for player\n");
- fprintf(file,"Lowercase indicates action is favorable for house\n");
- // Display expected return.
- long double gain,overall = 0;
- fprintf(file,"\n Player's Expected Return\n\n");
- fprintf(file,"Dealer's up card | Expected Return\n");
- fprintf(file,"-----------------|----------------\n");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++) {
- gain = Expected_Return();
- fprintf(file,"%10d |%13Lf\n",dealer_up_card,gain);
- overall += gain*Chance_Card(dealer_up_card);
- }
- dealer_up_card = 1;
- gain = Expected_Return();
- fprintf(file," A |%13Lf\n",gain);
- overall += gain*Chance_Card(1);
- fprintf(file,"-----------------|----------------\n");
- fprintf(file," Overall |%13Lf\n",overall);
- // Display chance of all possible dealer hands.
- fprintf(file,"\n Probability of dealer's hand\n\n");
- fprintf(file,"Up card | Bust | 17 | 18 | 19 | 20 | 21 | Blackjack\n");
- fprintf(file,"--------|---------|---------|---------|---------|---------|---------|----------\n");
- chance_dealer_bust[0] = chance_dealer_blackjack[0] = 0;
- for (dealer.count = 17; dealer.count <= 21; dealer.count++)
- chance_dealer_count[0][dealer.count] = 0;
- for (dealer_up_card = 2; dealer_up_card < 10; dealer_up_card++) {
- fprintf(file,"%5d |%8.5Lf",dealer_up_card,
- chance_dealer_bust[dealer_up_card]);
- chance_dealer_bust[0] += chance_dealer_bust[dealer_up_card]*
- Chance_Card(dealer_up_card);
- for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
- fprintf(file," |%8.5Lf",
- chance_dealer_count[dealer_up_card][dealer.count]);
- chance_dealer_count[0][dealer.count] +=
- chance_dealer_count[dealer_up_card][dealer.count]*
- Chance_Card(dealer_up_card);
- }
- fprintf(file," |%8.5Lf\n",chance_dealer_blackjack[dealer_up_card]);
- }
- if (!PEEK_10) {
- fprintf(file," 10 |%8.5Lf",chance_dealer_bust[10]);
- chance_dealer_bust[0] += chance_dealer_bust[10]*Chance_Card(10);
- for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
- fprintf(file," |%8.5Lf",chance_dealer_count[10][dealer.count]);
- chance_dealer_count[0][dealer.count] +=
- chance_dealer_count[10][dealer.count]*Chance_Card(10);
- }
- fprintf(file," |%8.5Lf\n",Chance_Card(1));
- chance_dealer_blackjack[0] += Chance_Card(1)*Chance_Card(10);
- }
- else {
- fprintf(file," 10 |%8.5Lf",chance_dealer_bust[10]*
- ((long double)1 - Chance_Card(1)));
- chance_dealer_bust[0] += chance_dealer_bust[10]*((long double)1 -
- Chance_Card(1))*Chance_Card(10);
- for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
- fprintf(file," |%8.5Lf",chance_dealer_count[10][dealer.count]*
- ((long double)1 - Chance_Card(1)));
- chance_dealer_count[0][dealer.count] +=
- chance_dealer_count[10][dealer.count]*((long double)1 -
- Chance_Card(1))*Chance_Card(10);
- }
- fprintf(file," |%8.5Lf\n",Chance_Card(1));
- chance_dealer_blackjack[0] += Chance_Card(1)*Chance_Card(10);
- }
- fprintf(file," A |%8.5Lf",chance_dealer_bust[1]*
- ((long double)1 - Chance_Card(10)));
- chance_dealer_bust[0] += chance_dealer_bust[1]*((long double)1 -
- Chance_Card(10))*Chance_Card(1);
- for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
- fprintf(file," |%8.5Lf",chance_dealer_count[1][dealer.count]*
- ((long double)1 - Chance_Card(10)));
- chance_dealer_count[0][dealer.count] +=
- chance_dealer_count[1][dealer.count]*((long double)1 -
- Chance_Card(10))*Chance_Card(1);
- }
- fprintf(file," |%8.5Lf\n",Chance_Card(10));
- chance_dealer_blackjack[0] += Chance_Card(10)*Chance_Card(1);
- fprintf(file,"--------|---------|---------|---------|---------|---------|---------|----------\n");
- fprintf(file,"Overall |%8.5Lf",chance_dealer_bust[0]);
- for (dealer.count = 17; dealer.count <= 21; dealer.count++)
- fprintf(file," |%8.5Lf",chance_dealer_count[0][dealer.count]);
- fprintf(file," |%8.5Lf\n",chance_dealer_blackjack[0]);
- ////////////////////////////////////////////////////////////////////
- // Display expected values for hard hands.
- fprintf(file,"\n\t2\t3\t4\t5\t6\t7\t8\t9\t10\tA\n");
- player.New();
- for (player.count = 4; player.count <= 21; player.count++) {
- fprintf(file,"%d",player.count);
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
- fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
- fprintf(file,"Hit");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",hit[dealer_up_card][0][player.count]);
- fprintf(file,"\t%.9Lf\n",hit[1][0][player.count]);
- fprintf(file,"Double");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",double_down[dealer_up_card][0][player.count]);
- fprintf(file,"\t%.9Lf\n",double_down[1][0][player.count]);
- }
- // Display expected values for soft hands.
- fprintf(file,"\t2\t3\t4\t5\t6\t7\t8\t9\t10\tA\n");
- player.num_aces = player.soft = 1;
- for (player.count = 12; player.count <= 21; player.count++) {
- fprintf(file,"Soft %d",player.count);
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
- fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
- fprintf(file,"Hit");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",hit[dealer_up_card][1][player.count]);
- fprintf(file,"\t%.9Lf\n",hit[1][1][player.count]);
- fprintf(file,"Double");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",double_down[dealer_up_card][1][player.count]);
- fprintf(file,"\t%.9Lf\n",double_down[1][1][player.count]);
- }
- // Display expected values for splitting pairs.
- fprintf(file,"\t2\t3\t4\t5\t6\t7\t8\t9\t10\tA\n");
- player.New(); player.Deal(1); player.Deal(1);
- fprintf(file,"A-A");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
- fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
- fprintf(file,"Hit");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",hit[dealer_up_card][player.soft][player.count]);
- fprintf(file,"\t%.9Lf\n",hit[1][player.soft][player.count]);
- fprintf(file,"Double");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",double_down[dealer_up_card][player.soft][player.count]);
- fprintf(file,"\t%.9Lf\n",double_down[1][player.soft][player.count]);
- fprintf(file,"Split");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",split[dealer_up_card][1]);
- fprintf(file,"\t%.9Lf\n",split[1][1]);
- fprintf(file,"Resplit");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",resplit[dealer_up_card][1]);
- fprintf(file,"\t%.9Lf\n",resplit[1][1]);
- for (card = 2; card <= 10; card++) {
- player.New(); player.Deal(card); player.Deal(card);
- fprintf(file,"%d-%d",card,card);
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
- fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
- fprintf(file,"Hit");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",hit[dealer_up_card][player.soft][player.count]);
- fprintf(file,"\t%.9Lf\n",hit[1][player.soft][player.count]);
- fprintf(file,"Double");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",double_down[dealer_up_card][player.soft][player.count]);
- fprintf(file,"\t%.9Lf\n",double_down[1][player.soft][player.count]);
- fprintf(file,"Split");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",split[dealer_up_card][card]);
- fprintf(file,"\t%.9Lf\n",split[1][card]);
- fprintf(file,"Resplit");
- for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
- fprintf(file,"\t%.9Lf",resplit[dealer_up_card][card]);
- fprintf(file,"\t%.9Lf\n",resplit[1][card]);
- }
- fclose(file);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement