Lab 2

due: Monday February 24 (submit on Gradescope here).

Goals:

In this lab, we will complete a few methods in order to create a card game. The gameplay (in CardGame.java) is already implemented for you, but some of the Card and Deck methods need to be implemented. There are three files you will need to get started (download here), but you only need to submit two of these files to Gradescope (Card.java and Deck.java). As usual, please download the template, move it to your cs201 folder and then open the lab2 folder in VS Code.


The card game is played as follows:

User input is requested using a Scanner object. You don't need to modify anything about this part of the code (in CardGame.java), but it's good to know about. The scanner can be created and used as follows:

Scanner scanner = new Scanner(System.in); // we will scan for input in the terminal

int i = scanner.nextInt(); // get the next input as an integer
String s = scanner.next(); // get the next input as a String

scanner.close();

For more information about the Scanner, please see Oracle's documentation.

Part 1: Complete the Card class definition (in Card.java).

First, note that a playing card has a suit (a String) and a value (an int between 1 and 13). The Card class is defined to store these two fields when a Card object is constructed.

When we create our own custom classes, it often helps to implement a special toString() method in these classes. This is the method that gets called when Java prints our objects (see here for more info).

Before implementing the Card toString() method, start by implementing the getValueName() method in Card.java. This method will return a String representation of the card value. For example, if the value is 2, you should return "2". If the value is 12, you should return "Queen". See the documentation above the getValueName() method for further details about what should be returned. For values between 2 and 10, you can use the Integer.toString method.

Next, you should complete the toString() method in Card.java. This should print something like "3 of Hearts" or "Jack of Clubs". Hint: combine the result of the getValueName() method as well as the suit field with the word "of". Click the Run Java button (at the top of Card.java) as we have been doing to test your code and make sure the example cards are printed correctly.

Part 2: Complete the Deck class definition (in Deck.java).

There are 52 cards in a deck: 4 suits, and each suit can have values between 1 (Ace) and 13 (King). The Deck class stores an array of Card objects called cards. In the Deck constructor, please create and fill this cards array with all 52 cards.

Next, we need to implement the draw method for the Deck class. Instead of actually removing a Card from our cards array, we will just keep track of the index of the current card in the deck. This index is called position (another field of the Deck class) and starts at 0. Whenever a card is drawn (by calling the draw() method), we return the current Card object at the position index, while also incrementing position so that we can get the next card during the next call to draw().

The picture below might help visualize this. The first time we call draw(), the 2 of Diamonds should be returned because it's at position 0. But position also needs to be incremented so that we can return the 4 of Clubs upon the next call to draw().

When the position reaches the end of the deck (i.e. has a value beyond an allowable index in cards), then there are no cards left. Please complete the empty() method which will return true if position is at the end of the deck, and false otherwise.

Part 3: Finish and play the game!

To finish the game, we need to go back to the Card.java file and implement the compareTo method. This method should compare the current Card object with some otherCard. Here, we don't need the suit of the cards for the comparison: we just want to compare the value. If the card value is < the other card value, return -1. If the card value is > the other card value, return 1. Otherwise, the card values are the same and return 0. You can test your code in the PSVM defined in Card.java.

Please note that this game is inspired from the High-Low card game. In our game, we will treat an Ace as having the lowest value (1).

If everything seems to work, run CardGame.java and try to play!

Submission

Submit Card.java and Deck.java to Gradescope (here). Gradescope will then run some tests on your code, specifically on Card.getValueName, Card.toString, Card.compareTo, Deck (constructor), Deck.draw and Deck.empty. The test names have been labelled so you have an idea of what kind of inputs are being used to test your code (and you can submit as many times as necessary).