Programming Assignment #4 Interfaces and Polymorphism I. The Ancient and Honorab
ID: 3798957 • Letter: P
Question
Programming Assignment #4
Interfaces and Polymorphism
I. The Ancient and Honorable Game of Nim
Nim is an ancient game with several variations. Here’s one: Two players takes turns removing marbles from a pile. On each turn, the player must remove at least one but no more than half of the remaining marbles. The player who is forced to remove the last marble loses.
II. The Assignment
Write a Java program in which the computer plays against a human opponent.
Begin each game by asking the human whether she wants to go first or second, and whether the computer should play in smart or stupid mode.
In stupid mode, the computer removes a random number of marbles between 1 and n/2 each turn.
In smart mode, the computer removes exactly enough marbles to make the remaining pile a power of two minus one (1, 3, 7, 15, 31, or 63).
The computer cannot be beaten in smart mode if it has the first move, unless the initial pile size happens to be 15, 31, or 63. Naturally, a human who plays first and knows the winning strategy is also invincible.
Begin each game with a pile of between 10 and 100 marbles, inclusive, where the size is set randomly.
After each turn, print out the player name (human’s actual name or computer), how many marbles the player took, and the number of marbles remaining.
When each game ends the winner should be announced and the human asked whether she wants to play again.
III. Specifications
1. To receive credit for this assignment, you must create a Java interface called Player, and 3 classes that implement it – one class for each of the 3 types of players. The interface will declare a move() method and any others you may deem necessary.
2. Implement another class called Nim with a play() method that conducts the game (as shown in class). The play() method must call the move() method polymorphically.
3. Design the move() method of the HumanPlayer class so that the human is not be allowed to “cheat” by removing an illegal number of marbles. (You know how those humans are)
4. Implement another class called Pile to create and maintain a pile of marbles.
5. Your test class will create the Player objects, the Nim object, and call the play() method. After each game, ask whether the user wants to play again.
The Nim class must depend only on the Player interface and Pile class, and not on any of the classes that implement the Player interface
Hint: Create the Player objects in your test class (or in a separate PlayerGenerator class) and pass them to the Nim constructor, or to the play() method
The individual player classes and the Pile class must not depend on one another or on the Nim class
(Recall that class A “depends on” class B if A creates objects or declares object variables of B (including method parameters), calls static methods of B, or accesses static constants of B)
IV. Due Date: Thursday, March 2nd
Code must be throughly internally commented for full credit
Explanation / Answer
NimGame.java
/*
File Name: NimGame.java
//******PROPERTY OF ALICIA RODRIGUEZ********
Tester class which will create the player objects and pass them
to the Nim constructor (or the play() method). Once the game has finished,
the user is prompted to see if they want to play again.
*/
package nimgame;
import java.util.Scanner;
//******PROPERTY OF ALICIA RODRIGUEZ********
public class NimGame {
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
//******PROPERTY OF ALICIA RODRIGUEZ********
System.out.println("Welcome To The Ancient and "
+ "Honorable Game of Nim! ");
//Player objects
Player humanPlayer = new Human();
Player dumbComputerPlayer = new DumbComputer();
Player smartComputerPlayer = new SmartComputer();
//******PROPERTY OF ALICIA RODRIGUEZ********
Scanner inputScan = new Scanner(System.in);
String playAgain;
do
{ //Play the game atleast once.
//Ask HUMAN whether they want to go first or second, and if they
//want to play against the smart or dumb comp.
System.out.println("Do you want to want to go First or Second? "
+ "(Type First or Second)");
String answer1 = inputScan.next();
System.out.println(""); //new line for formatting
//******PROPERTY OF ALICIA RODRIGUEZ********
System.out.println("Do you want to play with the Smart or Dumb "
+ "computer? (Type Smart or Dumb)");
String answer2 = inputScan.next();
System.out.println(""); //new line for formatting
//Nim object, create a new game everytime the person wants to play
//again
Nim nimGame = new Nim();
//******PROPERTY OF ALICIA RODRIGUEZ********
//4 different if statements for each condition
if(answer1.equalsIgnoreCase("First") &&
answer2.equalsIgnoreCase("Smart"))
{
nimGame.play(humanPlayer, smartComputerPlayer);
}
if(answer1.equalsIgnoreCase("First") &&
answer2.equalsIgnoreCase("Dumb"))
{
nimGame.play(humanPlayer, dumbComputerPlayer);
//******PROPERTY OF ALICIA RODRIGUEZ********
}
if(answer1.equalsIgnoreCase("Second") &&
answer2.equalsIgnoreCase("Smart"))
{
nimGame.play(smartComputerPlayer, humanPlayer);
//******PROPERTY OF ALICIA RODRIGUEZ********
}
if(answer1.equalsIgnoreCase("Second") &&
answer2.equalsIgnoreCase("Dumb"))
{
nimGame.play(dumbComputerPlayer, humanPlayer);
}
System.out.println(""); //new line for formatting
//******PROPERTY OF ALICIA RODRIGUEZ********
//Ask player if they want to play atleast one more time
System.out.println("Do you want to play again? (Yes or No)");
playAgain = inputScan.next();
System.out.println(""); //new line for formatting
//Check if the player doesn't want to play again
if(playAgain.equalsIgnoreCase("No"))
{ //if they don't then display message.
System.out.println(" Thanks for playing.");
}
//no break needed because it's already the end of the loop
//******PROPERTY OF ALICIA RODRIGUEZ********
} while(playAgain.equalsIgnoreCase("Yes"));
//does the player want to play again? then keep looping
//******PROPERTY OF ALICIA RODRIGUEZ********
}
//******PROPERTY OF ALICIA RODRIGUEZ********
}//end of NimGame class definition
SmartComputer.java
/*
File Name: SmartComputer.java
//******PROPERTY OF ALICIA RODRIGUEZ********
Smart computer player removes exactly enough marbles to make the remaining pile
a power of 2 minus one (ie. 1, 3, 7, 15, 31, or 63).
The smart computer player cannot be beaten unless the initial pile number that
is generated happens to be a power of 2 minus one.
*/
package nimgame;
//******PROPERTY OF ALICIA RODRIGUEZ********
import java.util.Random;
//******PROPERTY OF ALICIA RODRIGUEZ********
public class SmartComputer implements Player
{
/**
* Constructor of the smart computer
*/
public SmartComputer()
{//******PROPERTY OF ALICIA RODRIGUEZ********
//no instances variables needed; Therefore, nothing to be initialized.
}
/**
* Overriding toString method which will return what type of player this is
*
* @return smart computer
*/
@Override
public String toString()
{
return "Smart Computer";
}//******PROPERTY OF ALICIA RODRIGUEZ********
/**
* The smart computer will remove exactly enough marbles to make the
* remaining pile a power of 2 minus one.
*
* @param marbles number of marbles that are in the pile
* @return the number which the player wants to make their move with
*/
@Override
public int move(int marbles)
{//******PROPERTY OF ALICIA RODRIGUEZ********
int move=0;
if(marbles == 1 || marbles == 3 || marbles == 7 || marbles == 15
|| marbles == 31 || marbles == 63)
{ //if the marbles is already a power of 2-1
//then play as a dumb computer
Random generator = new Random();
move = generator.nextInt(marbles/2)+1;
//******PROPERTY OF ALICIA RODRIGUEZ********
}
else //play as smart computer
{
//powers of 2 -1
int [] powers = {1, 3, 7, 15, 31, 63};
//0 1 2 3 4 5
//******PROPERTY OF ALICIA RODRIGUEZ********
int i = powers.length-1; //last position in array
//while in position i
while(powers[i] > marbles)
{ //if i is > marbles
//decrement i until you've found that i is greater than marbles
i--;
//******PROPERTY OF ALICIA RODRIGUEZ********
//Example: marbles = 100
//is 63 greater than 100? no
}
//then subtract 100 by 63, which will give you the number of moves
move = marbles - powers[i];
//******PROPERTY OF ALICIA RODRIGUEZ********
}
System.out.println(this + " has removed " + move
+ " marbles from the pile. ");
return move; //move = marbles - powers(which ever number selected)
}//******PROPERTY OF ALICIA RODRIGUEZ********
}//end of SmartComputer class definition
Player.java
/*
File Name: Player.java
//******PROPERTY OF ALICIA RODRIGUEZ********
Player interface which will be implemented on the three different
types of players.
*/
package nimgame;
//******PROPERTY OF ALICIA RODRIGUEZ********
public interface Player {
/**
* The number which the player wants to make their next move with. Each
* different type of player has different conditions in choosing what
* number they wish to play.
* //******PROPERTY OF ALICIA RODRIGUEZ********
* @param marbles number of marbles that are in the pile
* @return the number which the player wants to make their move with
*/
int move(int marbles);
//******PROPERTY OF ALICIA RODRIGUEZ********
}//end of Player interface definition
Pile.java
/*
File Name: Pile.java
Class which creates and maintains the pile of marbles. The pile generates a
random number of marbles between 10 and 100.
*/
package nimgame;
//******PROPERTY OF ALICIA RODRIGUEZ********
import java.util.Random;
public class Pile
{//******PROPERTY OF ALICIA RODRIGUEZ********
//Instance Variable:
private int marbles; //number of marbles in the pile
/**
* Sets the initial number of marbles between 10 and 100 marbles randomly.
* This is how the game will start, with a random number and then the
* player will select a number which they want to subtract from.
*/
public Pile()
{//******PROPERTY OF ALICIA RODRIGUEZ********
Random generator = new Random();
marbles = generator.nextInt(91)+10;
}
//******PROPERTY OF ALICIA RODRIGUEZ********
/**
* Get the number of marbles which are left in the pile
*
* @return the number of marbles which are left in the pile
*/
public int getMarbles()
{
return marbles;
}
//******PROPERTY OF ALICIA RODRIGUEZ********
/**
* Removes marbles from the pile.
*
* @param toBeRemove number which will be removed from the pile
*/
public void removeMarbles(int toBeRemove)
{
//******PROPERTY OF ALICIA RODRIGUEZ********
marbles = marbles - toBeRemove;
System.out.println("There are now " + marbles + " marbles in the pile");
}
//******PROPERTY OF ALICIA RODRIGUEZ********
}//end of Pile class definition
Human.java
/*
File Name: Human.java
//******PROPERTY OF ALICIA RODRIGUEZ********
Human player which decides whether they want to play first or second. Human
player is whom inputs the move which they want to make.
*/
package nimgame;
import java.util.Scanner;
//******PROPERTY OF ALICIA RODRIGUEZ********
public class Human implements Player
{
/**
* Constructor of the human player.
*/
public Human()
{
//no instances variables needed; Therefore, nothing to be initialized.
}
//******PROPERTY OF ALICIA RODRIGUEZ********
/**
* Overriding toString method which will return what type of player this is
*
* @return human player
*/
@Override
public String toString()
{
return "Human Player"; //******PROPERTY OF ALICIA RODRIGUEZ********
}
/**
* Human is not allowed to cheat. Remove an illegal number of marbles which
* the human inputs.
*//******PROPERTY OF ALICIA RODRIGUEZ********
* @param marbles number of marbles that are in the pile
* @return the number which the player wants to make their move with
*/
@Override
public int move(int marbles)
{//******PROPERTY OF ALICIA RODRIGUEZ********
Scanner inputScan = new Scanner(System.in);
int move;
//Player must remove 1 but no more than half of the remaining marbles.
System.out.println(this + ", remove 1 but no more than half of "
+ "the remaining marbles: ");
move = inputScan.nextInt();
//******PROPERTY OF ALICIA RODRIGUEZ********
//while it is an illegal number
while (move > marbles / 2 || move < 1)
{//******PROPERTY OF ALICIA RODRIGUEZ********
System.out.println("Cheater! You've input an illegal number."
+ " Please try again. ");
System.out.println("Remove 1 but no more than half of "
+ "the remaining marbles: ");
move = inputScan.nextInt();
} //******PROPERTY OF ALICIA RODRIGUEZ********
System.out.println(""); //new line for formatting
return move; //the legal number which they wish to move with
}
//******PROPERTY OF ALICIA RODRIGUEZ********
}//end of Human class definition
Nim.java
/*
File Name: Nim.java
//******PROPERTY OF ALICIA RODRIGUEZ********
Nim class which depends only on the Player interface and
Pile class. It does not depend on any of the other classes that
implement the Player Interface.
*/
package nimgame;
//******PROPERTY OF ALICIA RODRIGUEZ********
public class Nim
{
//Instance Variables:
private Pile marblePile; //the pile of marbles
/**
* Constructs a pile.
*/
public Nim()
{
marblePile = new Pile();
//******PROPERTY OF ALICIA RODRIGUEZ********
}
/**
* Conductor of the game. Nim knows how many marbles are in the pile.
* Must call the move() method polymorphically.
*
* @param player1 Player 1: either human, smart comp, or dumb comp.
* @param player2 Player 2: either human, smart comp, or dumb comp.
*/
public void play(Player player1, Player player2)
{
System.out.println("***Game has started*** ");
//******PROPERTY OF ALICIA RODRIGUEZ********
System.out.println(player1 + " VS " + player2 + " ");
//polymorphically calling the corresponding toString methods
int play;
System.out.println("There are " + marblePile.getMarbles()
+ " marbles in the pile.");
//******PROPERTY OF ALICIA RODRIGUEZ********
do
{ //start conducting the game atleast once
play = player1.move(marblePile.getMarbles()); //polymorphism
marblePile.removeMarbles(play); //remove the number of marbles
//the player chooses in "move"
if(marblePile.getMarbles() == 1)
{ //if the number of marbles is equal to 1 then...
System.out.println(player1 + " is the winner!");
System.out.println(player2 + " pick up the last marble!");
break; //no need to continue
}
//******PROPERTY OF ALICIA RODRIGUEZ********
play = player2.move(marblePile.getMarbles()); //polymorphism
marblePile.removeMarbles(play); //remove the number of marbles
//the player chooses in "move"
if(marblePile.getMarbles() == 1)
{
System.out.println(player2 + " is the winner!");
System.out.println(player1 + " pick up the last marble!");
//no break needed because it's already the end of the loop
}
}
while(marblePile.getMarbles() > 0); //is #of marbles greater than 0?
//continue loop, if it's not then
//game has finished.
}//******PROPERTY OF ALICIA RODRIGUEZ********
}//end of Nim class definition
DumComputer.java
/*
File Name: DumbComputer.java
Dumb computer player removes a random number of marbles between 1 and
n/2 each time it is it's turn.
*/
package nimgame;
//******PROPERTY OF ALICIA RODRIGUEZ********
import java.util.Random;
public class DumbComputer implements Player
{
/**
* Constructor of the dumb computer
*/
public DumbComputer()
{
//no instances variables needed; Therefore, nothing to be initialized.
}
//******PROPERTY OF ALICIA RODRIGUEZ********
/**
* Overriding toString method which will return what type of player this is
*
* @return dumb computer
*/
@Override
public String toString()
{
return "Dumb Computer";
}
//******PROPERTY OF ALICIA RODRIGUEZ********
/**
* The dumb computers move will be a random number of marbles
* between 1 and n/2.
* //******PROPERTY OF ALICIA RODRIGUEZ********
* @param marbles number of marbles that are in the pile
* @return the number which the player wants to make their move with
*/
@Override
public int move(int marbles)
{
Random generator = new Random();
int move = generator.nextInt(marbles/2)+1;
System.out.println(this + " has removed " + move
+ " marbles from the pile. ");
return move;
}
} //end of Dumb Computer class definition
//******PROPERTY OF ALICIA RODRIGUEZ********
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.