Project contains 3 classes:
/*************************************************************************************
The purpose of this project is to create 3 classes. Pile contains the number of marbles
in a randomly generated pile, and also a remove method to determine how many marbles are
to be removed. The player class determines the behavior of each type of player. There are
three types of players. Simple computer, Smart computer, and Human. These are all of enum
type. The program will use a randomly generated number to determine who goes first and
which level of skill the computer player is set at. Each player will draw a number of marbles
from the pile until the pile reaches 1. Whoever pulls the last marble will lose.
A player must choose between 1 and half the remaining pile.
***************************************************************************************/
Game
import java.util.*;
public class Game {
private static void printHeading(int projectNum, String projectName){ //creates an identifier method.
System.out.println("Chris Olson");
System.out.println("CMSC 255-002, Spring 2013");
System.out.println("Project " + projectNum);
System.out.println(projectName);
System.out.println();
}
public static void main(String[] args) {
printHeading(8,"Nim");
Scanner in = new Scanner(System.in);
Pile marbles = new Pile(); //creates initial Pile object
//Sets variables and objects to enum type
int marblesToRemove = 0;
Player humanPlayer = new Player(Player.Type.HUMAN);
Player compPlayer = new Player(Player.Type.SMART_COMPUTER);
Player secondPlayer = new Player(Player.Type.HUMAN);
Player firstPlayer = new Player(Player.Type.HUMAN);
Random randomNum = new Random(); //creates new random object to generate random numbers
int selection = 0;
//Interface
System.out.println("**************WELCOME TO THE GAME OF NIM******************");
System.out.println();
System.out.println();
System.out.println("******************RULES OF THE GAME***********************");
System.out.println("--The number of marbles in the initial pile will be random amount between 10 and 100.");
System.out.println("---Each player must choose between 1 and half of the remaining pile of marbles to remove.");
System.out.println("----The player stuck with the last marble loses the game.");
System.out.println("---The computer will randomly be placed into simple or smart mode randomly.");
System.out.println("--The player who goes first will also be chosen at random.");
System.out.println();
System.out.println("Enter 1 to play against another human or 2 to play against a computer.");
System.out.println("Enter 3 if you would like 2 computers to play against each other.");
selection = in.nextInt();
//Generates a random number between 1-2 to determine whether computer is set to smart of simple mode
if(randomNum.nextInt(2) == 1){
compPlayer.setType(Player.Type.SMART_COMPUTER);
System.out.println("Computer is set to Smart mode.");
}
else{
compPlayer.setType(Player.Type.SIMPLE_COMPUTER);
System.out.println("Computer is set to Simple mode.");
}
if(selection == 1){
compPlayer = humanPlayer;
}
else if(selection == 2) compPlayer = compPlayer;
else if(selection == 3) humanPlayer = compPlayer;
//Generates a random number between 1-2 to determine who goes first
if(randomNum.nextInt(2) == 1){
System.out.println("The user may go first.");
firstPlayer = humanPlayer; //sets player order
secondPlayer = compPlayer;
}
else{
System.out.println("The computer will go first.");
firstPlayer = compPlayer; //sets player order
secondPlayer = humanPlayer;
}
System.out.println();
System.out.println("Initial pile contains " + marbles.getMarbles() + " marbles.");
System.out.println();
while(marbles.getMarbles() > 0){ //while loop runs until getMarbles is greater than 0
System.out.println("Number of marbles currently in pile: " + marbles.getMarbles());
System.out.println();
marblesToRemove = firstPlayer.playTurn(marbles.getMarbles()); //calls playTurn and getMarbles methods to determine how many marbles have been removed and strategy
for(int i = 0;i<10;i++){
System.out.println("*");
}
System.out.println("--Player 1 removed " + marblesToRemove + " marbles.");
marbles.removeMarbles(marblesToRemove); //calls removeMarbles method with argument marblesToRemove
System.out.println();
if(marbles.getMarbles() == 1){ //If player 2 ends up with 1 marble left, player 1 wins
System.out.println("**********Player 1 wins.**********");
break;
}
System.out.println("Number of marbles currently in pile: " + marbles.getMarbles());
System.out.println();
marblesToRemove = secondPlayer.playTurn(marbles.getMarbles()); //calls playTurn and getMarbles methods to determine how many marbles have been removed and strategy
System.out.println("--Player 2 removed " + marblesToRemove + " marbles.");
marbles.removeMarbles(marblesToRemove); //calls removeMarbles method with argument marblesToRemove
System.out.println();
if(marbles.getMarbles() == 1){ //If player 1 ends up with 1 marble left, player 2 wins
System.out.println("**********Player 2 wins.**********");
break;
}
}
}
}
Player
import java.util.*;
/**
*
* @param player class sets the player type to enum and then dictates behavior based on selection in Game class.
*/
public class Player {
Scanner input = new Scanner(System.in);
Random marbles = new Random(); //creates random object of random class
public enum Type{HUMAN,SMART_COMPUTER,SIMPLE_COMPUTER} //declare enum objects
private Type type;
/**
* Constructor
* @param t indicates which of the three allowable Types this Player object will be
*/
public Player(Type t){
this.type = t;
}
/**
*
* @param t allows for enum type to be re-assigned
*/
public void setType(Type t){
this.type = t;
}
/**
*
* @param playTurn determines the computer and human behavior that dictates the course of the game
*/
public int playTurn(int pileSize){
int marblesRemoved = 0; //sets variable to 0
if(type == Type.SIMPLE_COMPUTER){ //SIMPLE_COMPUTER makes any random move, with no strategy.
marblesRemoved = marbles.nextInt((pileSize)/2)+1; //removes a random number between 1 and half the size of the remaining pile
}
else if(type == Type.SMART_COMPUTER){ //SMART_COMPUTER plays with a strategy. the computer takes off enough marbles to make the size of the pile a power of two minus 1—that is, 3, 7, 15, 31, or 63
if(pileSize > 63)
marblesRemoved = pileSize - 63;
else if(pileSize > 31)
marblesRemoved = pileSize - 31;
else if(pileSize > 15)
marblesRemoved = pileSize - 15;
else if (pileSize > 7)
marblesRemoved = pileSize - 7;
else if(pileSize == 2)
marblesRemoved = pileSize - 1;
else
marblesRemoved = marbles.nextInt((pileSize)/2)+1; //if the size of the pile is between 3-7, SMART_COMPUTER makes random legal move
}
else if (type == Type.HUMAN){ //HUMAN chooses the amount of marbles to remove
System.out.println("Please choose a number of marbles to remove between 1 and " + (pileSize/2));
marblesRemoved = input.nextInt();
while(marblesRemoved <=0 || marblesRemoved > pileSize/2){ //user input check to make sure number is between the correct values
System.out.println("You must choose a number between 1 and " + (pileSize/2) + ". Please choose another number.");
marblesRemoved = input.nextInt();
}
}
return marblesRemoved; //return marbles removed based on player enum type
}
public String toString(){ //can be implicitly called and relevant information about the internal state of the object. shows which enum player type is being played.
return this.type + "Player type selected.";
}
}
Pile
import java.util.*;
/**
*
* @param pile class generates a random pile of marbles to be used in game class. Ths number of marbles is between 10-100 inclusive.
* It also calculates the number of marbles removed
*/
public class Pile {
private int marbles = 0;
Random rand = new Random(); //create new random object to generate random number
/**
*
* @param pile constructer sets marble pile to random number between 1-100
*/
public Pile(){
this.marbles = rand.nextInt(89)+11;
}
/**
*
* @param getMarbles returns the current number of marbles in the game
*/
public int getMarbles(){
return this.marbles;
}
/**
*
* @param removeMarbles accepts an int vaiarble to remove from the stack of marbles
*/
public void removeMarbles(int takeMarb){
this.marbles -= takeMarb;
}
public String toString(){ //can be implicitly called and relevant information about the internal state of the object. Shows the current amount of marbles in stack.
return this.marbles + "marbles left in pile.";
}
}