In blackjack, face cards (K, Q, J) counts as 10, an ace counts as 1 or 11, and the other cards count their value. The goal is to get as close to 21 as possible without going over, and to beat the dealer's hand. Once all the players finish, the dealer plays his hand according to specified rules. This project is only going to look at the dealer's play.

The algorithm for the dealer can be expressed as follows:

- If the total is 16 or less, take another card and repeat this step
- Otherwise, take no more cards, and settle all bets

The dealer may therefore end up with any of the following scores: 17, 18, 19, 20, 21, blackjack, or bust. The question is, for any given upcard, what are the probabilities the dealer will end up with each of these possible results? A blackjack is a 21 composed of exactly two cards - an Ace and a 10-value card. Since the rules treat blackjacks differently than other 21-counts, it should be considered a separate result for the dealer.

Use a shoe of 6 decks of 52 cards, or 312 total cards. Create a vector of the necessary length, and place the numbers above in the vector so the counts are correct. You should print out this vector of values and verify for yourself that the values are correct.

Next, your program should deal cards from this deck to the dealer's hand until the total is over 16, as the rule above indicates. You will have to be careful how you treat Aces. Print out the values of the cards in the order they are dealt, and verify that the dealing stops as appropriate. You should prompt the user once for a random seed value and generate one deal only. (Therefore if you use the same seed you should get the same hand dealt.) How can you verify that your dealing algorithm is not dealing the same card more than once?

Store this program as 21a.cpp in the lab3 folder of your eng101 space. While you may handle aces differently, your program should work something like this:

ruby% a.out Seed ? 1 Cards dealt: 11 5 10 10 :: total = 26 ruby% a.out Seed ? 6 Cards dealt: 10 10 :: total = 20 ruby% a.out Seed ? 9 Cards dealt: 4 3 3 2 4 10 :: total = 26 ruby% a.out Seed ? 12345 Cards dealt: 11 6 :: total = 17 ruby% a.out Seed ? 13 Cards dealt: 10 11 :: total = 21 ruby% a.out Seed ? 1 Cards dealt: 11 5 10 10 :: total = 26

Next display these statistics as probabilities in a readable grid structure.

Finally, change the dealer rules so the dealer hits on a soft 17, and generate revised statistics on 1,000,000 deals using the same seed value. Compare the two. Where did you expect differences? Where are there differences? Can you determine which one should be more favorable to the house? If not, would more deals help?

Store your final program using the soft 17 rule as 21b.cpp in the lab3 folder of your eng101 space.

Your program should have the following rough structure:

- Set up the deck
- do the following 1,000,000 times
- shuffle the deck
- remember the first card dealt
- if the total is less than 17 (optionally also a soft 17)
- deal another card from the deck
- update the total

- identify busts and blackjacks
- keep track of the times this final result happens

- print out the final statistics

Dealer results in 1000000 deals UpCard 17 18 19 20 21 Bust BlkJk 1 0.058009 0.143974 0.143987 0.142291 0.065956 0.137050 0.308734 2 0.129509 0.135729 0.129861 0.125192 0.121202 0.358507 0 3 0.126504 0.132416 0.125264 0.122732 0.115489 0.377594 0 4 0.123957 0.126421 0.122380 0.118691 0.114468 0.394082 0 5 0.119597 0.124278 0.119127 0.112777 0.107366 0.416855 0 6 0.115530 0.113878 0.114906 0.110339 0.105096 0.440251 0 7 0.371553 0.135432 0.079290 0.079382 0.074211 0.260132 0 8 0.129021 0.360571 0.128917 0.070656 0.067057 0.243776 0 9 0.120687 0.118726 0.349259 0.119700 0.060798 0.230831 0 10 0.112073 0.111609 0.111833 0.341216 0.034549 0.211309 0.077410

Can you tell by looking at the above chart whether it was made with the dealer staying or hitting on soft 17?

The deck is simulated by a vector of 312 values. Should the initial order of values have an effect on the final results? Does it?

This approach reshuffles the deck at the start of each deal. This means the dealer is always taking cards from an initially full, shuffled deck. What is good or bad about this?

This project suggested using a second parallel vector to handle shuffling a deck. How else could shuffling have been handled? How is one way better than another?

In C++ a bool is an int in disguise. Nevertheless in C++ there is a difference between a vector of ints and a vector of bools. What is the difference? What are the benefits of one over the other? Why do you think a vector of ints was suggested?

The dealer gets a 10-value card as an upcard more often than any other card, so the counts are higher for this upcard. Approximately how much higher? Should we do anything to adjust for this?

How do we know how many hands to try? Was 1 million a good choice? Do your probabilities change if you do 10 million hands instead? You may want to use the -O2 compiler option and try this out.

In many casinos, the dealer actually checks for a blackjack before the player plays the hand. If the dealer has a blackjack, it automatically beats anything a player may have except another blackjack, which ties. What if any consequence does this casino rule have on a player using your statistics to make play decisions?

This project recommended only prompting for a seed value once before dealing all of the hands. Certainly you wouldn't want to prompt the user for a million seed numbers! However, another possibility is that for the Nth deal, the random number generator could be seeded with N. Does this make a difference? What might be good or bad about this? How much time does the seeding process take? How are deals #1 and deals #2 related with this approach? Does it assume more or less "randomness" from the random number generator? Does it assume anything about the seeding process? Would seeding with a different function of N matter?