CMPU 125 - Assignment 6
Implementing the Go Fish game - Part 2
Assigned: Monday, Oct. 20
Due: Friday, Nov 14

In this assignment you will:

  1. define a GoFish class to implement the card game Go Fish that plays one game, player (you) against the computer.

Summary: 

To refresh your memory, the game of Go Fish with 2 players works like this:  Each player is dealt 7 cards. Player one starts by requesting a particular rank card from player two (i.e., ace, king, 7, 10). If player two has any cards of the requested rank, they give all cards of that rank to player one and player one requests another card. When player one requests a rank of card that player two does not have, player two says "go fish", after which player one draws a card from the deck. If the drawn card matches the rank player one was asking for, player one can continue asking for cards; otherwise, player two takes a turn. If a player obtains a set of 4 cards of the same rank at any time during one of their turns, they can remove the set from their hand and they score a point. The game ends when the total score of both players is 13.

The GoFish class you write for this assignment will use most of the classes you developed for assignment 5. Note that this game involves comparing cards only according to rank, not suit. Therefore, you might want to change the equals method in the Card class so that it compares only rank, not suit, to determine Card equality. Alternately, you could create a new method in the Card class that compares only the rank of two Cards.
 
The details of the game are shown in Figure 1:

Figure 1: The class GoFish and its associated classes.


Implementation Details

I. Modify class GoFishHand:

For this part of the assignment, you will add some methods to the GoFishHand class you completed for Assignment 5.  The methods you should add are described below:
  1. Add a method called give that transfers all Cards of a given rank from the receiving hand to the parameter hand and returns a boolean that is true if any Cards were transferred. This method should take, as input parameters, an integer representing the rank and the GoFishHand that the cards will be transferred to.  Thus, the call  myHand.give(7,yourHand) would remove all 7s from myHand, add them to yourHand, and return true if any cards were affected (and false if none were affected).
     
    The give method should declare a local variable of type Iterator<Card>, calling the iterator() method inherited from the ArrayList<Card> class to return an Iterator<Card> object. The cards to be given are found by iterating through the hand that receives the method call. To remove Cards from a hand while iterating through it, obtaining each Card using the hasNext() and next() methods in a while loop, you can call the remove() method on the Iterator<Card> object. The remove method of the Iterator<Card> class just removes the Card from the hand, but it doesn't return anything. 
     
  2. A method called removeSets should go through a GoFishHand and remove all sets of 4 same-rank Cards from the hand, returning an integer representing the number of complete sets removed. Since there are 13 possible ranks of Cards, one way to count the number of each rank is to declare an integer array of size 14, initializing each position of the array to 0. Then, each position from 1 to 13 that corresponds to a rank in the hand can be incremented while taking a pass through the hand (possibly using a for-each loop).  After all the ranks in the hand have been tallied, check to see which ranks are equal to 4, removing those cards from the hand and incrementing the score for either the player or the computer for every set of 4 cards removed.

II.  Class GoFish:

Implement this class in file GoFish.java. This class should have the following instance variables:  computerHand and playerHand of type GoFishHand, deck of type Deck, and playerScore and computerScore, of type int.  This class will require input from the user, so you can write it to extend ConsoleProgram to take user input.

Methods in the GoFish class:

  1. GoFish should contain a main method, which welcomes the user, creates a new GoFish object, and then calls the play method on that object.
     
  2. The run method of GoFish should call the start() method of the ConsoleProgram class (if you are extending ConsoleProgram), should set both scores to 0, create a new Deck of Cards and shuffle it, create the two GoFishHands (playerHand and computerHand), and deal 7 cards to each hand.
     
  3. A method called play implements the following algorithm:
     1. while playerScore + computerScore < 13 {
     2.    while playerScore + computerScore < 13 && playerTurn() {}
     3.    while playerScore + computerScore < 13 && computerTurn() {}
        }
     4. print computerScore and playerScore
     5. if playerScore > computerScore, tell user they win
     6. else tell user computer wins
      
    Note that the while loops in steps 2 and 3 have no statements inside the {}'s. The reason for this may become clear after you read about the playerTurn() and computerTurn() methods below.
     
  4. A method called playerTurn takes a turn for the player. This method returns a boolean and takes no parameters. The algorithm for this method is as follows:

     1. if playerHand is empty and deck is not empty
     2.    deal a card to playerHand
     3. print the state of the game (see specs for toString of GoFish below)
     4. rank = prompt the user for a String, isolate 1st char and convert to an int
     5. bonusTurn = computerHand.give(rank, playerHand) 
     6. if bonusTurn is false  // computerHand contained no cards of given rank
     7.      print "Go fish"
     8.      deal a card and add it to the playerHand
     9.      if the rank of the card drawn was the one the user requested in step 4
    10.          bonusTurn = true
    11. sets = playerHand.removeSets()
    12. playerScore += sets
    13. if sets > 0
    14.      print number of sets and playerScore
    15. return bonusTurn


  5. A method called computerTurn takes a turn for the computer. This method returns a boolean and takes no parameters. The algorithm for this method is as follows:

     1. if computerHand is empty and deck is not empty
     2.    deal a card to computerHand
     3. print the state of the game (see specs for toString of GoFish below)
     4. rank = generate a random rank in the range 1...13
     5. get the first character of the rank and print "The computer asks for "+firstChar
     6. bonusTurn = playerHand.give(rank,computerHand)

     6. if bonusTurn is false  // playerHand contained no cards of given rank
     7.      print "Go fish"
     8.      deal a card and add it to the computerHand
     9.      if the rank of the card drawn was the one the computer generated in step 4
    10.          bonusTurn = true
    11. sets = computerHand.removeSets()
    12. computerScore += sets
    13. if sets > 0
    14.      print number of sets and computerScore
    15. return bonusTurn
     
  6. Lastly, add a toString method to the GoFish class.  This method should return a String that reports the current state of the game, as follows:    
     
         There are 36 cards in the deck
         The computer has 10 cards
         Your hand: [Ac, 6d, 3d, 7h, Tc, 3s]

     

You will get extra credit if you make your program more robust to unexpected input. For example, you can create exception classes and use the exceptions to recover from errors as shown in class.

Sample Output

Running the GoFish class will produce something like following series of output windows (produced by pressing the Run button when the GoFish class is highlighted in DrJava). NOTE: The blue text shown in the following figures is user input



Figure 1:  Start of GoFish game


 
Figure 2:  Middle of GoFish game


 
Figure 3:  End of GoFish game

Submitting your solution

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

cd
cd cs125 
submit125 A6