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”

```<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){
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.
* @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.
* @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!");
}

/**
* 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 +" ");
}
}

}
</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>```