Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I NEED HELP WITH THIS ASSIGNMENT PLEASE!!! The Ancient and Honorable Game of Nim

ID: 3599211 • Letter: I

Question

I NEED HELP WITH THIS ASSIGNMENT PLEASE!!!

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.

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 she wants to play against a smart computer or a stupid computer.

StupidComputer objects remove a random number of marbles between 1 and n/2, inclusive, each turn. (Where n is the number of marbles in the pile)

SmartComputer objects remove exactly enough marbles to make the remaining pile a power of two minus one (1, 3, 7, 15, 31, or 63).

A SmartComputer cannot be beaten if it has the first move, unless the initial pile size is 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 name), 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. If so, she must be able to choose her opponent and whether to go first or second

Specifications

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 kinds of players. The interface will declare an abstract move method that returns the number of marbles taken and an abstract getName method that returns the player’s name

Although the Measurable interface demonstrates static and default methods in addition to abstract methods, your Player interface will have abstract methods only (i.e. move and getName)

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

Design the move method of the HumanPlayer class so that the human is not allowed to “cheat” by removing an illegal number of marbles. (You know how those humans are)

Design the move method of the SmartComputer class so that the computer is not allowed to “cheat” either. (Once they get smart, no telling what those computers might do)

Implement another class called Pile to create and maintain a pile of marbles

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. You may pass the individual objects or an array containing the objects, your choice

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 of B, declares object variables of B (including method parameters), calls static methods of B, or accesses static constants of B

Explanation / Answer

Hello, I have answered the same question before. These are the things I did in my code

Note: Forgive me if the indentation is messed up.

//Player.java file

public interface Player {

      public abstract int move(int remaining);/*the parameter holds the number of tiles remaining*/

      public abstract String getName();

}

//HumanPlayer.java file

import java.util.Scanner;

public class HumanPlayer implements Player{

      String name;

      Scanner scanner;

      public HumanPlayer(String name) {

            this.name=name;

            scanner=new Scanner(System.in);

      }

      /**

      * the method will take a valid user input and returns;

      * throw an error if wrong values supplied

      */

      public int move(int remaining){

            int tiles=0;

            int max;

            if(remaining==1){

                  max=1;

            }else{

                  max=remaining/2;

            }

           

            if(max==1){

                  System.out.println("Choose 1");

            }else{

                  System.out.println("Choose from 1 and "+max+" tiles");

            }

           

            try{

                  tiles=Integer.parseInt(scanner.nextLine());

                  if(tiles<=0 || tiles>max){

                        System.out.println("Illegal choice");

                        return move(remaining); /*call itself again until player inputs a valid choice*/

                  }

            }catch(Exception e){

                  System.out.println("Illegal choice");                

                  return move(remaining); /*call itself again when player inputs any strings or wrong data*/

                 

            }

           

            return tiles;

      }

      public String getName() {          

            return name;

      }

}

//StupidComputer.java

import java.util.Random;

public class StupidComputer implements Player{

      Random random;

      public StupidComputer() {

            random=new Random();

      }

      /**

      * The method will just generate a random number between 1 and remaining/2 and returns

      */

      public int move(int remaining) {

            int tiles=0;

            int max;

            if(remaining==1){

                  max=1;

            }else{

                  max=remaining/2;

            }

           

            if(max==1){

                  return 1; /*only possible move*/

            }else{

                  tiles=random.nextInt(max-1)+1; /*generating a random number of tiles*/

            }

            return tiles;

      }

      public String getName() {          

            return "Stupid Computer";

      }

}

//SmartComputer.java

import java.util.Random;

public class SmartComputer implements Player {

      // Random random;

      public SmartComputer() {

            /**

            * default constructor

            */

      }

      /**

      * the following method will return the number of tiles removing by the smart computer

      */

      public int move(int remaining) {

            int tiles = 0;

            int max;

            if (remaining == 1) {

                  max = 1;

            } else {

                  max = remaining / 2;

            }

            if (max == 1) {

                  return 1; /* only possible move */

            } else {

                  tiles = findPilesToRemove(max, remaining);

            }

            return tiles;

      }

      public String getName() {

            return "Smart Computer";

      }

      /**

      * this method will return the number of piles to be removed so that the

      * remaining piles will be a power of two minus one (1, 3, 7, 15, 31, or 63).

      * (is possible)

      *

      * @param max

      *            the maximum piles that can be removed

      * @param remaining

      *            the total piles remaining

      * @return

      */

      int findPilesToRemove(int max, int remaining) {

            int tiles = 1;

            for (int i = max; i >= 1; i--) {

                  if (isPowerOf2(remaining - i)) {

                        if ((i + 1) <= max) {

                              return (i + 1);

                        }

                  }

            }

            return tiles;

      }

      /**

      * This method will check if a number is power of 2 (if a number n is a

      * power of 2, it's binary representation will have only one 1)

      *

      * @param n

      *            number to be checked

      * @return true if it is a power of 2 else false

      */

      private static boolean isPowerOf2(int n) {

            if (n <= 0) {

                  return false;

            }

            return (n & (n - 1)) == 0;

      }

}

//Pile.java

public class Pile {

      int piles;

      public Pile() {

            /**

            * default constructor

            */

            piles=0;

      }

      Pile(int tiles){

            /**

            * initializing number of piles

            */

            this.piles=tiles;

      }

      /**

      *

      * @return true if pile is 0

      */

      public boolean isEmpty(){

            if(piles==0){

                  return true;

            }else{

                  return false;

            }

      }

      /**

      *

      * @return the number of piles remaining

      */

      public int getTilesRemaining(){

            return piles;

      }

      /**

      *

      * @return the max number of piles that can be removed

      */

      public int getMaxLegalMove(){

            if(piles==1){

                  return 1;

            }

            return piles/2;

      }

      /**

      *

      * @param n

      * remove n number of piles

      */

      public void deleteTiles(int n){

            if(n<=piles){

                  piles=piles-n;

            }

           

      }

}

//Nim.java

import java.util.Random;

import java.util.Scanner;

public class Nim {

      private Player player1;

      private Player player2;

      private Random random;

      public Nim(Player player1,Player player2) {

            this.player1=player1;

            this.player2=player2;

      }

     

      public void play(){

            random = new Random();

            Pile pile=new Pile(random.nextInt(100 - 10 +1) + 10);

            boolean firstRun=true; /*a flag variable for checking if the play is being started (for tossing which player to play first)*/

            Player currentPlayer=null; /*a Player variable to represent the player with the current turn*/

            int tmp=random.nextInt(); /*generating a random number for tossing*/

            int tiles_to_move=0; /* a variable to store the number of tiles returned by move() of the players*/

           

            while(!pile.isEmpty()){

                  if(firstRun){

                        if(tmp%2==0){ /*if the random number generated is an even number,player 1 will play first,else player2*/

                              System.out.println(player1.getName()+" will make the first move");

                              currentPlayer=player1;

                        }else{

                              System.out.println(player2.getName()+" will make the first move");

                              currentPlayer=player2;                         

                        }

                        firstRun=false;

                  }

                  System.out.println(" Pile now has "+pile.getTilesRemaining()+" tiles, it's "+currentPlayer.getName()+"'s turn");

                                               

                  tiles_to_move=currentPlayer.move(pile.getTilesRemaining());

                  if(tiles_to_move<=0 || tiles_to_move>pile.getMaxLegalMove()){

                        /**

                        * double checking the input; making it more bulletproof

                        */

                        System.out.println("Illegal Move, try again");

                  }else{

                        pile.deleteTiles(tiles_to_move); /*removing tiles from the pile*/

                        System.out.println(currentPlayer.getName() + " chose " + tiles_to_move);

                        if (currentPlayer == player1) { /*swapping the turns*/

                              currentPlayer = player2;

                        } else if (currentPlayer == player2) {

                              currentPlayer = player1;

                        }

                  }

                 

                 

                 

                  if(pile.isEmpty()){ /*if the pile is empty, then the game is over; currentPlayer (not the one who made last turn) wins*/

                        System.out.println("Game over: "+currentPlayer.getName()+" wins");

                  }

            }

            System.out.println("Do you want to play again? Y or N");

            Scanner scanner=new Scanner(System.in);

            String ch=scanner.next();

            if(ch.equalsIgnoreCase("Y")){

                  play();

            }else{

                  System.out.println("Thanks. Byee");

            }

      }

}

//Test.java

import java.util.Scanner;

public class Test {

      public static void main(String[] args) {

            Scanner scanner=new Scanner(System.in);

            System.out.println("Welcome...!");

            System.out.println("Enter your name");

            String name=scanner.nextLine();

            System.out.println("Do you want to play against a Stupid computer (a) or a Smart computer (b)?");

            System.out.println("Enter a or b");

            String choice=scanner.nextLine();

            if(choice.equalsIgnoreCase("a")){

                  /**

                  * human and stupid computer will play

                  */

                  HumanPlayer human=new HumanPlayer(name);

                  StupidComputer stupid=new StupidComputer();

                  Nim nim=new Nim(human, stupid);

                  nim.play();

            }else if(choice.equalsIgnoreCase("b")){

                  /**

                  * human and smart computer will play

                  */

                  HumanPlayer human=new HumanPlayer(name);

                  SmartComputer smart=new SmartComputer();

                  Nim nim=new Nim(human, smart);

                  nim.play();

            }

           

      }

}

/*output*/

Welcome...!

Enter your name

Alice

Do you want to play against a Stupid computer (a) or a Smart computer (b)?

Enter a or b

b

Smart Computer will make the first move

Pile now has 51 tiles, it's Smart Computer's turn

Smart Computer chose 20

Pile now has 31 tiles, it's Alice's turn

Choose from 1 and 15 tiles

14

Alice chose 14

Pile now has 17 tiles, it's Smart Computer's turn

Smart Computer chose 2

Pile now has 15 tiles, it's Alice's turn

Choose from 1 and 7 tiles

7

Alice chose 7

Pile now has 8 tiles, it's Smart Computer's turn

Smart Computer chose 1

Pile now has 7 tiles, it's Alice's turn

Choose from 1 and 3 tiles

7

Illegal choice

Choose from 1 and 3 tiles

3

Alice chose 3

Pile now has 4 tiles, it's Smart Computer's turn

Smart Computer chose 1

Pile now has 3 tiles, it's Alice's turn

Choose 1

1

Alice chose 1

Pile now has 2 tiles, it's Smart Computer's turn

Smart Computer chose 1

Pile now has 1 tiles, it's Alice's turn

Choose 1

1

Alice chose 1

Game over: Smart Computer wins

Do you want to play again? Y or N

Y

Smart Computer will make the first move

Pile now has 74 tiles, it's Smart Computer's turn

Smart Computer chose 11

Pile now has 63 tiles, it's Alice's turn

Choose from 1 and 31 tiles

31

Alice chose 31

Pile now has 32 tiles, it's Smart Computer's turn

Smart Computer chose 1

Pile now has 31 tiles, it's Alice's turn

Choose from 1 and 15 tiles

10

Alice chose 10

Pile now has 21 tiles, it's Smart Computer's turn

Smart Computer chose 6

Pile now has 15 tiles, it's Alice's turn

Choose from 1 and 7 tiles

5

Alice chose 5

Pile now has 10 tiles, it's Smart Computer's turn

Smart Computer chose 3

Pile now has 7 tiles, it's Alice's turn

Choose from 1 and 3 tiles

3

Alice chose 3

Pile now has 4 tiles, it's Smart Computer's turn

Smart Computer chose 1

Pile now has 3 tiles, it's Alice's turn

Choose 1

1

Alice chose 1

Pile now has 2 tiles, it's Smart Computer's turn

Smart Computer chose 1

Pile now has 1 tiles, it's Alice's turn

Choose 1

1

Alice chose 1

Game over: Smart Computer wins

Do you want to play again? Y or N

N

Thanks. Byee