Advertisement
Guest User

Blackjack infinite deck calculations

a guest
Dec 13th, 2014
331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 30.18 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////
  2. // STRATEGY.CPP
  3. //
  4. // Calculates basic strategy with exact expected values for various styles
  5. // of casino blackjack, using an infinite deck approximation.
  6.  
  7. #include <stdio.h>
  8. #include <conio.h>
  9.  
  10. #define TRUE            1
  11. #define FALSE           0
  12. #define max(x,y)        (((x)>(y))?(x):(y))
  13.  
  14. ////////////////////////////////////////////////////////////////////
  15. // User-configurable game options.
  16.  
  17. int HIT_SOFT_17,                // TRUE if dealer hits on soft 17
  18.     PEEK_10,                    // TRUE if dealer peeks when showing a 10
  19.     DOUBLE_ANY_2,               // TRUE if doubling down is allowed on any 2
  20.                 // cards
  21.     DOUBLE_AFTER_SPLIT,         // TRUE if doubling down after splitting
  22.                 // pairs is allowed
  23.     RESPLIT,                    // TRUE if re-splitting pairs is allowed
  24.     RESPLIT_ACES;       // TRUE if re-splitting aces is allowed
  25.  
  26. ////////////////////////////////////////////////////////////////////
  27. // Dealer and player hands.
  28.  
  29. class Hand {
  30. public:
  31.   int count,                            // point total for the hand
  32.       num_aces,                         // number of aces in the hand
  33.       soft;                             // TRUE if the hand is "soft"
  34.  
  35. // New() gets rid of all cards in the hand.
  36.  
  37.   void New() {
  38.     count = num_aces = soft = 0;
  39.   }
  40.  
  41. // Deal() "deals" the given card into the hand.
  42.  
  43.   void Deal(int card) {
  44.     count += card;                      // add to point total
  45.     if (card == 1) {            // aces are special
  46.       num_aces++;
  47.       if (count < 12) {         // count as 11 if possible
  48.     count += 10;            // (a "soft" hand)
  49.     soft = TRUE;
  50.       }
  51.     }
  52.     if (count > 21 && soft) {           // if count is too high to count ace
  53.       count -= 10;          // as 11, count it as 1
  54.       soft = FALSE;
  55.     }
  56.   }
  57.  
  58. // Undeal() removes the given card from the hand.
  59.  
  60.   void Undeal(int card) {
  61.     count -= card;                      // decrease point total
  62.     if (card == 1) {                    // if removing an ace
  63.       num_aces--;
  64.       if (!num_aces && soft) {          // and the soft hand now has no
  65.     count -= 10;                    // aces, make the hand "hard"
  66.     soft = FALSE;
  67.       }
  68.     }
  69.     if (count < 12 && num_aces &&       // if ace can now count as 11, make
  70.     !soft) {            // hand soft
  71.       count += 10;
  72.       soft = TRUE;
  73.     }
  74.   }
  75. };
  76.  
  77. Hand dealer; int dealer_up_card;        // dealer's hand, PLUS up card
  78. Hand player;                            // player's hand
  79.  
  80. ////////////////////////////////////////////////////////////////////
  81. // Chance_Card() returns the probability of drawing the given card from the
  82. // deck (constant for infinite deck).
  83.  
  84. long double Chance_Card(int card) {
  85.   if (card == 10)
  86.     return((long double)4/13);          // 4 of every 13 is a 10
  87.   else
  88.     return((long double)1/13);          // all others are 1 in 13
  89. }
  90.  
  91. ////////////////////////////////////////////////////////////////////
  92. // Probability of every possible dealer hand for every possible up card. For
  93. // example, chance_dealer_count[6][21] is the probability of the dealer
  94. // standing on a count of 21 with 6 as an up card.
  95.  
  96. long double chance_dealer_bust[11],
  97.         chance_dealer_count[11][22],
  98.         chance_dealer_blackjack[11];
  99.  
  100. ////////////////////////////////////////////////////////////////////
  101. // Dealer() is called by Compute_Dealer() to recursively compute the
  102. // probability of every possible dealer hand.
  103.  
  104. void Dealer(long double chance) {
  105.   int card;
  106.  
  107.   if (dealer.count < 17 ||                      // if dealer should hit
  108.      (dealer.count == 17 && HIT_SOFT_17 &&      // (maybe on a soft 17)
  109.     dealer.soft))
  110.     for (card = 1; card <= 10; card++) {        // deal every possible card
  111.       dealer.Deal(card);
  112.       Dealer(chance*Chance_Card(card));         // with a given probability
  113.       dealer.Undeal(card);
  114.     }
  115.   else if (dealer.count > 21)                   // dealer busts
  116.     chance_dealer_bust[dealer_up_card] += chance;
  117.  
  118. // Dealer stands; note that blackjacks are handled by Compute_Dealer().
  119.  
  120.   else
  121.     chance_dealer_count[dealer_up_card][dealer.count] += chance;
  122. }
  123.  
  124. ////////////////////////////////////////////////////////////////////
  125. // Compute_Dealer() calls Dealer() to compute dealer probabilities for the
  126. // up card specified by dealer_up_card.
  127.  
  128. void Compute_Dealer() {
  129.   int card;
  130.  
  131. // Reset all dealer probabilities.
  132.  
  133.   chance_dealer_bust[dealer_up_card] =
  134.     chance_dealer_blackjack[dealer_up_card] = 0;
  135.   for (dealer.count = 17; dealer.count <= 21; dealer.count++)
  136.     chance_dealer_count[dealer_up_card][dealer.count] = 0;
  137.   dealer.New(); dealer.Deal(dealer_up_card);    // deal JUST the up card
  138.   switch (dealer_up_card) {
  139.  
  140. // Dealer ALWAYS checks for blackjack when showing an ace, so assume the hole
  141. // card is NEVER a 10.
  142.  
  143.     case 1  : for (card = 1; card < 10;         // deal every card but a 10
  144.             card++) {
  145.         dealer.Deal(card);
  146.         Dealer(Chance_Card(card)/       // chance of that card, GIVEN
  147.             ((long double)1 -       // that it's not a 10
  148.             Chance_Card(10)));
  149.         dealer.Undeal(card);
  150.           }
  151.           break;
  152.  
  153. // If the dealer checks for blackjack when showing a 10, assume the hole card
  154. // is NOT an ace, as above.
  155.  
  156.     case 10 : if (PEEK_10)
  157.         for (card = 2; card <= 10; card++) {
  158.           dealer.Deal(card);
  159.           Dealer(Chance_Card(card)/
  160.             ((long double)1 - Chance_Card(1)));
  161.           dealer.Undeal(card);
  162.         }
  163.  
  164. // If the dealer does NOT peek when showing a 10, the hole card could be an
  165. // ace, but handle it here.
  166.  
  167.           else {
  168.         for (card = 2; card <= 10; card++) {
  169.           dealer.Deal(card);
  170.           Dealer(Chance_Card(card));
  171.           dealer.Undeal(card);
  172.         }
  173.         chance_dealer_blackjack[dealer_up_card] =
  174.             Chance_Card(1);         // chance of blackjack =
  175.           }                                 // chance hole card is an ace
  176.           break;
  177.  
  178. // All other up cards are no problem.
  179.  
  180.     default : Dealer(1);
  181.   }
  182. }
  183.  
  184. ////////////////////////////////////////////////////////////////////
  185. // Expected value of every possible player action for every possible
  186. // combination of player hand and dealer up card. For example:
  187.  
  188. // stand[7][16] is the expected value of standing on a 16 against a dealer's
  189. // 7. Note that these values are the same for "hard" and "soft" hands.
  190.  
  191. long double stand[11][22],
  192.  
  193. // hit[6][0][12] is the expected value of hitting a HARD (that's the 0) 12
  194. // against a dealer's 6.
  195.  
  196.         hit[11][2][22],
  197.  
  198. // double_down[6][1][18] is the expected value of doubling down on a SOFT
  199. // (that's the 1) 18 (i.e. A-7) against a dealer's 6.
  200.  
  201.         double_down[11][2][22],
  202.  
  203. // split[7][9] is the expected value of splitting a pair of 9's against a
  204. // dealer's 7, BUT NOT SPLITTING ANY ADDITIONAL 9's YOU MAY DRAW.
  205.  
  206.         split[11][11],
  207.  
  208. // resplit[7][9] is the expected value of splitting a pair of 9's against a
  209. // dealer's 7, AND RE-SPLITTING ANY ADDITIONAL 9's YOU MAY DRAW.
  210.  
  211.         resplit[11][11];
  212.  
  213. ////////////////////////////////////////////////////////////////////
  214. // Compute_Gain() computes the expected value of standing, hitting, and
  215. // doubling down on the player's hand (given in the player instance of Hand)
  216. // against the dealer's up card (in dealer_up_card).
  217.  
  218. void Compute_Gain() {
  219.   int card;
  220.   long double gain;
  221.  
  222. // Calculate expected value of standing.
  223.  
  224.   stand[dealer_up_card][player.count] =
  225.     chance_dealer_bust[dealer_up_card] -    // win if dealer busts
  226.     chance_dealer_blackjack[dealer_up_card]; // lose if dealer has BJ
  227.   for (dealer.count = 17; dealer.count <= 21;   // if dealer stands
  228.     dealer.count++)
  229.     if (player.count > dealer.count)            // win if player's count
  230.       stand[dealer_up_card][player.count] +=    // beats dealer's count
  231.     chance_dealer_count[dealer_up_card][dealer.count];
  232.     else if (player.count < dealer.count)       // lose if dealer's count
  233.       stand[dealer_up_card][player.count] -=    // beats player's count
  234.     chance_dealer_count[dealer_up_card][dealer.count];
  235.  
  236. // Calculate expected value of hitting.
  237.  
  238.   hit[dealer_up_card][player.soft]              // reset expected value
  239.     [player.count] = 0;
  240.   for (card = 1; card <= 10; card++) {          // for all possible hit cards
  241.     player.Deal(card);                          // deal the card
  242.  
  243. ////////////////////////////////////////////////////////////////////
  244. // This is the heart of the algorithm. If the player didn't bust after
  245. // hitting, we need to know the expected value of the player's NEW hand. We
  246. // WILL know this, as long as we have made each of the calls to
  247. // Compute_Gain() (one for each possible player hand) IN THE RIGHT ORDER.
  248.  
  249.     if (player.count <= 21)                     // if player didn't bust
  250.       gain = max(                               // get BEST expected value of
  251.     stand[dealer_up_card][player.count],    // the NEW hand (player can
  252.     hit[dealer_up_card][player.soft]        // either stand or hit)
  253.         [player.count]);
  254.     else                                        // player always loses on a
  255.       gain = -1;                                // bust
  256.     player.Undeal(card);
  257.     hit[dealer_up_card][player.soft]            // weight value of new hand
  258.     [player.count] +=                       // with chance of drawing
  259.     gain*Chance_Card(card);                 // that card
  260.   }
  261.  
  262. // Calculate expected value of doubling down. Note the expected value is
  263. // reset with the probability of the dealer having blackjack, and not 0. This
  264. // is because IF the dealer has blackjack, the player only loses his original
  265. // bet, and not his additional double down bet. Subsequent calculations don't
  266. // take this into account, so we make the correction at the outset.
  267.  
  268.   double_down[dealer_up_card][player.soft][player.count] =
  269.     chance_dealer_blackjack[dealer_up_card];
  270.   for (card = 1; card <= 10; card++) {          // for all possible hit cards
  271.     player.Deal(card);                          // deal the card
  272.     if (player.count <= 21)                     // if player didn't bust
  273.       gain = stand[dealer_up_card][player.count]*2; // player HAS to stand
  274.     else
  275.       gain = -2;                                // lose it all if hand busts
  276.     player.Undeal(card);
  277.     double_down[dealer_up_card][player.soft]    // weight value with chance
  278.     [player.count] +=                       // of drawing that card
  279.     gain*Chance_Card(card);
  280.   }
  281. }
  282.  
  283. ////////////////////////////////////////////////////////////////////
  284. // Compute_Split() computes the expected value of splitting the given pair of
  285. // cards against the dealer's up card (in dealer_up_card).
  286.  
  287. void Compute_Split(int pair_card) {
  288.   int card;
  289.   long double gain;
  290.  
  291.   split[dealer_up_card][pair_card] =            // reset expected values
  292.     resplit[dealer_up_card][pair_card] = 0;
  293.  
  294. // We can assume the pair has already been split, and compute the expected
  295. // value of ONE of the two NEW hands. For an INFINITE deck, the expected
  296. // value of the split will simply be twice this value.
  297.  
  298.   player.New(); player.Deal(pair_card);         // deal the split card
  299.   for (card = 1; card <= 10; card++) {          // for all possible second
  300.     player.Deal(card);                          // cards, deal that card
  301.     gain = stand[dealer_up_card][player.count]; // get EV of standing
  302.     if (pair_card != 1) {                       // can't hit split aces!
  303.       gain = max(gain,                          // otherwise, maybe hitting
  304.     hit[dealer_up_card][player.soft][player.count]); // is better
  305.       if (DOUBLE_AFTER_SPLIT &&
  306.     (DOUBLE_ANY_2 || player.count == 10 || player.count == 11 ||
  307.     (player.count == 20 && player.soft) ||
  308.     (player.count == 21 && player.soft)))   // or (if allowed) doubling
  309.     gain = max(gain,                        // down
  310.         double_down[dealer_up_card][player.soft][player.count]);
  311.     }
  312.     player.Undeal(card);
  313.     split[dealer_up_card][pair_card] +=         // weight EV with chance of
  314.     gain*Chance_Card(card);                 // drawing that card
  315.  
  316. // If the hit card makes ANOTHER pair, and re-splitting IS ALLOWED, then the
  317. // EV of the new hand is exactly the value we are trying to calculate (this
  318. // is similar to the problem of integrating e^x sin x by parts)! So we "put
  319. // off" this calculation and "solve" for the EV when we're finished.
  320.  
  321.     if (card != pair_card)
  322.       resplit[dealer_up_card][pair_card] += gain*Chance_Card(card);
  323.   }
  324.  
  325. // The expected value of the split is twice the value of one split hand;
  326. // however, as when doubling down, the player only loses his original bet if
  327. // the dealer has blackjack, so the same correction must be made.
  328.  
  329.   split[dealer_up_card][pair_card] *= 2;
  330.   split[dealer_up_card][pair_card] +=
  331.     chance_dealer_blackjack[dealer_up_card];
  332.  
  333. // The expected value of splitting AND RE-SPLITTING is almost the same, mod a
  334. // "normalization" as a result of "solving" for the EV.
  335.  
  336.   resplit[dealer_up_card][pair_card] *= 2;
  337.   resplit[dealer_up_card][pair_card] +=
  338.     chance_dealer_blackjack[dealer_up_card];
  339.   resplit[dealer_up_card][pair_card] /=
  340.       (long double)1 - Chance_Card(pair_card)*2;
  341. }
  342.  
  343. ////////////////////////////////////////////////////////////////////
  344. // Strategy() and Strategy_Split() return the character abbreviation for the
  345. // best action for the given player's hand and dealer's up card. Uppercase
  346. // means favorable for the player, lowercase means favorable for the house.
  347.  
  348. char Strategy() {
  349.   char strategy;
  350.   long double s = stand[dealer_up_card][player.count],
  351.           h = hit[dealer_up_card][player.soft][player.count],
  352.           d = double_down[dealer_up_card][player.soft][player.count];
  353.  
  354.   if (!DOUBLE_ANY_2 && player.count != 10 && player.count != 11 &&
  355.     !(player.count == 20 && player.soft) &&
  356.     !(player.count == 21 && player.soft))
  357.     d = -2;
  358.   if (s > h && s > d)
  359.     if (s < 0) strategy = 's'; else strategy = 'S';
  360.   else if (h > d)
  361.     if (h < 0) strategy = 'h'; else strategy = 'H';
  362.   else
  363.     if (d < 0) strategy = 'd'; else strategy = 'D';
  364.   return(strategy);
  365. }
  366.  
  367. char Strategy_Split(int card) {
  368.   char strategy;
  369.   long double s = stand[dealer_up_card][player.count],
  370.           h = hit[dealer_up_card][player.soft][player.count],
  371.           d = double_down[dealer_up_card][player.soft][player.count],
  372.           t = split[dealer_up_card][card],
  373.           p = resplit[dealer_up_card][card];
  374.  
  375.   if (!DOUBLE_ANY_2 && player.count != 10) d = -2;
  376.   if (!RESPLIT || (!RESPLIT_ACES && card == 1)) p = -2;
  377.   if (s > h && s > d && s > t && s > p)
  378.     if (s < 0) strategy = 's'; else strategy = 'S';
  379.   else if (h > d && h > t && h > p)
  380.     if (h < 0) strategy = 'h'; else strategy = 'H';
  381.   else if (d > t && d > p)
  382.     if (d < 0) strategy = 'd'; else strategy = 'D';
  383.   else if (t > p)
  384.     if (RESPLIT)
  385.       if (t < 0) strategy = 'p'; else strategy = 'P';
  386.     else
  387.       if (t < 0) strategy = 't'; else strategy = 'T';
  388.   else
  389.     if (p < 0) strategy = 't'; else strategy = 'T';
  390.   return(strategy);
  391. }
  392.  
  393. ////////////////////////////////////////////////////////////////////
  394. // Expected_Return() returns the expected gain against the dealer's up card.
  395.  
  396. long double Expected_Return() {
  397.   long double gain,total = 0;
  398.   int card1,card2;
  399.  
  400.   for (card1 = 1; card1 <= 10; card1++)
  401.     for (card2 = 1; card2 <= 10; card2++) {
  402.       player.New(); player.Deal(card1); player.Deal(card2);
  403.       gain = max(stand[dealer_up_card][player.count],
  404.     hit[dealer_up_card][player.soft][player.count]);
  405.       if (DOUBLE_ANY_2 || player.count == 10 || player.count == 11)
  406.     gain = max(gain,
  407.         double_down[dealer_up_card][player.soft][player.count]);
  408.       if (card1 == card2) {
  409.     gain = max(gain,split[dealer_up_card][card1]);
  410.     if (RESPLIT && (RESPLIT_ACES || card1 != 1))
  411.       gain = max(gain,resplit[dealer_up_card][card1]);
  412.       }
  413.       if (dealer_up_card == 1)
  414.     gain = gain*((long double)1 - Chance_Card(10)) -
  415.           Chance_Card(10);
  416.       if (dealer_up_card == 10 && PEEK_10)
  417.     gain = gain*((long double)1 - Chance_Card(1)) -
  418.           Chance_Card(1);
  419.       if (player.count == 21) {
  420.     gain = (long double)3/2;
  421.     if (dealer_up_card == 1)
  422.       gain *= (long double)1 - Chance_Card(10);
  423.     else if (dealer_up_card == 10)
  424.       gain *= (long double)1 - Chance_Card(1);
  425.       }
  426.       total += gain*Chance_Card(card1)*Chance_Card(card2);
  427.   }
  428.   return(total);
  429. }
  430.  
  431. ////////////////////////////////////////////////////////////////////
  432. // Main program.
  433.  
  434. void main() {
  435.   char key;
  436.   int card;
  437.  
  438.   printf("\n\nBlackjack strategy calculator\n\n");
  439.  
  440. // Set user-configurable game options.
  441.  
  442.   printf("Press 'H' if dealer hits on soft 17, 'Enter' otherwise: ");
  443.   while ((key = getch()) != 'H' && key != 'h' && key != '\r');
  444.   printf("%c\n",key);
  445.   HIT_SOFT_17 = (key == 'H' || key == 'h');
  446.  
  447.   printf("Press 'P' if dealer peeks when showing a 10, 'Enter' otherwise: ");
  448.   while ((key = getch()) != 'P' && key != 'p' && key != '\r');
  449.   printf("%c\n",key);
  450.   PEEK_10 = (key == 'P' || key == 'p');
  451.  
  452.   printf("Press 'D' if doubling down is allowed on any two cards, ");
  453.   printf("'Enter' otherwise: ");
  454.   while ((key = getch()) != 'D' && key != 'd' && key != '\r');
  455.   printf("%c\n",key);
  456.   DOUBLE_ANY_2 = (key == 'D' || key == 'd');
  457.  
  458.   printf("Press 'D' if doubling down after splitting is allowed, ");
  459.   printf("'Enter' otherwise: ");
  460.   while ((key = getch()) != 'D' && key != 'd' && key != '\r');
  461.   printf("%c\n",key);
  462.   DOUBLE_AFTER_SPLIT = (key == 'D' || key == 'd');
  463.  
  464.   printf("Press 'R' if re-splitting pairs is allowed, 'Enter' otherwise: ");
  465.   while ((key = getch()) != 'R' && key != 'r' && key != '\r');
  466.   printf("%c\n",key);
  467.   RESPLIT = (key == 'R' || key == 'r');
  468.  
  469.   RESPLIT_ACES = FALSE;
  470.   if (RESPLIT) {
  471.     printf("Press 'A' if re-splitting aces is allowed, 'Enter' otherwise: ");
  472.     while ((key = getch()) != 'A' && key != 'a' && key != '\r');
  473.     printf("%c\n",key);
  474.     RESPLIT_ACES = (key == 'A' || key == 'a');
  475.   }
  476.   printf("\n");
  477.  
  478. // Compute basic strategy for every possible dealer up card.
  479.  
  480.   for (dealer_up_card = 1; dealer_up_card <= 10; dealer_up_card++) {
  481.  
  482. // Compute probabilities of all possible dealer hands with the given up card.
  483.  
  484.     Compute_Dealer();
  485.     player.New();
  486.  
  487. // Compute expected value of HARD hands first, in DECREASING order. We have
  488. // to stop at 11, because we could hit a 10 with an ace and have a SOFT 21.
  489.  
  490.     for (player.count = 21; player.count >= 11; player.count--)
  491.       Compute_Gain();
  492.  
  493. // Now compute expected value of all SOFT hands, also in DECREASING order.
  494.  
  495.     player.num_aces = player.soft = 1;
  496.     for (player.count = 21; player.count >= 12; player.count--)
  497.       Compute_Gain();
  498.     player.New();
  499.  
  500. // Finish up the hard hands.
  501.  
  502.     for (player.count = 10; player.count >= 4; player.count--)
  503.       Compute_Gain();
  504.  
  505. // Now compute expected value of splitting all pairs.
  506.  
  507.     for (card = 1; card <= 10; card++)
  508.       Compute_Split(card);
  509.   }
  510.  
  511. ////////////////////////////////////////////////////////////////////
  512. // Display results to output file.
  513.  
  514.   char filename[80];
  515.   FILE *file;
  516.  
  517.   printf("Enter output filename: ");
  518.   scanf("%s",filename);
  519.   file = fopen(filename,"w");
  520.  
  521. // Display strategy table for hard hands.
  522.  
  523.   fprintf(file,"                Basic Strategy Table\n\n");
  524.   fprintf(file,"                         Dealer's up card\n");
  525.   fprintf(file,"Hard hands |   2   3   4   5   6   7   8   9  10   A\n");
  526.   fprintf(file,"-----------|----------------------------------------\n");
  527.   player.New();
  528.   for (player.count = 4; player.count <= 21; player.count++) {
  529.     fprintf(file,"%6d     |",player.count);
  530.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  531.       fprintf(file,"   %c",Strategy());
  532.     dealer_up_card = 1; fprintf(file,"   %c\n",Strategy());
  533.   }
  534.  
  535. // Display strategy table for soft hands.
  536.  
  537.   fprintf(file,"\n                         Dealer's up card\n");
  538.   fprintf(file,"Soft hands |   2   3   4   5   6   7   8   9  10   A\n");
  539.   fprintf(file,"-----------|----------------------------------------\n");
  540.   player.New(); player.soft = TRUE;
  541.   player.count = 12; fprintf(file,"    A- A   |");
  542.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  543.     fprintf(file,"   %c",Strategy());
  544.   dealer_up_card = 1; fprintf(file,"   %c\n",Strategy());
  545.   for (player.count = 13; player.count <= 21; player.count++) {
  546.     fprintf(file,"    A-%2d   |",player.count - 11);
  547.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  548.       fprintf(file,"   %c",Strategy());
  549.     dealer_up_card = 1; fprintf(file,"   %c\n",Strategy());
  550.   }
  551.  
  552. // Display strategy table for pairs.
  553.  
  554.   fprintf(file,"\n                         Dealer's up card\n");
  555.   fprintf(file,"   Pairs   |   2   3   4   5   6   7   8   9  10   A\n");
  556.   fprintf(file,"-----------|----------------------------------------\n");
  557.   player.New(); player.Deal(1); player.Deal(1);
  558.   fprintf(file,"    A- A   |");
  559.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  560.     fprintf(file,"   %c",Strategy_Split(1));
  561.   dealer_up_card = 1; fprintf(file,"   %c\n",Strategy_Split(1));
  562.   for (card = 2; card <= 10; card++) {
  563.     player.New(); player.Deal(card); player.Deal(card);
  564.     fprintf(file,"%5d-%2d   |",card,card);
  565.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  566.       fprintf(file,"   %c",Strategy_Split(card));
  567.     dealer_up_card = 1; fprintf(file,"   %c\n",Strategy_Split(card));
  568.   }
  569.  
  570. // Display legend.
  571.  
  572.   fprintf(file,"----------------------------------------------------\n");
  573.   fprintf(file,"S  Stand\n");
  574.   fprintf(file,"H  Hit\n");
  575.   fprintf(file,"D  Double down\n");
  576.   if (RESPLIT) {
  577.     fprintf(file,"T  Split (and re-split)\n");
  578.     fprintf(file,"P  Split (only once)\n\n");
  579.   }
  580.   else
  581.     fprintf(file,"T  Split\n\n");
  582.   fprintf(file,"Uppercase indicates action is favorable for player\n");
  583.   fprintf(file,"Lowercase indicates action is favorable for house\n");
  584.  
  585. // Display expected return.
  586.  
  587.   long double gain,overall = 0;
  588.   fprintf(file,"\n     Player's Expected Return\n\n");
  589.   fprintf(file,"Dealer's up card | Expected Return\n");
  590.   fprintf(file,"-----------------|----------------\n");
  591.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++) {
  592.     gain = Expected_Return();
  593.     fprintf(file,"%10d       |%13Lf\n",dealer_up_card,gain);
  594.     overall += gain*Chance_Card(dealer_up_card);
  595.   }
  596.   dealer_up_card = 1;
  597.   gain = Expected_Return();
  598.   fprintf(file,"         A       |%13Lf\n",gain);
  599.   overall += gain*Chance_Card(1);
  600.   fprintf(file,"-----------------|----------------\n");
  601.   fprintf(file,"     Overall     |%13Lf\n",overall);
  602.  
  603. // Display chance of all possible dealer hands.
  604.  
  605.   fprintf(file,"\n                         Probability of dealer's hand\n\n");
  606.   fprintf(file,"Up card |   Bust  |    17   |    18   |    19   |    20   |    21   | Blackjack\n");
  607.   fprintf(file,"--------|---------|---------|---------|---------|---------|---------|----------\n");
  608.   chance_dealer_bust[0] = chance_dealer_blackjack[0] = 0;
  609.   for (dealer.count = 17; dealer.count <= 21; dealer.count++)
  610.     chance_dealer_count[0][dealer.count] = 0;
  611.   for (dealer_up_card = 2; dealer_up_card < 10; dealer_up_card++) {
  612.     fprintf(file,"%5d   |%8.5Lf",dealer_up_card,
  613.     chance_dealer_bust[dealer_up_card]);
  614.     chance_dealer_bust[0] += chance_dealer_bust[dealer_up_card]*
  615.     Chance_Card(dealer_up_card);
  616.     for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
  617.       fprintf(file," |%8.5Lf",
  618.     chance_dealer_count[dealer_up_card][dealer.count]);
  619.       chance_dealer_count[0][dealer.count] +=
  620.     chance_dealer_count[dealer_up_card][dealer.count]*
  621.     Chance_Card(dealer_up_card);
  622.     }
  623.     fprintf(file," |%8.5Lf\n",chance_dealer_blackjack[dealer_up_card]);
  624.   }
  625.   if (!PEEK_10) {
  626.     fprintf(file,"   10   |%8.5Lf",chance_dealer_bust[10]);
  627.     chance_dealer_bust[0] += chance_dealer_bust[10]*Chance_Card(10);
  628.     for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
  629.       fprintf(file," |%8.5Lf",chance_dealer_count[10][dealer.count]);
  630.       chance_dealer_count[0][dealer.count] +=
  631.       chance_dealer_count[10][dealer.count]*Chance_Card(10);
  632.     }
  633.     fprintf(file," |%8.5Lf\n",Chance_Card(1));
  634.     chance_dealer_blackjack[0] += Chance_Card(1)*Chance_Card(10);
  635.   }
  636.   else {
  637.     fprintf(file,"   10   |%8.5Lf",chance_dealer_bust[10]*
  638.       ((long double)1 - Chance_Card(1)));
  639.     chance_dealer_bust[0] += chance_dealer_bust[10]*((long double)1 -
  640.       Chance_Card(1))*Chance_Card(10);
  641.     for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
  642.       fprintf(file," |%8.5Lf",chance_dealer_count[10][dealer.count]*
  643.       ((long double)1 - Chance_Card(1)));
  644.       chance_dealer_count[0][dealer.count] +=
  645.       chance_dealer_count[10][dealer.count]*((long double)1 -
  646.           Chance_Card(1))*Chance_Card(10);
  647.     }
  648.     fprintf(file," |%8.5Lf\n",Chance_Card(1));
  649.     chance_dealer_blackjack[0] += Chance_Card(1)*Chance_Card(10);
  650.   }
  651.   fprintf(file,"    A   |%8.5Lf",chance_dealer_bust[1]*
  652.     ((long double)1 - Chance_Card(10)));
  653.   chance_dealer_bust[0] += chance_dealer_bust[1]*((long double)1 -
  654.     Chance_Card(10))*Chance_Card(1);
  655.   for (dealer.count = 17; dealer.count <= 21; dealer.count++) {
  656.     fprintf(file," |%8.5Lf",chance_dealer_count[1][dealer.count]*
  657.     ((long double)1 - Chance_Card(10)));
  658.     chance_dealer_count[0][dealer.count] +=
  659.     chance_dealer_count[1][dealer.count]*((long double)1 -
  660.         Chance_Card(10))*Chance_Card(1);
  661.   }
  662.   fprintf(file," |%8.5Lf\n",Chance_Card(10));
  663.   chance_dealer_blackjack[0] += Chance_Card(10)*Chance_Card(1);
  664.   fprintf(file,"--------|---------|---------|---------|---------|---------|---------|----------\n");
  665.   fprintf(file,"Overall |%8.5Lf",chance_dealer_bust[0]);
  666.   for (dealer.count = 17; dealer.count <= 21; dealer.count++)
  667.     fprintf(file," |%8.5Lf",chance_dealer_count[0][dealer.count]);
  668.   fprintf(file," |%8.5Lf\n",chance_dealer_blackjack[0]);
  669.  
  670. ////////////////////////////////////////////////////////////////////
  671. // Display expected values for hard hands.
  672.  
  673.   fprintf(file,"\n\t2\t3\t4\t5\t6\t7\t8\t9\t10\tA\n");
  674.   player.New();
  675.   for (player.count = 4; player.count <= 21; player.count++) {
  676.     fprintf(file,"%d",player.count);
  677.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  678.       fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
  679.     fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
  680.     fprintf(file,"Hit");
  681.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  682.       fprintf(file,"\t%.9Lf",hit[dealer_up_card][0][player.count]);
  683.     fprintf(file,"\t%.9Lf\n",hit[1][0][player.count]);
  684.     fprintf(file,"Double");
  685.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  686.       fprintf(file,"\t%.9Lf",double_down[dealer_up_card][0][player.count]);
  687.     fprintf(file,"\t%.9Lf\n",double_down[1][0][player.count]);
  688.   }
  689.  
  690. // Display expected values for soft hands.
  691.  
  692.   fprintf(file,"\t2\t3\t4\t5\t6\t7\t8\t9\t10\tA\n");
  693.   player.num_aces = player.soft = 1;
  694.   for (player.count = 12; player.count <= 21; player.count++) {
  695.     fprintf(file,"Soft %d",player.count);
  696.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  697.       fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
  698.     fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
  699.     fprintf(file,"Hit");
  700.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  701.       fprintf(file,"\t%.9Lf",hit[dealer_up_card][1][player.count]);
  702.     fprintf(file,"\t%.9Lf\n",hit[1][1][player.count]);
  703.     fprintf(file,"Double");
  704.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  705.       fprintf(file,"\t%.9Lf",double_down[dealer_up_card][1][player.count]);
  706.     fprintf(file,"\t%.9Lf\n",double_down[1][1][player.count]);
  707.   }
  708.  
  709. // Display expected values for splitting pairs.
  710.  
  711.   fprintf(file,"\t2\t3\t4\t5\t6\t7\t8\t9\t10\tA\n");
  712.   player.New(); player.Deal(1); player.Deal(1);
  713.   fprintf(file,"A-A");
  714.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  715.     fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
  716.   fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
  717.   fprintf(file,"Hit");
  718.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  719.     fprintf(file,"\t%.9Lf",hit[dealer_up_card][player.soft][player.count]);
  720.   fprintf(file,"\t%.9Lf\n",hit[1][player.soft][player.count]);
  721.   fprintf(file,"Double");
  722.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  723.     fprintf(file,"\t%.9Lf",double_down[dealer_up_card][player.soft][player.count]);
  724.   fprintf(file,"\t%.9Lf\n",double_down[1][player.soft][player.count]);
  725.   fprintf(file,"Split");
  726.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  727.     fprintf(file,"\t%.9Lf",split[dealer_up_card][1]);
  728.   fprintf(file,"\t%.9Lf\n",split[1][1]);
  729.   fprintf(file,"Resplit");
  730.   for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  731.     fprintf(file,"\t%.9Lf",resplit[dealer_up_card][1]);
  732.   fprintf(file,"\t%.9Lf\n",resplit[1][1]);
  733.   for (card = 2; card <= 10; card++) {
  734.     player.New(); player.Deal(card); player.Deal(card);
  735.     fprintf(file,"%d-%d",card,card);
  736.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  737.       fprintf(file,"\t%.9Lf",stand[dealer_up_card][player.count]);
  738.     fprintf(file,"\t%.9Lf\n",stand[1][player.count]);
  739.     fprintf(file,"Hit");
  740.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  741.       fprintf(file,"\t%.9Lf",hit[dealer_up_card][player.soft][player.count]);
  742.     fprintf(file,"\t%.9Lf\n",hit[1][player.soft][player.count]);
  743.     fprintf(file,"Double");
  744.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  745.       fprintf(file,"\t%.9Lf",double_down[dealer_up_card][player.soft][player.count]);
  746.     fprintf(file,"\t%.9Lf\n",double_down[1][player.soft][player.count]);
  747.     fprintf(file,"Split");
  748.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  749.       fprintf(file,"\t%.9Lf",split[dealer_up_card][card]);
  750.     fprintf(file,"\t%.9Lf\n",split[1][card]);
  751.     fprintf(file,"Resplit");
  752.     for (dealer_up_card = 2; dealer_up_card <= 10; dealer_up_card++)
  753.       fprintf(file,"\t%.9Lf",resplit[dealer_up_card][card]);
  754.     fprintf(file,"\t%.9Lf\n",resplit[1][card]);
  755.   }
  756.  
  757.   fclose(file);
  758. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement