[java] Rock, Paper, Scissors Game Java

I'm new to programming and I'm trying to write a very simple Rock, Paper, Scissors game in Java. It will compile and run fine, but I am looking to say something like "Invalid move. Try again." or something along those lines for when the user (personPlay) does not enter a correct character (r, p, or s). What would be the best way to do so? For example, if you enter a "q", it should print "Invalid move." Thank you so much in advance!

// *************
// Rock.java 
// ************* 

import java.util.Scanner; 
import java.util.Random; 


public class Rock 
{ 
public static void main(String[] args) 
{ 
    String personPlay; //User's play -- "R", "P", or "S" 
    String computerPlay = ""; //Computer's play -- "R", "P", or "S" 
    int computerInt; //Randomly generated number used to determine 
                     //computer's play 
    String response; 


    Scanner scan = new Scanner(System.in); 
    Random generator = new Random(); 

    System.out.println("Hey, let's play Rock, Paper, Scissors!\n" + 
                       "Please enter a move.\n" + "Rock = R, Paper" + 
                       "= P, and Scissors = S.");

    System.out.println();

    //Generate computer's play (0,1,2) 
    computerInt = generator.nextInt(3)+1; 

    //Translate computer's randomly generated play to 
    //string using if //statements 

    if (computerInt == 1) 
       computerPlay = "R"; 
    else if (computerInt == 2) 
       computerPlay = "P"; 
    else if (computerInt == 3) 
       computerPlay = "S"; 


    //Get player's play from input-- note that this is 
    // stored as a string 
    System.out.println("Enter your play: "); 
    personPlay = scan.next();

    //Make player's play uppercase for ease of comparison 
    personPlay = personPlay.toUpperCase(); 

    //Print computer's play 
    System.out.println("Computer play is: " + computerPlay); 


    //See who won. Use nested ifs 

    if (personPlay.equals(computerPlay)) 
       System.out.println("It's a tie!"); 
    else if (personPlay.equals("R")) 
       if (computerPlay.equals("S")) 
          System.out.println("Rock crushes scissors. You win!!");
    else if (computerPlay.equals("P")) 
            System.out.println("Paper eats rock. You lose!!"); 
    else if (personPlay.equals("P")) 
       if (computerPlay.equals("S")) 
       System.out.println("Scissor cuts paper. You lose!!"); 
    else if (computerPlay.equals("R")) 
            System.out.println("Paper eats rock. You win!!"); 
    else if (personPlay.equals("S")) 
         if (computerPlay.equals("P")) 
         System.out.println("Scissor cuts paper. You win!!"); 
    else if (computerPlay.equals("R")) 
            System.out.println("Rock breaks scissors. You lose!!"); 
    else 
         System.out.println("Invalid user input."); 
}

}

This question is related to java java.util.scanner

The answer is


Before we try to solve the invalid character problem, the lack of curly braces around the if and else if statements is wreaking havoc on your program's logic. Change it to this:

if (personPlay.equals(computerPlay)) {
   System.out.println("It's a tie!");
}
else if (personPlay.equals("R")) {
   if (computerPlay.equals("S")) 
      System.out.println("Rock crushes scissors. You win!!");
   else if (computerPlay.equals("P")) 
        System.out.println("Paper eats rock. You lose!!");
}
else if (personPlay.equals("P")) {
   if (computerPlay.equals("S")) 
       System.out.println("Scissor cuts paper. You lose!!"); 
   else if (computerPlay.equals("R")) 
        System.out.println("Paper eats rock. You win!!");
} 
else if (personPlay.equals("S")) {
     if (computerPlay.equals("P")) 
         System.out.println("Scissor cuts paper. You win!!"); 
     else if (computerPlay.equals("R")) 
        System.out.println("Rock breaks scissors. You lose!!");
}
else 
     System.out.println("Invalid user input.");

Much clearer! It's now actually a piece of cake to catch the bad characters. You need to move the else statement to somewhere that will catch the errors before you attempt to process anything else. So change everything to:

if( /* insert your check for bad characters here */ ) { 
     System.out.println("Invalid user input.");
}
else if (personPlay.equals(computerPlay)) {
   System.out.println("It's a tie!");
}
else if (personPlay.equals("R")) {
   if (computerPlay.equals("S")) 
      System.out.println("Rock crushes scissors. You win!!");
   else if (computerPlay.equals("P")) 
        System.out.println("Paper eats rock. You lose!!");
}
else if (personPlay.equals("P")) {
   if (computerPlay.equals("S")) 
       System.out.println("Scissor cuts paper. You lose!!"); 
   else if (computerPlay.equals("R")) 
        System.out.println("Paper eats rock. You win!!");
} 
else if (personPlay.equals("S")) {
     if (computerPlay.equals("P")) 
         System.out.println("Scissor cuts paper. You win!!"); 
     else if (computerPlay.equals("R")) 
        System.out.println("Rock breaks scissors. You lose!!");
}

int w =0 , l =0, d=0, i=0;
    Scanner sc = new Scanner(System.in);

// try tentimes
    while (i<10) {


        System.out.println("scissor(1) ,Rock(2),Paper(3) ");
        int n = sc.nextInt();
        int m =(int)(Math.random()*3+1);


        if(n==m){

            System.out.println("Com:"+m +"so>>> " + "draw");
            d++;


        }else if ((n-1)%3==(m%3)){
            w++;
            System.out.println("Com:"+m +"so>>> " +"win");
        }
        else if(n >=4 )
        {
            System.out.println("pleas enter correct number)");


    }
        else {
            System.out.println("Com:"+m +"so>>> " +"lose");
            l++;

        }
        i++;

Why not check for what the user entered and then ask the user to enter correct input again?

eg:

//Get player's play from input-- note that this is 
// stored as a string 
System.out.println("Enter your play: "); 
response = scan.next();
if(response=="R"||response=="P"||response=="S"){
  personPlay = response;
}else{
  System.out.println("Invaild Input")
}

for the other modifications, please check my total code at pastebin


I would recommend making Rock, Paper and Scissors objects. The objects would have the logic of both translating to/from Strings and also "knowing" what beats what. The Java enum is perfect for this.

public enum Type{

  ROCK, PAPER, SCISSOR;

  public static Type parseType(String value){
     //if /else logic here to return either ROCK, PAPER or SCISSOR

     //if value is not either, you can return null
  }
}

The parseType method can return null if the String is not a valid type. And you code can check if the value is null and if so, print "invalid try again" and loop back to re-read the Scanner.

Type person=null;

 while(person==null){
      System.out.println("Enter your play: "); 
      person= Type.parseType(scan.next());
      if(person ==null){
         System.out.println("invalid try again");
      }
 }

Furthermore, your type enum can determine what beats what by having each Type object know:

public enum Type{

    //...

    //each type will implement this method differently
    public abstract boolean beats(Type other);


}

each type will implement this method differently to see what beats what:

ROCK{

   @Override
   public boolean beats(Type other){            
        return other ==  SCISSOR;

   }
}

 ...

Then in your code

 Type person, computer;
   if (person.equals(computer)) 
   System.out.println("It's a tie!");
  }else if(person.beats(computer)){
     System.out.println(person+ " beats " + computer + "You win!!"); 
  }else{
     System.out.println(computer + " beats " + person+ "You lose!!");
  }

You could insert something like this:

personPlay = "B";

while (!personPlay.equals("R") && !personPlay.equals("P") && !personPlay.equals("S")) {

    //Get player's play from input-- note that this is 
    // stored as a string 
    System.out.println("Enter your play: "); 
    personPlay = scan.next();

    //Make player's play uppercase for ease of comparison 
    personPlay = personPlay.toUpperCase();

    if (!personPlay.equals("R") && !personPlay.equals("P") && !personPlay.equals("S"))
        System.out.println("Invalid move. Try again.");

}