UserPlayer Class

Strategy Overview

The second and final type of Player in our game will be one that allows the user to play the game and follow their own preferred strategy. Specifically, it will have the user input a rank to ask of the opponent every turn. In this part of the lab, we will implement a UserPlayer that interacts with the user and is our second child class of AbtractPlayer.

With a UserPlayer you can compete with either a RandomPlayer or another player!

UserPlayer Description

Inside your GitHub repository, you will find a file called UserPlayer.java. This is where we will implement the UserPlayer 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.

Once again, most of the functionality needed is already implemented in the AbstractPlayer parent class. However, we do need to add one instance variable: a Scanner object that allows us to repeatedly get new inputs from the user:

/** The {@link Scanner} to use to interact with the user. */
private Scanner scanner;

Note

The Scanner needs to be an instance variable instead of recreated every time we interact with the user, otherwise we will not be able to repeatedly ask for inputs before closing the program.

As in Part 3, there are only two methods to implement: the UserPlayer constructor and the decideRank method that implements the strategy described above.

UserPlayer Constructor

Once again, the UserPlayer constructor should call the parent constructor to initialize all of the shared instance variables. It should also create the Scanner used to interact with the user through System.in (as in Lab 1 Part 2):

this.scanner = new Scanner(System.in);
decideRank Method

The decideRank method determines which rank to request from the opponent. This time, the rank should be chosen by the user. To aid them in their choice, this function should:

  1. Print out the Cards in the player’s current hand so they know what their valid options are.
  2. Save the user’s input, validating that both (i) it is an integer (using a try-except block with a NumberFormatException), and (ii) it is one of the ranks in the player’s hand (this is where the countCards helper function suggested in Part 2 could be useful).
  3. Return the user’s input if it is valid, else prompt them again for an input

Testing Our Implementation

Once again, we can test our implementation before running the full GoFish game. We can again add a private static void main(String args[]) function to our UserPlayer class and add code for testing new functionality:

  1. Instantiate an instance of the UserPlayer class to make sure that the new Scanner instance variable is being correctly. This verifies the correctness of the constructors.
  2. Again provide the UserPlayer object with some known cards using the gainCards method, then call the decideRank method to verify that (i) it displays the correct options to the user, (ii) it validates the user’s input correctly, (iii) it keeps requesting inputs until a valid rank is provided, and (iv) it returns the user’s chosen rank.

Playing Go Fish!

Once you’ve tested both of your RandomPlayer and UserPlayer classes, we are ready to play the game using the GoFish class. You should first compile the GoFish.java file, which will also make sure all of the other Java files needed for the game are compiled. The program in GoFish expects two command line arguments when it is run: the types of player 1 and player 2, which should be either Random or User. For example, to play two RandomPlayer AIs against one another, we would run the following in the terminal after compiling all of our code:

java GoFish Random Random

If you want to try your hand against the RandomPlayer, you could instead run the following and act as Player 1:

java GoFish User Random

Finally, if you want to try to play against a friend, you could instead run the following:

java GoFish User User

where one of you acts as Player 1 and the other as Player 2.

Committing Your Progress

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