// Referee.java // Class for the state of a game of Chips For Three. // Written by THC for Lab #1. import java.util.Scanner; public class Referee { // Instance variables. private int chips; // Number of chips left private Player currentPlayer, nextPlayer, previousPlayer; // The three players private int maxMove; // Max number of chips in next legal move // Initialize the state of the game: // * the names of the players and how many chips each has // * the number of chips in the pile // * max number of chips that may be taken in the first move public Referee() { Scanner input = new Scanner(System.in); // Start by creating the two Player objects. System.out.print("What is the name of the first player? "); currentPlayer = new Player(input.nextLine()); System.out.print("What is the name of the second player? "); nextPlayer = new Player(input.nextLine()); // Make sure that the first two players have different names. while (currentPlayer.getName().equalsIgnoreCase(nextPlayer.getName())) { System.out.print("Both players cannot be named " + nextPlayer.getName() + ". Enter a different name: "); nextPlayer = new Player(input.nextLine()); } System.out.print("What is the name of the third player? "); previousPlayer = new Player(input.nextLine()); // Make sure that the third player has a different name from the first two. while (currentPlayer.getName().equalsIgnoreCase(previousPlayer.getName()) || nextPlayer.getName().equalsIgnoreCase(previousPlayer.getName())) { System.out.println("There cannot be more than one player named " + previousPlayer.getName() + ". Enter a different name: "); previousPlayer = new Player(input.nextLine()); } // Get the initial number of chips in the pile. final int MIN_CHIPS = 7; // Smallest odd number > 1 that is congruent to 1 (mod 3) System.out.print("How many chips does the initial pile contain? "); chips = input.nextInt(); while (chips < MIN_CHIPS || chips % 2 == 0 || chips % 3 != 1) { if (chips < MIN_CHIPS) System.out.print("You have to start with at least " + MIN_CHIPS + " chips. Choose another number: "); else System.out.print("You have to start with an odd number of chips " + "that is one greater than a multiple of 3.\n" + "Choose another number: "); chips = input.nextInt(); } // It's easy to determine the maximum number of chips that may be taken // in the first move. maxMove = chips / 2; // Print a blank line to separate this dialog from the rest of the game. System.out.println(); } // Return whether the game is over. public boolean saysGameIsOver() { return chips == 0; } // Print out the state of the game: // * How many chips each player has. // * Whose turn it is. // * How many chips remain. public void describeState() { describePlayers(); System.out.println("It is your turn, " + currentPlayer.getName() + "."); if (chips == 1) System.out.println("There is 1 chip remaining."); else System.out.println("There are " + chips + " chips remaining."); } // Print out how many chips each player has. public void describePlayers() { System.out.println(currentPlayer.describe()); System.out.println(nextPlayer.describe()); System.out.println(previousPlayer.describe()); } // Return whether a given move is legal and, if it's not legal, tell // the player why. private boolean isLegal(int move) { if (move < 1) { System.out.println("Illegal move: you must take at least one chip."); return false; } else if (move > maxMove) { System.out.print("Illegal move: you may not take more than " + maxMove + " chip"); if (maxMove != 1) System.out.print("s"); System.out.println("."); return false; } else return true; } // Get a legal move from a player, prompting until a legal move is given. public int getLegalMove() { int move; // The player's move Scanner input = new Scanner(System.in); // Tell the player the range of how many chips may be taken. System.out.print("You may take any number of chips from 1 to " + maxMove + ". "); do { System.out.print("How many will you take, " + currentPlayer.getName() + "? "); move = input.nextInt(); } while (!isLegal(move)); // At this point, we have a legal move, so return it. First, put out a blank // line to separate the dialog that just occurred from what will follow. System.out.println(); return move; } // Update the state of the game based on a move. public void updateState(int move) { chips -= move; // Remove the chips taken from the pile // Put the chips on the current player's pile. currentPlayer.addChips(move); // Rotate among the three players. Player temp = currentPlayer; currentPlayer = nextPlayer; nextPlayer = previousPlayer; previousPlayer = temp; // And update the max legal move for the next turn. maxMove = Math.min(chips, 2 * move); } // Determine who won the game, and announce it. public void announceWinner() { System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * *"); describePlayers(); // First, determine if one is odd and two are even. We do so by taking // the remainders and adding them up. They're either all 1 (adding to 3) // or only one is 1. int currentRem = currentPlayer.getChips() % 2; int nextRem = nextPlayer.getChips() % 2; int previousRem = previousPlayer.getChips() % 2; String winner; if (currentRem + nextRem + previousRem == 1) { // One is odd, two are even. The winner is the odd one. if (currentRem == 1) winner = currentPlayer.getName(); else if (nextRem == 1) winner = nextPlayer.getName(); else winner = previousPlayer.getName(); System.out.println(winner + " has an odd number of chips, " + "and the other two players have an even number."); } else { // All three are odd. Find the one with the different remainder when // we divide by 3. currentRem = currentPlayer.getChips() % 3; nextRem = nextPlayer.getChips() % 3; previousRem = previousPlayer.getChips() % 3; if (currentRem == nextRem) winner = previousPlayer.getName(); else if (currentRem == previousRem) winner = nextPlayer.getName(); else winner = currentPlayer.getName(); // Say why we have our winner. System.out.println("All three players have an odd number of chips."); System.out.println("Remainders when we divide chips by 3:"); System.out.println(" " + currentPlayer.getName() + ": " + currentRem); System.out.println(" " + nextPlayer.getName() + ": " + nextRem); System.out.println(" " + previousPlayer.getName() + ": " + previousRem); } System.out.println(winner + " wins!"); } }