CS140 -- Lab 4 (Spring 2021)


Inspiration

Blackjack is a simple and popular card game. A player competes with a dealer with the goal of coming as close to 21 as possible without going over. Players that exceed 21 lose; if the final value is less than 21, the dealer takes cards up until 17 or higher. If the player’s value is higher, they win; otherwise they lose.

This is designed to reinforce C++ class design, dynamic memory allocation, passing by reference vs. value, and random number generation as also inclided in the challenge this week.

Part 1: a CardDeck class

  1. Develop a C++ class named CardDeck that stores a deck of cards as an array of n integers (to practice data hiding) and a corresponding "size" variable stored as a private data member in your new class.
  2. The non-default constructor should receive a value n and then place the integers from 0 to n - 1 into the array.
  3. Please specify a "fall back" value for this non-default constructor so n is assumed to be 52 (aka CardDeck(int = 52); as a prototype)
  4. Write a public member function getSize() that returns the size of the current deck using the size variable explained above.
  5. Provide a utility function named shuffle that performs a shuffle. You can either implement this yourself or use a temporary vector and the the random_shuffle algorithm of the STL (as covered in this week's challenge). Note that srand() must be called to change the random number seed for the shuffle. For now, we recommend you simply place this srand() call in the non-default constructor.
  6. Aim to have a simple client/test program done by the end of the lab period that initializes an array of ten cards (i.e., n = 10), and prints the deck before and after a shuffle.

Part 2: Practicing dynamic memory allocation

Change the implementation completed in lab to use dynamic memory allocation (new/delete). As discussed in the video/lecture this week, in addition to the constructor you need the following functions:

  1. Deconstructor
  2. Copy constructor
  3. Assignment operator

NOTE: Depending on how you chose to implement Part 3, you may not ** need ** a copy constructor or an assignment operator. In other words, you will have no segfaults/memory leaks since you will not invoke either because, for example, you never pass a card deck by value or set one card deck equal to another card deck.

That said, to receive full credit for this assignment you must include all three, especially since I have provided a highly similar class (array) for the lecture notes for 2/18 that can you are welcome to cite and use as inspiration.

Part 3: Developing a simple card game

Implement a simple BlackJack player using CardDeck as a foundation as follows: Also, when there are fewer than 15 cards, open a "new" deck and shuffle it before continuing the game. HINTs: You can use the modulus (%) operator to convert cards from 0-51 to 0-12, and you can use new/delete to ensure a constructor runs or a deconstructor runs for your decks.

Totally optional coding challenge

In a historical Dr. Plank style 140/302 students would be asked to complete TopCoder challenges to further hone their coding skills, after which a TA would provide their solution on a high level (no actual code usually). There was also typically no formal assessment, i.e., no actual grade... however, they were opporunties for students who wanted more practice and/or experience to do more than the "main" assignment.

In that spirit, I will provide this optional coding challenge of implementing one of my favorite card games as a child that I played with my Pop Pop (the common nickname for grandfathers in the Philadelphia area), which he learned as a very young boy growing up in southwest Germany as "Tod und Leben" and, I believe, as a soldier in the U.S. army having fougnt in WWII about a decade after he immigrated as a child to south Philly.

Code up a client for this children's game known as "War" (among other names). First, a 52-card deck is shuffled and divvied evenly between players. Next, each person places a single card for the other to see. Whoever has the highest card wins both cards. If there is a tie, "war" takes place; each player places 3 cards face down and one card face up. The highest showing card takes the combined pile. The "war" procedure is repeated until one player runs out of cards. This implies that if a war is declared and one of the players does not have 3 cards, they lose. Finally, aces can be either high or low depending on personal preference in your implementation.

Rubric

Part 1: 16 points

+4 Basic program structure is correct
- program commented well (2 pts)
- proper .h and .cpp files for CardDeck (2 pts)
+4 non-default constructor works as requested with a fall back value
+4 member functions are correct (2 pts each)
- getSize()
- shuffle()
+2 calls srand to seed the rand random number generator as requested
+1 client prints cards pre-shuffle
+1 client prints cards after shuffle

 
Part 2: 10 points

 
+2. Functional and working deconstructor that calls delete properly
+4  Functional and working copy constructor that works if/when you pass 
by value to a procedure
+4  Functional and working assignment operator that works when you set 
one CardDeck to another, e.g., CardDeck a; CardDeck b = a;
 
Although we will review your code and these should be relatively 
straightforward, we highly recommend that you use them as described 
to remove any bugs prior to submission (even though its ** very ** 
similar to the code provided on 2/18)

Part 3: 12 points

+1 Aces are always 11
+2 User of the client is provided with a clear hit/stand option
+4 The Blackjack game works as it should.  Refer to 
https://en.wikipedia.org/wiki/Blackjack for details.  In short:

Player always goes first. If they go over 21, they bust and the dealer 
wins no matter what Dealer must “hit” until they reach 17 or higher. If 
the dealer goes over 21, and the user doesn’t, the player wins
Otherwise, whoever has the higher number wins. For purposes of this lab 
you can chose to either track ties or assign any tie to the user, aka, 
user wins
+2 correctly keeps track of how many times a player wins and the dealer 
wins in your game
+1 asks if a user wants to continue after every game
+2 when there are fewer than 15 cards, open a "new" deck and shuffle 
it before continuing the game

Testing your code prior to submission

To faciliate testing, you were previously asked to clone the course Github repository as follows:

git clone https://github.com/semrich/CS140-21.git cs140

For this assignment, update this clone by using the following:

git pull

We'll discuss this in class but note that your client must be named "main.cpp" and compilable using make. Unlike other assignments this term, you will get more credit for the structure of your code and following instructions versus solving unit tests. Please refer to the final rubric for details.


Submission

Having done a trial run on Lab 0/Challenge 1, and on Lab 1 (see Tom's comments on Piazza) we think it would be easiest for everyone to create a single .tar for this assignment. The command to do so is:

tar -cvf lab4.tar CardDeck.h CardDeck.cpp main.cpp
Because this assignment is more focused on C++ syntax/class design vs. solving specific problems, and since we checked for a very similar win condition in Lab 1, most of the to-be posted rubric will be on specific syntax/code items vs. solving scripts in advance.

Note: Although submission will be faciliated by Canvas, we will compile and test on EECS lab machines!

If you develop your solution elsewhere please make sure it works on the lab computers prior to the deadline.