CMPU 125 - Assignment 5
Implementing the Go Fish game - Part 1
Assigned: Monday, Oct. 20
Due: Friday, Oct. 31

In this assignment you will:

  1. define a class to represent each playing card in a standard deck of cards (minus the jokers),
  2. define and implement a Deck class which is a linked list of Card objects, and
  3. define a class that extends the generic ArrayList class to represent a hand in the game of Go Fish.

Summary: 

The Card data type is like the Node class we discussed in lecture. The Deck class is a linked list (but not of the built-in LinkedList type) of Card objects. The GoFishHand class is an ArrayList of Card type which will represent players hands in a game of Go Fish.


Implementation Details

I.  Class Card:

You should begin by implementing this class, in file Card.java.  Objects of this class have three instance variables:  rank and suit, which are integers, and next, which will contain a reference to a Card object.

You should define a public named constant for each of the suits: SPADES, HEARTS, DIAMONDS, and CLUBS.  You should also have a public named constant integer defined for each Card object that is not referred to by a number, e.g., Ace of diamonds or King of spades: ACE, JACK, QUEEN, KING.

Methods in Class Card:

  1. The Card class should contain a 2-parameter constructor that initializes the rank and suit of a Card and sets the next field to null.
     
  2. You should define getter methods for all three instance variables and a setter method for the next field (you will need this setter method to create the linked list of Cards and to traverse all the Cards in a Deck). After a Card object is created, a client should only be able to change the next field.
     
  3. Define an equals method that overrides the Object class equals method (look up the definition line in the Java API by locating the description of the equals method in the Object class). You should be sure that the Object passed as a parameter to the equals method is not null and use the getClass() function of the Object class to make sure the receiver and the parameter have the same type before comparing the instance variables of the Card objects. Also, since the parameter to this method is type Object, you will need to cast the parameter as a Card before comparing its fields to the receiver. For this assignment, you should make sure all fields of a Card are checked for equality (because this method will be used by the containsDuplicates method, described below.)
     
  4. Define a toString() method that overrides the Object toString() method. This method should return a String consisting of a single letter or digit for the Card rank concated with a single lowercase letter for the suit. For example, if the card is the Ace of clubs, the toString method for that Card should return the String "Ac"; if the card is the 10 of diamonds, the toString method for that Card should return the String "Td"; if the card is the 2 of spades, the toString method for that Card should return the String "2s". Hopefully, you get the idea.

After you have defined the Card class, you'll define a class to represent a list of Cards that has 52 cards in it...in other words, a Deck of Cards.

II. Class Deck:

Next implement a class to represent a Deck of Cards, in a file called Deck.java. In this class you should have 3 instance variables: a reference to the first Card in the Deck, an integer representing the size of the Deck, and a RandomGenerator whose use will be explained later. You should also define a named constant to hold the maximum number of cards in a full joker-less Deck.  

Methods in class Deck:

  1. The zero-parameter constructor for this class should create a 52 card deck that has 13 cards per suit and 4 suits. You can create the Cards in any order (possibly in a nested for-loop?). Remember those public named constants you defined for the Card class?  Use them in this constructor. Your constructor should delegate the jobs of maintaining the pointer to the first card in the Deck and incrementing the size of the Deck to a method called addToEnd, described below.  
     
  2. The addToEnd method should take two integer parameters, representing the rank and suit of each card object. It should create a new Card object and add it as the last Card in the Deck, while maintaining the reference to the first card in the Deck (and thereby the entire Deck) and keeping track of the current size of the Deck (making sure the size does not exceed the maximum possible for a standard Deck.) The last Card in the Deck, i.e., the Card just added, should have null as the value of its next field.
     
  3. Add a getter method for the size variable.
     
  4. A get method should take as an input parameter a valid index of a Card in the Deck, returning a reference to the Card object at the given index.
     
  5. A void remove method should take as an input parameter a valid index of a Card in the Deck. The result of this method will be that the Deck no longer contains the Card at the given index.
     
  6. A void insert method should take as input parameters: two integers representing the rank and suit of the card to be inserted, and an integer representing the index where the card should be inserted. The index should be assumed to be a valid index in the current Deck (keeping in mind that the new Card could be inserted at the beginning, middle, or end of the Deck.) The method should create a new Card with the given rank and suit and, when it returns, the Deck should have increased its size by one Card.
      
  7. A deal method should remove and return the top card from the Deck, decrementing the Deck size and resetting the reference to the front of the Deck appropriately.
     
  8. This is the challenging part of the assignment:  Add a shuffle method that works on the receiving Deck, randomly permuting the position of each Card in the Deck and producing the equivalent of a randomly "shuffled" deck of Cards. This is the method in which you should use the RandomGenerator. One suggestion for accomplishing the shuffle is to use a private swap method that takes two valid indexes in a Deck and swaps the Cards at those index positions. The swap method can make use of the remove and insert methods you defined in steps 5 and 6.
     
  9. Create a containsDuplicates method that returns true if the Deck contains duplicate Cards and false otherwise.

  10.  Finally, create a toString method that traverses the entire Deck, returning the concatenation of the String representations of all the Cards in a single String.
     

III. Class GoFishHand:

This class will represent a 7-card hand of the child's game "Go Fish". The GoFishHand class should extend the ArrayList<Card> class and should import java.util.*.  This class should contain:

More methods will be added to this class in Assignment 6.


IV. Class TestDesk:

As the final part of this assignment, create a class called TestDeck that has a main method. Use the TestDeck main method to
  1. create a new Deck of Cards,

  2. print the original Deck (using System.out.println's is fine, there is no need to use the ConsoleProgram for this assignment),
     
  3. print the size of the Deck and report whether the Deck contains any duplicate cards,

  4. shuffle the Deck, 
     
  5. print the Deck after shuffling and report whether the Deck contains any duplicate cards,
     
  6. declare two new GoFishHand objects and deal 7 cards to each hand from the Deck,

  7. print the hands (note: you can do this easily by passing the hand as input to System.out.println because the ArrayList has a toString method), and

  8. print the size of the Deck after dealing.

Sample Output

Running the TestDeck will produce the following output in the interactions pane (blue text is produced by pressing the Run button):

> java TestDeck
Deck before shuffling:
As 2s 3s 4s 5s 6s 7s 8s 9s Ts Js Qs Ks Ah 2h 3h 4h 5h 6h 7h 8h 9h Th Jh Qh Kh Ad 2d 3d 4d 5d 6d 7d 8d 9d Td Jd Qd Kd Ac 2c 3c 4c 5c 6c 7c 8c 9c Tc Jc Qc Kc
Size of Deck is 52
There are not duplicate cards in the deck

Deck after shuffling:
4s As 2c 3h Qd 6d Ad Jh Kc 3d Ks 7h 2d 2s Th 4c 4d 9h 8c Ac 9c 6c 8h Qh 7c 5d Qc Ts Tc 5c 8d 7s 5s Kd 6h Ah Td 6s 3s Jd 8s Jc 3c 9d Kh Qs 9s Js 4h 2h 5h 7d
Size of Deck is 52
There are not duplicate cards in the deck

Dealing hands:
Contents of hand 1:
[4s, 2c, Qd, Ad, Kc, Ks, 2d]

Contents of hand 2:
[As, 3h, 6d, Jh, 3d, 7h, 2s]

Deck after dealing:
Th 4c 4d 9h 8c Ac 9c 6c 8h Qh 7c 5d Qc Ts Tc 5c 8d 7s 5s Kd 6h Ah Td 6s 3s Jd 8s Jc 3c 9d Kh Qs 9s Js 4h 2h 5h 7d
Size of Deck is 38

Submitting your solution

Save the files you created for this assignment in a folder called A5. From a terminal window, type the following commands:

cd
cd cs125 
submit125 A5