Project 2 — Blackjack/21

Assigned Tuessday, October 7th
Program Due Sunday, October 19th by 11:59pm
Weight 8%
Updates
  • The following has been updated:
    There was an editing/formatting error in the "Programming the Game" section that caused a sentence fragment to be inserted. That has been fixed, and the grammar improved.

Objectives

To gain experience:

  1. Designing a class-based application
  2. Designing and implementing new complex classes
  3. Writing a class according to a predefined specification
  4. Using provided classes
  5. Working with vectors

Project Policy

This project is considered an OPEN project. Please review the open project policy before beginning your project.

Blackjack/21

You will be developing a program to play the card game Blackjack. This game also goes by the name of "21", for reasons that will become obvious. There is a good description on Wikipedia here..

A quick synopsis: (there are many variations on the game; this is just one.)
The game starts with one or more players coming to the table, along with the dealer, who also plays. Each player starts with a pool of funds, all different. The game is played in multiple rounds.

In each round, you first go around the table in order, with each player placing a bet, up to whatever amount of money they have left. All of the betting is done before any cards are dealt. In our version, a player is allowed to bet $0. Do not worry about the player trying to make a negative bet. The player does not yet give the money to the dealer: she just places it on the table to indicate how much she wants to bet.

The dealer then gets a fresh deck of cards, and shuffles it. (She does this every round.) She deals one card to each player, going around the circle in order. then deals one card to herself. She then deals another card to everyone, including herself, so that everyone has two cards. The order is very important: she should NOT deal two cards to the first player, then two cards to the next, etc.. The players' cards are all dealt face-up. The second card for the dealer, however, is face down, so the players cannot see it.

The play then goes around the table, each player playing to completion before the next player goes. The goal of each player is to get the cards in his or her hand to add up to 21 or less, but higher than the dealer's hand. Numerical cards are worth their face value; face cards (J, Q, K) are all worth 10, and the Ace is special: it can be worth 1 or 11, at the player's discretion. On his turn, a player asks for one card at a time, saying "hit" to request an additional card. When she is satisfied with the value of her hand, she says "stay", and play moves on to the next player. If her hand goes over 21, however, the player "goes bust", meaning she loses immediately--so sad.

After all of the players have had their turn, the dealer plays. The dealer's play is much more constrained: there is no choice or strategy involved. if her hand is 16 or less, she MUST hit; 17 or higher: she MUST stay. It is also possible for the dealer to go bust.

As mentioned before, Aces are special, and can count as 1 or 11, at your discretion. So, if your hand has an Ace and a 5, that is worth either 6 or 16. If you have {A, 5, 6}, you would want to count the Ace as a 1, since counting it as 11 would be a bust. Conversely, if you had {A, 10}, you would "stay", since you have exactly 21, which is the highest hand you can have. In fact, this hand is called "blackjack", and is special. It beats a regular "21", so if you had {A, 10} and the dealer had {10, 5, 6}, you would win. (In some versions, you would win extra money; we are not playing with this rule.)

After all the players and the dealer have done their play, it is then time to see who has won or lost, and settle the bets. Each player is playing against only the dealer: they win or lose depending on whether their hand is higher or lower than the dealer's, according to these rules:

  1. If both the player and the dealer have stayed at a value 21 or below, the higher value wins. Blackjack (21 using only 2 cards) beats other 21's.
  2. If the player and dealer have the same value (including Blackjack against Blackjack), it is a tie.
  3. If you stayed at 21 or below, but the dealer went bust, you win.
  4. If you went bust, you lose, even if the dealer also went bust.

If the dealer wins, the player loses her bet. If the player wins, the dealer pays her an amount equal to her bet (so if she bet $10, she would keep that $10, plus get another $10). In the case of a tie, the player just keeps her bet.

(For those who care: we are not playing with doubling, splitting, insurance, or any other additional complications.)

Programming the Game

You will be creating a class called Blackjack, which creates and manages the game, as well as other classes to help the Blackjack class. We will be providing a complete main() function, in a file called Proj2.cpp, described in more detail below, which will construct a Blackjack object, and invoke its various methods to play through the game. Therefore, our main() will put specific requirements on the public interface for your Blackjack class. In other words, you must implement methods in your Blackjack class to provide what is being called from our main(). We have provided detailed specifications for the expected methods in a header file for your class, Blackjack.h. Note that the provided header file Blackjack.h is incomplete: it only has the "interface" specified, i.e., the prototypes for the public member functions main() might call. In the private section of the class declaration, you must add all the data members your implementation ends up needing to maintain the state of the running game.

You are responsible for the lower-level logic of the game. Mainly, you will be creating the file Blackjack.cpp which will contain the bulk of the logic of the game. You must implement the methods that are being called from main(), i.e., you must write definitions in Blackjack.cpp for all of the methods declared in Blackjack.h Read the detailed function header comments in Blackjack.h carefully to make sure you have implemented everything as specified.

In addition to the Blackjack class, you are required to create a Player class, and a Hand class. The Player will keep track of the information about a single player: their name, their pool of betting funds, their bet on the current game, etc.

The Hand class will manage the cards a single player has been dealt so far, and will provide member functions for printing out the cards in the hand, determining the total value of the cards in the hand, etc.

These will be a relatively straightforward classes, but must be well-designed, with logical accessors, mutators, and facilitators as necessary to reflect good OOP design.

So, you must have at least those three classes: Blackjack, Player, Hand; you are also allowed to add any other classes that you think would be helpful to the design. The use of these classes should be pretty clear from the design and the requirements of the Blackjack class. For example, the Blackjack constructor takes a list of players' names, and later on, printing out the players' stats requires these names, so the Blackjack class must store these somewhere. Given that it must also keep track of winnings, etc., it can either keep those in multiple parallel arrays, OR, it could collect all the information about a given player into the Player class. This Is Better. So, given that we guided/required you to have a Player class, the things that should be in there should be pretty intuitive. Where do you think it would be best to keep track of a player's Hand?

To make your job easier, we are also providing several additional classes: a Card class and a Deck class, with necessary header files with full documentation on their interfaces. This will take care of things like creating a new full deck, shuffling it, and dealing cards from it. For these, we will be providing both header files for you to include (Card.h and Deck.h), as well as full implementations in Card.cpp, Deck.cpp.

You should mostly be referring to the documentation in the Deck.h and Card.h header files, and should not need to look at the implementation code in the .cpp files. There are some things going on in the code in Deck.cpp and Card.cpp that might be confusing. However, you are free to study that code if you so desire.

Provided Code

We are providing the header file for your Blackjack class, Blackjack.h, which declares the public interface functions for this class. You are not allowed to change any of those function declarations. However, you are free to add any data members you need into the private section where we've inserted "ADD YOUR DATA MEMBERS HERE" as a comment. Most of your work will go into creating the actual implementation in Blackjack.cpp

Also provided are Card.h and Deck.h, which define the interfaces for the Card and Deck classes, as well as the actual method definitions in Card.cpp and Deck.cpp, which you will be using in your Blackjack class implementation,

Example Game Play

The program is run with a command-line argument specifying how many people will be playing, and what their names are. Note that it is the provided main() that takes care of command line parsing, so you do not have to worry about this. (Our assumption is that you are all masters of command line parsing from the first project and the labs, and would be insulted if we hit you with this mundane task again :-) Note that later projects will involve much more complex command lines, which you will again have to handle.)`
% ./Proj2.out Joe 100 Sally 200
Welcome to CMSC 202 Blackjack!
Round 1:
How much does Joe bet? 10

How much does Sally bet? 20

The players' hands:
Joe: Ace of Diamonds, 10 of Clubs
Sally: 2 of Hearts, 4 of Clubs
Dealer: Ace of Spades, [hidden card]

>>Joe's turn:
Hand: Ace of Diamonds, 10 of Clubs
Joe's play: hit

7 of Hearts
Hand: Ace of Diamonds, 10 of Clubs, 7 of Hearts
Joe's play: hit

4 of Spades
Busted!

>>Sally's turn:
Hand: 2 of Hearts, 4 of Clubs
Sally's play: hit

9 of Hearts
Hand: 2 of Hearts, 4 of Clubs, 9 of Hearts
Sally's play: stay

Dealer's turn:
Hand: Ace of Spades, 7 of Spades
Dealer's play: stay

Dealer has 18
Joe has busted--Dealer wins
Sally has 15--Dealer wins

Joe now has $90
Sally now has $180

Another round? no

Goodbye!
%

[The game continues...]

Your Game Logic

How to Test Your Project

You should throughly test your program for all typical, edge, and error cases. The main example above does some of this. You should run it enough times that you've tested games where the dealer get blackjack, other games where one of the players getting blackjack, and some games where various players go bust, including the dealer. We will provide more test scenarios later on.

Project Hints

Some clarifications and hints to help you with the project:

Additional Requirements

We will be covering the vector class in-class (no pun intended). To show that you know how to use it (and because it is the best thing to use), we are requiring that you use the vector class for storing the set of Player objects for a Blackjack, and the st of Card objects for a Hand.

The rest of the design is left open.

Grading

See the course website for a description of how your project will be graded.

We will be automating much of the grading for this project. It is absolutely essential that you do not modify any of the files that we provided to you {Proj1.h, Proj1.cpp, Card.h, Card.cpp, Deck.h, Deck.cpp}, You should not even submit these files. If you do inadvertantly submit your copies of these files, we will be replacing them with our own versions before trying to compile and run your program.

The one exception is the file Blackjack.h, which we are providing a skeleton for, but which you will be adding private data members to. However, even with this file, you must not modify any of the function declarations! If you do, there is a good chance you will lose many, if not most, of the points for this project.

Another requirement is that your executable, as produced by your Makefile, is called Proj2.out; adjust your Makefile accordingly.

Project Submission

Before submitting your project, be sure to compile and test your code on the GL system. See the Project Compilation section of the course Projects page for details on how to compile and execute your project on GL.

Assuming you’ve used the specified file names, submit your project by typing the command

submit cs202 proj2 [all of your various .h and .cpp files] Makefile

See the Project Submission page for detailed instructions. Note that we require you to submit the Makefile, also. We will in fact be using your own Makefile to build your program, so it must work properly.

You may resubmit your files as often as you like, but only the last submittal will be graded and will be used to determine if your project is late. Also note that if you rename or remove certain files, the old versions that you submitted earlier will stay in the submit directory unless you use "submitrm" to clean them out, which you should. At the end, a "submitls" should show exactly those files that are part of your project: no more, no less. For more information, see the Projects page on the course web site.

Remember — if you make any change to your program, no matter how insignificant it may seem, you should recompile and retest your program before submitting it. Even the smallest typo can cause errors and a reduction in your grade.