Project 2 — Blackjack/21

Assigned Tuessday, March 11th
Program Due Sunday, March 23rd by 11:59pm
Weight 8%
Updates
  • THE PROVIDED SOURCE FILES HAVE BEEN UPDATED:
    You should go to the "Provided Code" section below and re-download.

    The header files (Blackjack.h, Deck.h, and Card.h) have significantly more detailed comments. However, none of the actual C++ code in them has changed, so your code should not be affected. Read the more detailed function descriptions carefully to make sure you have implemented everything as specified.
    The code in Proj2.cpp has been upgraded: the calls to your Blackjack member functions were all correct in the earlier version, but some of the actual game-playing logic was broken; the new version should work much better.
    Also, main() now prints out a "Round #" each round. This was added to help us grade your output. Again, your code is not affected at all by this. The sample output has been adjusted accordingly.

  • Additional source files have been added to the "Provided Code" section:
    We were originally planning to only provide precompiled object file versions of the Deck and Card class implementations (Deck.o, Card.o), but there are some students who are developing the software locally on their own machines, and the object files would not be compatible with the C++ compilers under Windows or MacOS. So, we are releasing the source files. You should mostly be working from the documentation in the Deck.h and Card.h header 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.
  • A new section called "Project Hints" has been added to this document. Definitely worth looking at.

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.

Project Analysis

Time permitting, code from this project will be reviewed in class as noted on the schedule as “Project 1 Analysis.” If you would like your code to be reviewed in class, please contact your instructor. Your name will be held in strict confidence. This practice has worked extremely well in the past. It is a wonderful way to compare and contrast the different designs that people have used.

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. Each player starts with a pool of funds, all different. The game is played in multiple rounds. In each round, the players first place bets, up to whatever amount of money they have left. This is done before any cards are dealt. The dealer starts each round with a fresh deck of cards, and shuffles it. She deals two cards to each player, going around the circle dealing one card at a time, including to herself. So, she goes around the table twice. The players' cards are 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 more 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 a new card. When she is satisfied with her hand, she says "stay", and play moves on to the next player. If the hand goes over 21, the player "goes bust", meaning they lose immediately--so sad.

After every player has had their turn, the dealer plays. The dealer's play is much like the other players', but there is no choice: if her hand is 16 or less, she must hit; 17 or higher: she must stay. The dealer can also "go bust", in which case any remaining player automatically wins. Note, however, that any player that has already gone bust loses! If the dealer has stopped at a value between 17 and 21, each remaining player's hand is compared against the dealer's to see who wins and who loses their bets, as specified below.

As mentioned before, Aces are special: 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.)

Note that each player is playing against only the dealer: how their hand compares to other players' is irrelevant. If the dealer has a higher total than you (without going bust), you lose your bet. If you beat the dealer, you win an extra amount equal to your bet (so if you bet $10, you would get back the $10, plus another $10). In the case of a tie, you you just take back your bet. This is called a "push".

(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. We have provided this specification in a header file for your class, which you must now implement. 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.

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 (Card.cpp, Deck.cpp, although we might end up hiding the implementation details by providing precompiled object files Card.o and Deck.o)

You are responsible for the rest of the game. 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.

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?

Provided Code

The following is the header file for your Blackjack class, 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.

Also provided are Card.h and Deck.h, which define the interfaces for those classes, which you will use within your Blackjack class implementation.

(Note: these files were updated on 3/16--see notes at top)

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 (NEW)

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.