Game Sample: Pig

This is a game which I wrote for a computer science class. 2 of these classes were written by my prof. Adam Smith. He wrote the humanPigPlayer, and theAbstract  pigPlayer.

The game’s rules can be read here.

The class Pig serves as a template for the game to be played within. It keeps track of the scores of each player, and facilitates the play of the game by generating a random number, which represents the die. It also initializes the players. As the code is on this site, the 2 players will be 1 human, and 1 AI which can be viewed below. They are named “Name” and “Name2”

Screen Shot 2018-01-26 at 4.37.01 PMScreen Shot 2018-01-26 at 4.41.21 PM

<pre>
import java.util.Scanner;
/**
 * Skeleton for a pig game
 * @author Aidan Takami
 * @version   1.1
 */

class Pig {
	/**
	 * The score needed to win a round.
	 */
	public static final int WINNING_SCORE = 100;

	public static void main(String[] args) {

		// intro, initialize players
		System.out.println("Welcome to Pig!");
		PigPlayer human = new HumanPigPlayer("Name");
		PigPlayer opponent = new AidansPigPlayer("Name2"); // This is a bot, can also be human.
		int[] roundsWon = new int[2];

		// round 1
		System.out.println("Round 1!");
		if (playRound(human, opponent)) roundsWon[0]++;
		else roundsWon[1]++;

		System.out.println();

		// round 2
		System.out.println("Round 2!");
		if (playRound(opponent, human)) roundsWon[1]++;
		else roundsWon[0]++;

		// report the final results
		reportFinalTally(roundsWon, human, opponent);
	}

	/**
	 * Do one round, crediting the winner.
	 * @param player1 the first player
	 * @param player2 the second player
	 * @return true if player1 won, false if player2
	 */
	// This function does the following:
	// 1. Enter an infinite loop, with player 1 taking a turn, then player 2.
	// 2. Keep track of each player's score and the turn number.
	// 3. When a player wins, print the winner, and break out of the loop.
	// 4. Return
	private static boolean playRound(PigPlayer player1, PigPlayer player2) {
		//declares int values for turn number, player1 score, and player2 score. Also declares a boolean continueOn for loop
		int turn = 0;
		boolean continueOn = true;
		int player1Score = 0;
		int player2Score = 0;

		//loop allows players to play their turn until there is a winner
		while(continueOn == true){

			//adds score from player's turns to their score, and ends loop once WINNING_SCORE is reached
			player1Score += playTurn(player1, turn, player1Score, player2Score);
			if(player1Score >= WINNING_SCORE){
				return true;
			}
			player2Score += playTurn(player2, turn, player2Score, player1Score);
			if(player2Score >= WINNING_SCORE){
				return false;
			}
			turn++;
		}
		return false;
	}

	/**
	 * Play a single turn, returning how many points the player got.
	 * @param player the player whose turn it is
	 * @param turnNum the turn number (0-indexed)
	 * @param score the player's score
	 * @param opponentsScore the player's adversary's score
	 * @return the points that the player won
	 */
	// This function must do the following:
	// 1. Call the player's beginTurn() method.
	// 2. Loop so long as the player wants to continue rolling.
	// 3. Roll a die:
	//     a. If a 1 is rolled, return 0.
	//     b. On any other roll, add it to the pool.
	// 4. If the loop ends, return the pool's value.
	// 5. Be sure to print events frequently, so the human player can see what's
	//    happening!
	private static int playTurn(PigPlayer player, int turnNum, int score, int opponentsScore) {
		//calls beginTurn()
		player.beginTurn(score, opponentsScore);
		System.out.println();

		//declares a boolean for the loop and an int for the die roll
		boolean continueOn = true;
		int dieRoll;
		int rollNumber = 0;

		//sets score for this turn = to 0
		int roundScore = 0;

		//takes input from user before turn starts, but only users. Not ComputerPigPlayer
		if(player instanceof HumanPigPlayer){
		System.out.println(player.getName() + ", when you are ready, type something.");
		Scanner input = new Scanner(System.in);
		input.nextLine();
		}

		//While loop to iterate as long as player wishes to continue on
		while(continueOn == true){

			//rolls a random die value, prints out roll, and returns 0 if a 0 is rolled
			rollNumber++;
			dieRoll = (int )(Math.random() * 6 + 1);
			System.out.println("You rolled a " + dieRoll + "!");
			if(dieRoll == 1){
				System.out.println("Too bad! End of turn!");
				return 0;
			}

			//adds roll to score and prints score
			else{
				roundScore += dieRoll;
				score += dieRoll;
			}
			System.out.println("Your score is now " + score + ".");

			//if score == WinningScore, score is returned. also gives player option to continue or not
			if(score >= WINNING_SCORE || !(player.decideIfShouldRoll(turnNum, rollNumber, roundScore, score, opponentsScore))){

				//ends loop
				continueOn = false;
			}
			System.out.println();
		}
		//returns the score
		return roundScore;
	}

	/**
	 * Deliver a final report, indicating the overall winner after all rounds
	 * have been played.
	 * @param roundsWon an array of <code>int</code>s indicating the number of rounds each player won
	 * @param player1 the first player
	 * @param player2 the second player
	 */
	// This function must do the following:
	// 1. Print out both player's scores.
	// 2. Indicate who the winner was (or if there was a tie).
	private static void reportFinalTally(int[] roundsWon, PigPlayer player1, PigPlayer player2) {
		if(roundsWon[0] > roundsWon[1]){
			System.out.println("Congrats " + player1.getName() + " you won!!");
			System.out.println("The final tally was " + roundsWon[0] + " to " + roundsWon[1] + "!");
		}
		if(roundsWon[1] > roundsWon[0]){
			System.out.println("Congrats " + player2.getName() + " you won!!");
			System.out.println("The final tally was " + roundsWon[1] + " to " + roundsWon[0] + "!");
		}
		if(roundsWon[0] == roundsWon[1]){
			System.out.println("TIE!");
			System.out.println("The final tally was " + roundsWon[0] + " to " + roundsWon[1] + "!");
		}
	}
}
</pre>

This is the base pigPlayer class, created by Adam Smith. AI and the human class both extend this class

<pre>
/**
 * This is the base pig player. Other pig players (e.g. <code>HumanPigPlayer</code>) must
 * extend this class.
 * @author   Adam Smith
 * @version   1.0
 */

abstract public class PigPlayer {
	private String name; // player's name

	/**
	 * The main constructor for <code>PigPlayer</code>.
	 * @param name The <code>PigPlayer</code>'s name
	 */
	public PigPlayer(String name) {
		this.name = name;
	}

	/**
	 * Accessor for the <code>PigPlayer</code>'s name.
	 * @return the <code>PigPlayer</code>'s name
	 */
	public String getName() {
		return name;
	}

	/**
	 * Alert the <code>PigPlayer</code> that its turn is beginning. This method
	 * needs to be implemented in the subclass (even if it is an empty
	 * function).
	 * @param myScore the player's current score
	 * @param opponentsScore the opponent's current score
	 */
	abstract public void beginTurn(int myScore, int opponentsScore);

	/**
	 * Should the <code>PigPlayer</code> roll again? This method needs to be
	 * implemented in the subclass, taking the exact same arguments (even though
	 * some of them may be unused).
	 * @param turnNumber which turn the player is on (0-indexed)
	 * @param rollNumber which roll the player is on (0-indexed)
	 * @param poolSize the number of points currently in the pool
	 * @param myScore the number of points the player has already won
	 * @param opponentsScore the number of points the opponent has already won
	 * @return true to roll again, false to stop
	 */
	abstract public boolean decideIfShouldRoll(int turnNumber, int rollNumber, int poolSize, int myScore, int opponentsScore);
}
</pre>

This is the human pigPlayer class. Also created by Adam Smith, it allows a human to participate in the game, when initialized in the Pig class.

<pre>
import java.util.Scanner;

/**
 * This is the human pig player. It makes all of its decisions based on input
 * from the keyboard.
 * @author      Adam Smith
 * @version     1.0
 */

public class HumanPigPlayer extends PigPlayer {

	// the shared Scanner among all human pig players (in case there are many)
	static Scanner inputScanner = null;

	/**
	 * The main constructor for <code>HumanPigPlayer</code>.
	 * @param name The <code>HumanPigPlayer</code>'s name
	 */
	public HumanPigPlayer(String name) {
		super(name);

		// if this is the first HumanPigPlayer, allocate the Scanner
		if (inputScanner == null) inputScanner = new Scanner(System.in);
	}

	/**
	 * Alert the human player that his/her turn is beginning.
	 * @param myScore the player's current score
	 * @param opponentsScore the opponent's current score
	 */
	public void beginTurn(int myScore, int opponentsScore) {
		System.out.println(getName() +", it is now your turn!");
		System.out.println("\tYour score is "+myScore+", and your opponent's is " +opponentsScore+".");
	}

	/**
	 * Should the player roll again? This method just asks the human at the
	 * keyboard.
	 * @param turnNumber which turn the player is on (unused)
	 * @param rollNumber which roll the player is on (unused)
	 * @param poolSize the number of points currently in the pool
	 * @param myScore the number of points the player has already won (unused)
	 * @param opponentsScore the number of points the opponent has already won
	 * (unused)
	 * @return true to roll again, false to stop
	 */
	public boolean decideIfShouldRoll(int turnNumber, int rollNumber, int poolSize, int myScore, int opponentsScore) {
		System.out.println("The pool is now " +poolSize+".");
		return getYesNoQuestion("Do you wish to roll?");
	}

	// private helper function that keeps asking a question until it gets a yes or a no
	private static boolean getYesNoQuestion(String question) {
		while (true) {
			System.out.print(question +" ");
			String answer = inputScanner.nextLine();
			if (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes")) return true;
			if (answer.equalsIgnoreCase("n") || answer.equalsIgnoreCase("no")) return false;
		}
	}

}
</pre>

This is extremely simple AI created by me to serve as an opponent in  a game of Pig.

I simplified resources found here and tried to best optimize the AI’s chance of winning against a human player.

<pre>
/**
 * Pig Player AI which uses resources found online to hopefully best optimize
* the AI's chance of winning.
 * @author      Aidan
 * @version     1.0
 */

public class AidansPigPlayer extends PigPlayer {

	/**
	 * The main constructor for <code>ComputerPigPlayer</code>.
	 * @param name The <code>ComputerPigPlayer</code>'s name
	 */
	public AidansPigPlayer(String name) {
		super(name);
	}

	/**
	 * This function does nothing. It is here to fulfill the requirements of the abstract <code>PigPlayer</code> class.
	 * @param myScore the player's current score (unused)
	 * @param opponentsScore the opponent's current score (unused)
	 */
	@Override
	public void beginTurn(int myScore, int opponentsScore) {
                System.out.println();
		System.out.println("Bot's turn!");
	}
<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>
	/**
	 * Should the player roll again? The computer always rolls once.
	 * @param turnNumber which turn the player is on (unused)
	 * @param rollNumber which roll the player is on
	 * @param poolSize the number of points currently in the pool (unused)
	 * @param myScore the number of points the player has already won (unused)
	 * @param opponentsScore the number of points the opponent has already won
	 * (unused)
	 * @return true to roll again, false to stop
	 */
	@Override
	public boolean decideIfShouldRoll(int turnNumber, int rollNumber, int poolSize, int myScore, int opponentsScore) {
		if(myScore >= opponentsScore + 25){
			if(poolSize < 14){
				return true;
			}
		}
		if (poolSize <span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>< 20) return true;
		else return false;
	}
}

</pre>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s