2

My assignment is to write a program that lets the user play the game of Rock, Paper, Scissors against the computer.

Instructions:

The main method should have two nested loops, where the outer loop will allow the user to play the game as often as desired and the inner loop will play the game as long as there is a tie. Call the method isValidChoice() in a while loop in the userChoice() method to verify that the choice that user enters must be “rock”, “paper”, or “scissors”. If invalid string is input, isValidChoice()will return false and the program should ask for new input until the valid input is given.

Situation:

The program runs fine when the user enters a valid input. However once its not a valid input, there is a small problem.

Result:

Enter rock, paper, or scissors: rocky
Invalid input, enter rock, paper, or scissors: roc
Invalid input, enter rock, paper, or scissors: rock
The computer's choice was paper
The user's choice was rocky

Play again? (y/n)

As you can see, the program recognizes the invalid inputs. The user finally enter a valid input the third time. However, it displays user's first choice "rocky" which is invalid. Therefore the program can't display who wins.

Question

I need your help.
I want my program to run like this: When the user enters multiple invalid inputs, but once a valid input is entered, my program should still be able to display the user's valid input and display the winner.

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

public class RockPaperScissorsGame 
{
   public static void main (String[] args)
   {
      Scanner keyboard = new Scanner(System.in);

      String computer, user;
      char keepPlaying;

      do 
      {
         computer = computerChoice();
         user = userChoice();

         System.out.println("The computer's choice was " + computer);
         System.out.println("The user's choice was " + user);

         determineWinner(computer, user);

         while (computer.equals(user))
         {
            computer = computerChoice();
            user = userChoice();

            System.out.println("The computer's choice was " + computer);
            System.out.println("The user's choice was " + user);

            determineWinner(computer, user);
         }


         System.out.println("\n" + "Play again? (y/n)");
         keepPlaying = keyboard.nextLine().toLowerCase().charAt(0);

         while ( keepPlaying != 'y' && keepPlaying != 'n' )
         {
            System.out.println("Invalid input, please enter (y/n)");
            keepPlaying = keyboard.nextLine().toLowerCase().charAt(0);
         }

      } while (keepPlaying == 'y');

   }
   public static String computerChoice()
   {
      String[] choice = {"rock","paper","scissors"};
      Random rand = new Random();
      int computerChoice = rand.nextInt(3);
      return choice[computerChoice];
   }
   public static String userChoice()
   {
      Scanner keyboard = new Scanner(System.in);
      System.out.print("Enter rock, paper, or scissors: ");
      String choice = keyboard.nextLine();

      isValidChoice(choice);
      return choice;
   }
   public static boolean isValidChoice (String choice)
   {
      Scanner keyboard = new Scanner(System.in);

      while (!(choice.equalsIgnoreCase("rock")) && !(choice.equalsIgnoreCase("paper")) && !(choice.equalsIgnoreCase("scissors")))
    {
       System.out.print("Invalid input, enter rock, paper, or scissors: ");
       choice = keyboard.nextLine();
    }

       return true;
    }
    public static void determineWinner(String computer, String user)
    {
       if (computer.equalsIgnoreCase("rock") && user.equalsIgnoreCase("paper"))
          System.out.println("\n" + "Paper wraps rock.\nThe user wins!");
       else if (computer.equalsIgnoreCase("rock") && user.equalsIgnoreCase("scissors"))
          System.out.println("\n" + "Rock smashes scissors.\nThe computer wins!");
       else if (computer.equalsIgnoreCase("paper") && user.equalsIgnoreCase("rock"))
          System.out.println("\n" + "Paper wraps rock.\nThe computer wins!");
       else if (computer.equalsIgnoreCase("paper") && user.equalsIgnoreCase("scissors"))
          System.out.println("\n" + "Scissors cuts paper.\nThe user wins!");
       else if (computer.equalsIgnoreCase("scissors") && user.equalsIgnoreCase("rock"))
          System.out.println("\n" + "Rock smashes scissors.\nThe user wins!");
       else if (computer.equalsIgnoreCase("scissors") && user.equalsIgnoreCase("paper"))
          System.out.println("\n" + "Scissors cuts paper.\nThe computer wins!");
       else if (computer.equalsIgnoreCase(user))
          System.out.println("\n" + "The game is tied!\nGet ready to play again...");
    }   
}
SimplyValdo
  • 35
  • 2
  • 6
  • 4
    possible duplicate of [Is Java "pass-by-reference" or "pass-by-value"?](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – ajb Nov 18 '14 at 00:36
  • 5
    You seem to think that `isValidChoice(choice)` could modify the `choice` variable, but it can't. So the `choice` in `userChoice` will remain the same, i.e. the original invalid entry. – ajb Nov 18 '14 at 00:37
  • 1
    A quick style comment, your `isValidChoice` method should only return whether the given `choice` is valid or not. It shouldn't perform any other tasks (in your case you have it getting a new result from stdin if it fails the test). Otherwise the name of the method does not match what it truly does. To further the argument, with the code you have the return value of `isValidChoice` will always be true and can be ignored. – lc. Nov 18 '14 at 00:39
  • 1
    `determineWinner` seems to be incorrect--[rock flies right through paper](https://www.youtube.com/watch?v=MyCa-LHtIKE) :) :) :) – ajb Nov 18 '14 at 00:39
  • @ajb : Yes, your second comment explains well about my thoughts . I'm taking an intro java programming class, so I'm learning. I need to read that article you posted. I'll recheck my logic on `determineWinner` Thank you for everything :) – SimplyValdo Nov 18 '14 at 01:10
  • @SimplyValdo The comment about `determineWinner` was a joke. My apologies, I should be careful about making pop culture references in a forum like this. Your logic is just fine. – ajb Nov 18 '14 at 01:22
  • The assignment is incomplete without "lizard, spock". – dar7yl Nov 18 '14 at 01:24

3 Answers3

4

This issue arises from the fact that Java is pass by value, not pass by reference.

In other words, rather than a reference of your parameter being passed to the method, a copy of the parameter is passed. Your method changes the copy but then once the method ends, the copy goes out of scope and is garbage collected.

When you pass choice into isvalidChoice, the reference to choice itself isn't passed. A copy of the string is made and then is passed. When you update the variable choice, it doesn't change the original string, it changes the copy that the System made. This answer explains how it works pretty well.

So what should you do?

Instead of looping in isValidChoice have isValidChoice return false if it isn't a valid input.

Your isValidChoice should end up looking like this:

public static boolean isValidChoice(String choice) {
    return (choice.equalsIgnoreCase("rock")) || (choice.equalsIgnoreCase("paper")) || (choice.equalsIgnoreCase("scissors"));
}

Then do something like this in userChoice

Scanner keyboard = new Scanner(System.in);
while(!isValidChoice(choice)) {
    System.out.print("Invalid input, enter rock, paper, or scissors: ");
    choice = keyboard.nextLine();
}
Community
  • 1
  • 1
  • In layman's terms, the user variable 'points' to the value of user, meanwhile the choices variable in isValidChoice is a separate item that 'points' to the value of user. When you do choices = x, you're simply setting the choices variable to 'point' to another value, leaving the user variable alone. – Perry Monschau Nov 18 '14 at 00:46
  • @michael : Thank you for a well explanation. I'll read the link you posted carefully. – SimplyValdo Nov 18 '14 at 01:43
0

package practicePrograms;

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

public class Rock_Paper_Scissors {

@SuppressWarnings({ "resource" })
public static void main(String[] args) {
    Random rand = new Random();
    Scanner scan = new Scanner (System.in);
    int totalscuser = 0;
    int compans = 0;
    int totalsccpu = 0;
    System.out.println("Rock Paper Scissors!"+"\n"+"Rock:     '0'"+ "\n" +"Paper:    '1'"+"\n"+"Scissors: '2'");
    System.out.println("It's best out of 3!");
    for(int i = 0; i<3; i++){
        compans = rand.nextInt(3);
        compans = rand.nextInt(3);
        int inp = scan.nextInt();
        if(inp == compans){
            System.out.println("Tie");
        }else if((inp-1) == compans){
            if(inp>2){
                System.err.println("Enter a valid input."+"\n"+"CPU Wins because user entered an invalid input.");
                totalsccpu = totalsccpu + 1;
            }else{
                System.out.println("User Wins");
                totalscuser = totalscuser + 1;
            }
        }else if((inp) == compans-1){
            if(inp>2){
                System.err.println("Enter a valid input."+"\n"+"CPU Wins because user entered an invalid input.");
                totalsccpu = totalsccpu + 1;
            }else{
            System.out.println("CPU Wins");
            totalsccpu = totalsccpu + 1;
            }
        }else if((inp-2) == compans){
            if(inp>2){
                System.err.println("Enter a valid input."+"\n"+"CPU Wins because user entered an invalid input.");
                totalsccpu = totalsccpu + 1;
            }else{
            System.out.println("CPU Wins");
            totalsccpu = totalsccpu + 1;
            }
        }else if((inp) == compans-2){
            if(inp>2){
                System.err.println("Enter a valid input."+"\n"+"CPU Wins because user entered an invalid input.");
                totalsccpu = totalsccpu + 1;
            }else{
                System.out.println("User Wins");
                totalscuser = totalscuser + 1;
            }
        }else{
            System.err.println("Enter a valid input."+"\n"+"CPU Wins because  user entered an invalid input.");
            totalsccpu = totalsccpu + 1;
        }
        System.out.println("CPU entered: "+compans);
    }
    if(totalsccpu>totalscuser){
        System.err.println("YOU LOSE! :(");
    }else if(totalsccpu<totalscuser){
        System.err.println("YOU WIN! :]");
    }if(totalsccpu == totalscuser){
        System.err.println("YOU TIED! :|");
    }
}

}

0

This is example using integers, but can be adapted to your liking with strings.

when I write {rock} it means it is your int identifier for rock, or use .equals(insert string identifier here) for string it will look like !user.equals("Rock") && !user.equals("Paper") && !user.equals("Scissors")

while(user!= {rock} && user!= {paper} && user!= {scissors})
        { // use while
            System.out.print("Invalid choice! (Choose 1, 2 or 3): ");
            user= keyboard.nextInt(); // or keyboard.next() for any other way string
                if(user==1 || user==2 || user==3) // I used int for example
                    break; // quits the loop if proper identifier entered

            System.out.println();
            // if invalid choice, it will go back to the start of loop
        }
agotfrid
  • 507
  • 5
  • 7