5
\$\begingroup\$

This my first java program. I wrote this as a Nim Game so that I could learn java while writing it. I would love to see how could this be made better.

Sample Game:

Nim Game

Code:

import java.util.Scanner;

public class Nim {

  public static boolean isArrayZero(int[] arr){
    for(int i: arr){
      if(i > 0)
      return false;
    }
    return true;
  }

  public static int getPile(char pile){
    switch (pile) {
      case 'A': return 0;
      case 'B': return 1;
      case 'C': return 2;
      default:  return -1;

    }
  }
  public static String playerTurn(String pl1, String pl2, int nbOfTurns){
    if(nbOfTurns % 2 == 0)
       return pl1;
       return pl2;
  }
  public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    String player1, player2, player;
    int[] pile = {3,5,7};
    int pileNb, howMany = 0, chosenPile = 0, nbOfTurns = 0;
    char pileName;
    //Get names of players
    System.out.print("Player1 name: ");
    player1 = input.next();

    System.out.print("Player2 name: ");
    player2 = input.next();


    do {
      System.out.println(String.format("\nA:%s\tB:%s\tC: %s", pile[0], pile[1], pile[2]) );
      player = playerTurn(player1, player2, nbOfTurns);
      do{
          System.out.print(String.format("\n%s,Choose a pile: ", player));
          pileName = Character.toUpperCase(input.next().charAt(0));
          pileNb = getPile(pileName);
          if(pileNb == -1)
            continue;
          chosenPile = pile[pileNb];
          if(chosenPile == 0)
            continue;
          System.out.println(String.format("How many to remove from pile %s", pileName));
          howMany = input.nextInt();
      }while((howMany > chosenPile) || (howMany <= 0));
      pile[pileNb] = chosenPile - howMany;
      nbOfTurns += 1;
    } while (!isArrayZero(pile));
    System.out.println(String.format("%s, You loose", player) );
  }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Are you on Java 8? \$\endgroup\$ – h.j.k. Oct 4 '15 at 15:18
  • 2
    \$\begingroup\$ @h.j.k yes, I do have java8. \$\endgroup\$ – Mohammad Oct 4 '15 at 15:23
6
\$\begingroup\$

Checking arrays

Since you are in Java 8, you can use IntStream to help you out:

public static boolean isArrayZero(int[] arr){
    return Arrays.stream(arr).allMatch(i -> i <= 0);
}

What that means is to ensure all matches the IntPredicate (lambda) i <= 0.

Input validation

Your input validation can probably be better done as a method:

private static int getPile(Scanner scanner) {
    int result = -1;
    while (result = -1) {
        result = getPile(Character.toUpperCase(input.next().charAt(0)));
    }
    return result;
}

And the same goes for asking the number to remove from the pile. These can be done to eliminate the need to continue from the loop.

Modeling

Using an int[] array is perfectly fine, but you may also want to explore other forms of modeling, such as using an enum:

enum Pile {
    A, B, C;

    public static Pile getPile(char input) {
        try {
            return valueOf(String.valueOf(input));
        } catch (IllegalArgumentException e) {
            return null;
        }
    }
}

Instead of dealing with array indices, you then deal with enum values, which depending on your perspective may look a little better.

try-with-resources

The usage of try-with-resources on the Scanner instance is recommended to manage its underlying I/O resource cleanly.

Potential bug

The screenshot you currently have does not agree with your code, since it looks like Mark managed to remove 8 from 7 in pile 'C'. The same prompts confused me here... Maybe use a prompt that indicates an invalid input was encountered will be a bit better.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.