0

I am nearly finished with a Java project of mine. The objective is to play a game of Rock Paper Scissors with the user and the computer. The computer generates a random number and that number must correlate with either one of the three choices. I got it to where it can play successfully, but here is the catch, in the case of a tie, the game is to repeat and start over, otherwise it is to terminate. I have it to where it terminates, but cannot figure out how to get it to repeat the entire process in the case of a tie. The methods must remain the way they are, but my professor said the answer is if the entire thing is in a loop. My question is which loop should I use and where should it be placed? Here is the code:

public class FahrDylanRockPaperScissors{
public static void main (String [] args){
    String computer = computerChoice();
    String user = userChoice();
    determineWinner(computer, user);

}
public static String computerChoice( ){
    Random rand = new Random();
     int cinput = rand.nextInt(3)+ 1;
     String computer = "thing";
    if (cinput == 1)
    computer = "Rock";
    if (cinput == 2)
    computer = "Paper";
    if (cinput == 3)
    computer = "Scissors";
    return computer;
}
public static String userChoice(){
    Scanner sc = new Scanner (System.in);
    String user = "default";
    do{
        System.out.println ("Let's Play a game! Rock, Paper, Scissors!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + "\nPlease enter either Rock, Paper, or Scissors: " + "\nGood Luck!");
        user = sc.nextLine();
    }

    while (isValidChoice (user) == false);
    return user;
}
public static boolean isValidChoice(String choice){
    boolean status;
    if (choice.compareTo("Rock")== 0)
        status = true;
    else if (choice.compareTo("Paper")== 0)
        status = true;
    else if (choice.compareTo("Scissors")== 0)
        status = true;

    else{
        status = false;
        System.out.println("Error! Make sure you are capitalizing your choices");
    }

    return status;
}
public static void determineWinner(String computer, String user){
    System.out.println (" Computer Choice: " + computer);
    System.out.println ("Your Choice : " + user);
    if (computer.compareTo( "Rock" ) == 0 && user.compareTo  ("Scissors") == 0)
    System.out.println (" Computer wins! Better luck next time!");
    if (computer.compareTo("Scissors")== 0 && user.compareTo("Paper") == 0)
    System.out.println (" Computer wins! Better luck next time!");
    if (computer.compareTo("Paper") == 0 && user.compareTo("Rock") == 0)
    System.out.println (" Computer wins! Better luck next time!");
    if (computer.compareTo("Rock") == 0 && user.compareTo("Paper") == 0)
    System.out.println (" You win!!");
    if (computer.compareTo("Scissors") == 0 && user.compareTo("Rock") == 0)
    System.out.println (" You win!!");
    if (computer.compareTo("Paper") == 0 && user.compareTo("Scissors") == 0)
    System.out.println (" You win!!");
    else if (computer.compareTo(user) == 0 )
    System.out.println(" Tie! the game must be played again.");
}

}

spongebob
  • 8,370
  • 15
  • 50
  • 83
Dylan F
  • 81
  • 3
  • 14

4 Answers4

2

You can use a do-while loop, because your code needs to be executed at least one time.

public static void main (String [] args){
    boolean win = false;
    do{
        String computer = computerChoice();
        String user = userChoice();
        win = determineWinner(computer, user);
    }while(!win);
}

For the first time you execute the whole code. Then the predicate is checked, and if someone won, the do-while will stop. But if win equals false it will be executed again.

You could achieve the same with only a while loop, or other loops. But because your code needs to be run at least one time a do-while suits well.

Edit:

You need to change your code, so that determineWinner returns back if someone won (return true) or if there is a tie (return false). I did not see that it currently has no return type when posting the answer.

A simple way to get the determineWinner method to work would be the following.

public static boolean determineWinner(String computer, String user){
    System.out.println (" Computer Choice: " + computer);
    System.out.println ("Your Choice : " + user);
    if (computer.compareTo( "Rock" ) == 0 && user.compareTo  ("Scissors") == 0)
    System.out.println (" Computer wins! Better luck next time!");
    if (computer.compareTo("Scissors")== 0 && user.compareTo("Paper") == 0)
    System.out.println (" Computer wins! Better luck next time!");
    if (computer.compareTo("Paper") == 0 && user.compareTo("Rock") == 0)
    System.out.println (" Computer wins! Better luck next time!");
    if (computer.compareTo("Rock") == 0 && user.compareTo("Paper") == 0)
    System.out.println (" You win!!");
    if (computer.compareTo("Scissors") == 0 && user.compareTo("Rock") == 0)
    System.out.println (" You win!!");
    if (computer.compareTo("Paper") == 0 && user.compareTo("Scissors") == 0)
    System.out.println (" You win!!");
    else if (computer.compareTo(user) == 0 ){
        System.out.println(" Tie! the game must be played again.");
        return false;
    }
    return true;
}

And for your coding style:

It's good practice to use brackets {} for if/else/for... even if you have only one statement, because it improves the readability of your code.

Edit 2:

Because you can't change something, the easiest way is probably the following:

public static void main(String[] args){
     boolean tie = true;
        do{
            String computer = computerChoice();
            String user = userChoice();
            tie = (computer.compareTo(user) == 0);
            determineWinner(computer, user);
        }while(tie);
}

Even if determineWinner determines the winner you need it to give you feedback. If you can't get feedback, just determine if there will be a tie in your main-Method, and if you get a tie, repeat.

Loki
  • 4,065
  • 4
  • 29
  • 51
  • @CoolGuy I added this to my answer. I didn't see that it has no return type in the first place. – Loki Mar 24 '15 at 15:04
  • That certainly made the loop work but now it repeats even if the user or computer wins, which is not supposed to happen, it is only to repeat if tie. – Dylan F Mar 24 '15 at 15:04
  • Why would it repeat if the user or computer wins? If someone wins, determineWinner would `return true`, and `while(!win)` will stop execute. The author still needs to change the `determineWinner` method to return something, though. – Loki Mar 24 '15 at 15:06
  • 1
    `public static void determineWinner(...)` should be `public static boolean determineWinner(...)` – Spikatrix Mar 24 '15 at 15:18
  • I did the steps you listed in your edited post, the problem now is that there are three errors. E:\Programming\FahrDylanRockPaperScissors.java:81: error: cannot return a value from method whose result type is void return true; same thing for the false, and finally it cannot compare the boolean win with the method determineWinner, it requires boolean but finds void. – Dylan F Mar 24 '15 at 15:19
  • I forgot to change the return type. Try again with the updated version – Loki Mar 24 '15 at 15:20
  • Thats the problem, I cannot change the method of determineWinner, it must remain void – Dylan F Mar 24 '15 at 15:22
  • Can you change the body? – Loki Mar 24 '15 at 15:23
  • I can change anything save for the methods – Dylan F Mar 24 '15 at 15:26
  • If you can change something in the method, but not what it returns, the best way is probably the one, @frogbandit suggested. Create a new method that will execute the game logic, call it once in main and if you have a tie, let it run again. – Loki Mar 24 '15 at 15:28
  • I cannot create a new method to the body though the instructions want specific returns and methods, though no additional methods either. – Dylan F Mar 24 '15 at 15:31
  • I gave you another example solution. I would not prefer that one, but if you are not allowed to change anything, this would work. – Loki Mar 24 '15 at 15:32
  • The second edit fixed it, basically all I needed to do was a do while loop in the main and identifying the tie from the value of the ==0. Thank you man! I swear on the several times I posted here you have helped hugely. Along with everyone else thank you! – Dylan F Mar 24 '15 at 15:38
  • do you really need a loop at all? – kstandell Mar 24 '15 at 15:43
1

You could easily just make the three lines:

public static void playGame()
{
      String computer = computerChoice();
       String user = userChoice();
       determineWinner(computer, user);
}

into one new method, something like playGame(). Then in the main function, you can call playGame(), and at the end of determineWinner(), you could have:

else if (computer.compareTo(user) == 0 )
    {
        System.out.println(" Tie! the game must be played again.");
        playGame();
    }

to play the game again.

Also, make sure you include the import statements for Random and Scanner. And make sure you close your scanner.

frogbandit
  • 561
  • 1
  • 8
  • 21
  • This will solve the problem, but I suggest a slight change: methods should **only** do what their name suggests they do. A method that is called `determineWinner()` should not trigger a new game if there is a tie. Instead, it should return a value (that would be preferably based on an enum). Then the `playGame()` method can decide to call itself again. – GhostCat Mar 24 '15 at 15:11
0

Use a flag for tie, something like this:

boolean tie = false;

combine with do while:

do {


} while (tie);

if tie == true than keep going until its false.

Code Whisperer
  • 1,041
  • 8
  • 16
0

A do { ... } while () loop would be most natural for this problem, but pretty much any loop construct could serve.

Although you say

The methods must remain the way they are

you cannot do it if the determineWinner() method remains exactly as it now is. That method needs one way or another to communicate back to main() whether there is a tie, or else it must itself manage running a new game in the event of a tie. Were I free to do so, I would have it return a a boolean value indicating whether there was a tie. If it cannot be modified to return a value, then the other alternative would be for it to set a static variable to indicate whether there was a tie. Alternatively, you could solve this problem with recursion, but that would not involve a loop.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Please explain a bit more. if I am to create a static variable value from the tie, would I have to return that and use a do while loop with it, and also what do you mean by recursion we have yet to learn that. – Dylan F Mar 24 '15 at 15:25
  • Do not worry about recursion at this time. To use a static variable, you would declare it in the class, outside any method, for example: `static boolean wasTied = true;`. On every invocation, the `determineWinner()` method would set that variable to `true` or `false`, as appropriate. The `main()` method would use the value of that variable to determine whether to break from the loop or to perform another iteration. – John Bollinger Mar 24 '15 at 15:29