Executive Summary

This assignment is due by classtime on April 1.

You will implement a fully functioning game of Blackjack. No prior knowledge of the game is needed. However, you will need to know what cards appear in a standard deck of playing cards. See your instructor if you have any questions on that account.

Blackjack (also called "21") is basically a game between an individual player and a dealer. There's a gambling side to the game that this project does not address. The project simply plays the game with the user as "Player" and program as "Dealer", and determines the winner and loser.

Honor: The course policy and the instructions it references, most pertinently COMPSCIDEPTINST 1531.1C, spell out what kinds of assistance are permissable for programming projects. The instructor can give explicit permission for things that would otherwise not be allowed. For this project, you have explicit permission

  1. to get help from another current SI204 instructor as well as your own (any assistance must be documented though),
  2. to get help from current SI204 MGSP leaders, and
  3. to use general purpose C++ resources online (though such use must be documented). Resources that might specifically address this project, code that implements blackjack or other card games, are not allowed. You are very specifically not allowed to look at previous semesters' IC210 or SI204 programming projects that may have addressed similar issues.

Combining the instructions referenced in the course policy and the explicit permissions above, and what you get is summarized as:

Note: This assignment has lots and lots of room for creativity in how you write your program. However, it has NO room for creativity in your program output. The input and output should match the examples exactly.

Part 1 [Up to 30pts] - Name your source code file part1.cpp

A part 1 solution will create, shuffle, and print out a deck of cards. A correct solution must store the integer representations of the 52 cards in an array, and only after that print the output. Otherwise its use in working towards the remaining steps of the project is limited.

Your program will start by asking the user if he or she would like to seed the random number generator (RNG). Please follow the following format exactly:

~$ ./p1
Would you like to seed the random number generator? y
Please enter an integer as a seed: 10

If in response to the first question, the user enters 'n', the RNG should be seeded with time(0), as in our labs. This should be the only time you seed the RNG in your program.

You will then create an array containing the integers 0-51 - these integers will represent the 52 cards in the deck. Integers can be turned into cards, and vice-versa, using the following rules: The value is calculated by taking the integer and modding by 13 and adding 1. This gives you a number betwen 1 and 13, inclusive. 1 is Ace, 2-10 are 2-10, 11 is J, 12 is Q, and 13 is K. The suit is calculated by taking the integer and integer-dividing by 13. 0 is ♣, 1 is ♦, 2 is ♥, and 3 is ♠. So, your array of integers represents a deck of cards ranging from the Ace of Clubs (integer 0) to the King of Spades (integer 51).

In order to print cards, you'll need to be able to turn the card's integer into a string. Fortunately, C++ and our Unix terminal program understand "UTF-8", or "unicode" character encodings, which allow us to store all sorts of symbols beyond your standard ASCII set. However, a char is no longer sufficient, so unicode requires us to use strings. The use of unicode means we can print card suit symbols to the screen. Here are the suits and the corresponding string for printing them in unicode: ♣ ← "\u2663", ♦ ← "\u2666", ♥ ← "\u2665", ♠ ← "\u2660". So, before shuffling, we can print out each card in the deck and have it look like this:

A♣ 2♣ 3♣ 4♣ 5♣ 6♣ 7♣ 8♣ 9♣ 10♣ J♣ Q♣ K♣ A♦ 2♦ 3♦ 4♦ 5♦ 6♦ 7♦ 8♦ 9♦ 10♦ J♦ Q♦ K♦ A♥ 2♥ 3♥ 4♥ 5♥ 6♥ 7♥ 8♥ 9♥ 10♥ J♥ Q♥ K♥ A♠ 2♠ 3♠ 4♠ 5♠ 6♠ 7♠ 8♠ 9♠ 10♠ J♠ Q♠ K♠

The next step is shuffling - to shuffle once, you'll select two numbers between 0 and 51 inclusive using rand()%52, and swap the cards at those two indices in your deck. A full shuffle performs this 10,000 times. If you seed your RNG with the integer 0, you will get the following shuffled deck:

4♠ K♠ K♦ A♦ 10♦ 4♣ A♠ J♠ 4♦ 5♠ Q♥ Q♦ A♣ 9♠ 6♥ 3♦ J♥ K♥ 9♣ 10♣ 2♥ 7♥ 9♥ 8♥ J♦ K♣ 7♦ 5♦ 9♦ 3♣ 5♥ Q♠ 6♣ 3♥ 5♣ 6♠ 2♣ 2♠ 2♦ 10♠ 4♥ 7♠ 6♦ Q♣ 3♠ 10♥ 7♣ 8♠ 8♣ 8♦ A♥ J♣

A complete Part 1 solution creates, shuffles, and prints a deck in exactly this format. Below are some example runs:

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 0
4♠ K♠ K♦ A♦ 10♦ 4♣ A♠ J♠ 4♦ 5♠ Q♥ Q♦ A♣ 9♠ 6♥ 3♦ J♥ K♥ 9♣ 10♣ 2♥ 7♥ 9♥ 8♥ J♦ K♣ 7♦ 5♦ 9♦ 3♣ 5♥ Q♠ 6♣ 3♥ 5♣ 6♠ 2♣ 2♠ 2♦ 10♠ 4♥ 7♠ 6♦ Q♣ 3♠ 10♥ 7♣ 8♠ 8♣ 8♦ A♥ J♣

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 10
A♥ 7♥ Q♠ 10♣ J♠ A♦ 3♠ J♥ 8♥ 6♣ 5♣ Q♥ 9♥ 5♥ 7♠ 9♣ J♣ 2♠ 4♥ Q♣ 8♠ 3♦ 6♥ 2♣ 3♥ K♠ K♣ 8♦ A♣ 4♠ 7♦ K♦ J♦ 6♠ K♥ 6♦ 7♣ 9♠ 2♦ 8♣ 3♣ 10♠ 10♦ 9♦ 5♦ Q♦ 10♥ 4♦ A♠ 4♣ 2♥ 5♠

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? n
4♦ 3♦ 9♦ Q♥ 7♥ J♦ 6♠ J♠ 9♥ 6♦ 2♦ 5♦ Q♠ A♣ 5♥ 2♠ 10♠ 6♣ K♣ 2♥ 8♥ 3♥ 6♥ 2♣ 7♣ 8♦ J♣ K♠ 7♦ 9♣ 10♣ 3♣ 10♦ Q♦ A♦ A♥ 7♠ 5♠ 10♥ K♥ 9♠ K♦ 8♠ 4♣ A♠ 3♠ 8♣ 5♣ J♥ 4♥ Q♣ 4♠

This last example, of course, will give you a different deck every time.

Part 2 [Up to 50pts] - Name your source code file part2.cpp

A correct part 2 solution will simulate dealing cards to a "Player" and a "Dealer" in the following order: deal two cards to "Player", then deal two cards to "Dealer", then display (as shown below). Then three rounds of dealing first one card to "Player", then one card to "Dealer", then displaying the hands (once again as shown below). Note that the "top" of the deck is the first card from the deck array (index 0), and you must deal from the top of the deck (in the Old West, people got shot for violating this rule!). Thus, your program's output really must match what is shown below for the given examples. Note that the RNG seed (and so, the shuffled decks) being used are the ones illustrated in part 1. Notice how 10s are displayed in comparison to the 1-digit card values - your output should match this exactly.

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 0
 Player Dealer
|  4♠  |  K♦  |
|  K♠  |  A♦  |
 Player Dealer
|  4♠  |  K♦  |
|  K♠  |  A♦  |
| 10♦  |  4♣  |
 Player Dealer
|  4♠  |  K♦  |
|  K♠  |  A♦  |
| 10♦  |  4♣  |
|  A♠  |  J♠  |
 Player Dealer
|  4♠  |  K♦  |
|  K♠  |  A♦  |
| 10♦  |  4♣  |
|  A♠  |  J♠  |
|  4♦  |  5♠  |

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 10
 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
|  3♠  |  J♥  |
 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
|  3♠  |  J♥  |
|  8♥  |  6♣  |

Again, if the user does not seed the RNG, the result will be different every time.

Note: You really want to have your program simulate dealing a card to a hand. You should be able to point to few variables and say "those represent the player's hand," and point to a few more and say "those represent the dealer's hand."

Part 3 [Up to 70pts] - Name your source code file part3.cpp

A correct part 3 solution will start to play something that actually looks like a game. Player and Dealer will both be dealt two cards (as in part 2). But then the program will proceed to ask the Player and Dealer in turns whether they want to "hit" (in which case they get dealt another card into their hand), or to "stand" in which case their hand stays the same. The player goes first, and the program should go through three rounds (i.e. the Player and the Dealer both get three turns). Below is an example of how a game might play out. Your output and the way you get input from the user must match what's shown here.

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 10

 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
Round 1 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |      |
Round 1 Dealer's turn
hit or stand? [h/s] h


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
Round 2 Player's turn
hit or stand? [h/s] s


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
Round 2 Dealer's turn
hit or stand? [h/s] h


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
|      |  3♠  |
Round 3 Player's turn
hit or stand? [h/s] s


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
|      |  3♠  |
Round 3 Dealer's turn
hit or stand? [h/s] h


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |  A♦  |
|      |  3♠  |
|      |  J♥  |

Part 4 [Up to 85pts] - Name your source code file part4.cpp

A correct part 4 solution should behave exactly like a correct part 3 solution, except that in each round the current "best scores" for both Player and Dealer hands should be shown. The "best score" for a hand is computed according to the following rules. Add up points for each card in the hand, where aces are worth one point, kings, queens and jacks are worth 10 points, and numbered cards (i.e. 2 though 10) are worth their number in points. Call this number total. If the hand has no aces, total is the "best score" for the hand. If there are aces in the hand, and total + 10 is not greater than 21, the "best score" is total + 10. Otherwise, "best score" is simply total.

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 10

 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
Player 18, Dealer 20
Round 1 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |      |
Player 18, Dealer 20
Round 1 Dealer's turn
hit or stand? [h/s] s


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |      |
Player 18, Dealer 20
Round 2 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |      |
|  A♦  |      |
Player 19, Dealer 20
Round 2 Dealer's turn
hit or stand? [h/s] s


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |      |
|  A♦  |      |
Player 19, Dealer 20
Round 3 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |      |
|  A♦  |      |
|  3♠  |      |
Player 22, Dealer 20
Round 3 Dealer's turn
hit or stand? [h/s] s


 Player Dealer
|  A♥  |  Q♠  |
|  7♥  | 10♣  |
|  J♠  |      |
|  A♦  |      |
|  3♠  |      |
Player 22, Dealer 20

Part 5 [Up to 95pts] - Name your source code file part5.cpp

A part 5 solution functions just like a part 4 solution with the following two exceptions:

Example runs:

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 6

 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
Player 12, Dealer 15
Round 1 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
|  J♠  |      |
Player 12, Dealer 15
Round 1 Dealer's turn
hit or stand? [h/s] h


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
Player 12, Dealer 17
Round 2 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
|  8♥  |      |
Player 20, Dealer 17
Round 2 Dealer's turn
hit or stand? [h/s] s


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
|  8♥  |      |
Player 20, Dealer 17
Round 3 Player's turn
hit or stand? [h/s] s


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
|  8♥  |      |
Player 20, Dealer 17

Note: The game stopped because of consecutive "stand" moves.

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 6

 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
Player 12, Dealer 15
Round 1 Player's turn
hit or stand? [h/s] s


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
Player 12, Dealer 15
Round 1 Dealer's turn
hit or stand? [h/s] h


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
|      |  J♠  |
Player 12, Dealer 25

Note: The game stops because the Dealer "busts."

Part 6 [Up to 100pts] - Name your source code file part6.cpp

A part 6 solution functions like a part 5 solution with the following modifications:

Sample run:

taylor@kurt:~/zee/temp/proj2$ ./a.out 
Would you like to seed the random number generator? y
Please enter an integer as a seed: 6

 Player Dealer
|  A♣  |  **  |
|  A♦  |  J♦  |
Round 1 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♣  |  **  |
|  A♦  |  J♦  |
|  J♠  |      |
Round 1 Dealer's turn
hit or stand? [h/s] h


 Player Dealer
|  A♣  |  **  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
Round 2 Player's turn
hit or stand? [h/s] h


 Player Dealer
|  A♣  |  **  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
|  8♥  |      |
Round 2 Dealer's turn
hit or stand? [h/s] s


 Player Dealer
|  A♣  |  **  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
|  8♥  |      |
Round 3 Player's turn
hit or stand? [h/s] s


 Player Dealer
|  A♣  |  5♣  |
|  A♦  |  J♦  |
|  J♠  |  2♠  |
|  8♥  |      |
Player 20, Dealer 17
Player wins

Extra Credit [Up to 110pts] - Name your source code file partX.cpp

The extra credit solution will not even be considered unless the Part 7 Full credit solution functions completely correctly.

Your extra credit solution should play the game over and over again. Each time the player finishes a game, the program should ask whether the player wants to play again or quit. Each play the player must make a 5 dollar bet. If the player wins, the player gets the bet plus some amount of winnings back. You may decide what the payouts are (could be as simple as getting your bet plus 5 dollars back). You must report the players winnings / losses at the end of each round. The player must have the option of withdrawing from a game (not the table, just that game) after the initial two cards are dealt to player and dealer, but before any other play has taken place. Withdrawing means half the bet is returned to the player, but the other half goes to the house.


What to submit

You will all files leading up to your furthest properly functioning solution. So, if your Part 6 solution works, submit parts 1-6. If you don't have a properly functioning Part 6 solution, but your Part 5 solution works fine, submit parts 1-5 solution only (no half-working code). And so on. Note that what you submit must work, and absolutely must compile!

How to submit

If in Dr. Chambers' section, submit with submit proj02 part*.cpp

Your code must pass the online submission tests for full credit.

If in Dr. Taylor's section, submit with submit proj02

How projects are graded / how to maximize your points

Things to keep in mind to receive full marks:

  1. Submit all required items (as described above) on time.
  2. Make sure the form of your output matches the form of the example output in all ways. Of course the cards you see and decisions dealer and player make will vary from the examples you see.
  3. Make sure you follow the SI204 Style Guide. This means proper indentation, use of whitespace within lines of code, logical organization of chunks of code,
  4. Make sure you do a good job of putting things in functions. One monolithic main function is not OK, even if it works! The quality of your overall design will play a role, and a large part of that boils down to using functions well.