RandomPlayer Class

Strategy Overview

When playing Go Fish, the main decision a player needs to make is what rank to ask the other player for. There are many different strategies players could take here. Some popular ones include:

  1. always asking for the most common rank they have in their hand, which is the most likely to complete a book for the player
  2. always asking for the last rank they picked up from the deck when their previous turn ended, which could be the most likely rank to be held by the opponent
  3. spread their asks across the numbers they have (maybe in ascending or descending order), which could make it more difficult for the opponent to remember what cards the player is holding

What strategy a player follows is the key distinguishing characteristic between different types of Player and represent the different children classes of AbtractPlayer.

One basic strategy that combines aspects of all three of the above is to simply select a random card that the player is holding and ask for its rank. The ranks the player has more of is more likely to be randomly chosen, and randomly choosing a rank spreads asks across ranks to hopefully increase the chances of getting a card from the opponent and obfuscate what cards the player is holding.

In this part of the lab, we will implement a RandomPlayer that follows this random asking strategy and is our first child class of AbtractPlayer.

RandomPlayer Description

Inside your GitHub repository, you will find a file called RandomPlayer.java. This is where we will implement the RandomPlayer class that inherits the shared functionality of the AbstractPlayer and can participate in the GoFish game. Open this file in Visual Studio Code to get started.

Because we implemented so much of the necessary code in AbstractPlayer, there are no new instance variables to add and only two methods to implement: the RandomPlayer constructor and the decideRank method that implements the strategy described above.

RandomPlayer Constructor

There is nothing new that needs to be done in the RandomPlayer constructor since it has no new instance variables. Instead, the only code needed within the body of the RandomPlayer constructor is to call the parent’s constructor using:

super(playerNumber);
decideRank Method

The decideRank method determines which rank to request from the opponent. This needs to be a rank that the player already has. Similar to GuessingGame in Lab 1, we can:

  1. use a java.util.Random number generator to choose a random number between 0 and n-1 (where n is the number of cards in the player’s hand)
  2. grab the card at the randomly chosen position from the hand instance variable return the rank of the randomly selected card

Testing Our Implementation

Because the provided GoFish class expects us to have implemented both the RandomPlayer and UserPlayer (Part 4) classes, we cannot quite run the game yet to test our implementation. Instead, it is better practice to test each of the individual functions to make sure they are working to verify that both AbstractPlayer and RandomPlayer are implemented correctly.

To do so, we can add a private static void main(String args[]) function to our RandomPlayer class and add code for testing the different functions. Some ideas you might want to try:

  1. Instantiate an instance of the RandomPlayer class and make sure that the instance variables are correctly instantiated. This verifies the correctness of the constructors.
  2. Create a Card[] array and provide it to the gainCards method of the RandomPlayer object, then print contents of the hand instance variable to make sure it stores the correct cards. Example code to make an array with specific cards is:
Card[] cards = new Card[] {
	new Card(Card.Suit.Heart, 2),
	new Card(Card.Suit.Diamond, 2),
	new Card(Card.Suit.Spade, 5),
	new Card(Card.Suit.Club, 7),
	new Card(Card.Suit.Heart, 8)
};
  1. Request one of the ranks that are in the RandomPlayer‘s hand using the requestCards method, then print (i) the returned Card[] array to make sure the correct cards were found and (ii) the resulting hand instance variable to make sure the found cards were removed.
  2. Request one of the ranks that the RandomPlayer does not have in their hand to make sure an empty Card[] array is returned.
  3. Give the RandomPlayer the cards needed to have a book, then call the checkBooks method to see if the booksScore increases by 1 and the book is removed from their hand.
  4. Call the decideRank method a few times to see if different ranks are returned that all belong to the hand.

Committing Your Progress

Remember to save your progress periodically to GitHub using the add, commit, and push commands with git.