I am trying to make my rock paper scissors app loop if the user wants it to and am not sure how.
I am in a programming class but I broke my code while trying to fix it last time and managed to return to what I had before.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String playAgain = "Y";
while (playAgain.equals("Y") || playAgain.equals("y"))
{
String playerChoice = "";
while (!playerChoice.equals("R") && !playerChoice.equals("P") && !playerChoice.equals("S"))
{
System.out.println("Please enter a correct character\n (R)ock, (P)aper, or (S)cissors.");
playerChoice = scan.next();
//Player choice to upper case to minimize the number of wrong inputs//
playerChoice = playerChoice.toUpperCase();
}
int randNum = (int) (Math.random() * 3);
String compChoice = "";
switch (randNum)
{
case 0:
compChoice = "R";
break;
case 1:
compChoice = "P";
break;
case 2:
compChoice = "S";
break;
}
System.out.println("The computer chose: " + compChoice);
if (playerChoice.equals(compChoice))
{
System.out.println("It's a Tie!");
} else if (playerChoice.equals("R") && compChoice.equals("S") || playerChoice.equals("P") && compChoice.equals("R") || playerChoice.equals("S") && compChoice.equals("P"))
{
System.out.println("You Win!");
} else
{
System.out.println("You Lose");
}
System.out.println("Would you like to play again?\n(Y or N)");
playAgain = scan.nextLine();
if (playAgain.equals("N"))
{
break;
}
}
}
The solution is you need agreement between your scan method calls.
Either both should be nextLine or both should be next.
As an aside - I quite like the use of .equalsIgnoreCase instead of .equals on string comparisons, since it makes the code simple and easy to read. (You can skip the toUpperCase for instance, and the extra conditions)
As for why/what exactly the scanner is doing which causes that problem, that's a lot more detailed and fiddly.
Related
I am trying to figure out where to put the loop that when the user enters any value other than "rock", "paper" or "scissors" the program stays in the loop and displays "Invalid entry" while requesting the user to enter again.
Any help is much appreciated.
As it stands now, the program will display "Invalid entry" but then continues without asking the user to try again.
import java.util.Scanner; // Import the Scanner class
import java.util.Random; // Import the random class for game
/**
*/
public class Challenge17
{
// Method to determine the random choice of computer
public static String getComputerChoice(Random random)
{
int number;
number = random.nextInt(3) + 1;
String computerChoice;
switch (number)
{
case 1:
computerChoice = "rock";
break;
case 2:
computerChoice = "paper";
break;
case 3:
computerChoice = "scissors";
break;
default:
computerChoice = "";
}
return computerChoice;
}
// Method to display the menu for choices
public static void displayChoice( )
{
System.out.println("Game Options\n----------\n"
+ "1: rock\n2: paper\n3: scissors");
}
// Method to request and hold user choice for game
public static String getUserInput(Scanner keyboard)
{
String userInput;
System.out.println("Enter your choice: ");
userInput = keyboard.nextLine();
return userInput;
}
// Method to determine winner
public static String determineWinner(String computerChoice, String userInput)
{
String winner = "Tie Game!"; // Default display Tie game
String message = ""; // To determine the message for winner
String displayMessage; // To display the message for winner
// Custom messages below
String rockMessage = "Rock smashes scissors";
String scissorsMessage = "Scissors cuts paper";
String paperMessage = "Paper wraps rock";
boolean loop = false;
if(computerChoice.equals("rock") && userInput.equalsIgnoreCase("scissors"))
{
winner = " Computer wins!";
message = rockMessage;
loop = true;
}
else if (userInput.equalsIgnoreCase("rock") && computerChoice.equals("scissors"))
{
winner = "You win!";
message = rockMessage;
loop = true;
}
if(computerChoice.equals("scissors") && userInput.equalsIgnoreCase("paper"))
{
winner = " Computer wins!";
message = scissorsMessage;
loop = true;
}
else if (userInput.equalsIgnoreCase("scissors") && computerChoice.equals("paper"))
{
winner = "You win!";
message = scissorsMessage;
loop = true;
}
if(computerChoice.equals("paper") && userInput.equalsIgnoreCase("rock"))
{
winner = " Computer wins!";
message = paperMessage;
loop = true;
}
else if (userInput.equalsIgnoreCase("rock") && computerChoice.equals("scissors"))
{
winner = "You win!";
message = paperMessage;
loop = true;
}
else
{
System.out.println("Invalid entry.");
loop = false;
}
displayMessage = winner + " " + message;
return displayMessage;
}
// Main method to initiate and execute game
public static void main(String[] args)
{
Random random = new Random(); // To call the random class
Scanner keyboard = new Scanner(System.in); // To call the scanner class
String computerChoice; // Hold computer input
String userInput; // Hold user input
String input; // Hold input for repeat
char repeat; // Character for repeat
do
{
displayChoice(); // Call method to display the choices
computerChoice = getComputerChoice(random); // Hold the PC random choice
userInput = getUserInput(keyboard); // To get the user input
System.out.println("You chose: " + userInput + " computer chose: \n"
+ computerChoice);
System.out.println(determineWinner(computerChoice, userInput));
// Does the user want to play again
System.out.println("Would you like to play again?");
System.out.print("Enter Y for yes, or N for no: ");
input = keyboard.nextLine();
repeat = input.charAt(0);
}
while (repeat == 'Y' || repeat == 'y');
}
}
From my understanding i'm pretty sure you want this kind of a loop
public static String getUserInput(Scanner keyboard)
{
String userInput;
System.out.println("Enter your choice: ");
userInput = keyboard.nextLine();
while(!userInput.equals("rock")&&!userInput.equals("paper")&&!userInput.equals("scissors"))
{
System.out.println("Invalid Entry, Please re-enter your choice:");
userInput = keyboard.nextLine();
} //It wont go out of the loop unless it's one of the 3 choices
return userInput;
}
You could create a Boolean method.
private Boolean checkUserInput(String input) {
if(!input.equalsIgnoreCase("rock") && !input.equalsIgnoreCase("paper") && !input.equalsIgnoreCase("scissors")) return false;
return true;
Then you do the check before you determine the winner like if true then run the determineWinner(computerChoice, userInput) code else it doesn't.
That way, you can edit the code and add functionalities in the future if need be.
So here i am trying to create a program that takes an input as an int and then plays a game of Rock paper scissors. It seems to want to reprint statements that it shouldn't be and is skipping printing statements as well. I would love some assistance if possible. I have tried setting up print statements everywhere but it has just been more confusing.
import java.util.Scanner;
public class RPSS{
//Main method
public static void main(String[ ] argc)
{
System.out.println("Lets play rock paper scissors");
Scanner tnt = new Scanner(System.in);
String computerHand; // string variable for computer choice
String userHand; // string variable for user choice
//
String answer = "";
while (!a
nswer.equals("No") && (!answer.equals("no"))){
userHand = userHand();
computerHand = computerHand();
System.out.println("The User picks " + userHand + " " );
System.out.print("The Computer picks " + computerHand );
String winner = getWinner(computerHand, userHand);
System.out.println(winner);
System.out.println("play again?");
answer = tnt.next();
}
//Condition for the do-while loop
}
public static String userHand(){ //method for users choice in the game
//prints message to user giving them choices
System.out.println(" ");
System.out.println("1. Rock ");
System.out.println("2. Paper ");
System.out.println("3. Scissors ");
int userChoice; // user choice variable in this method
Scanner tnt = new Scanner(System.in); // creates instance of scanner class
userChoice = tnt.nextInt(); //reads user input
return getChoice(userChoice); //returns user choice to userChoice
}
public static String computerHand() //method for computer generated choice
{
int computernum = 1 + (int)(Math.random() * (( 2) +1));
return getChoice(computernum);
}
public static String getChoice(int num) //method recieving both computer hand and user hand
{
// if statements to place the correct choice
String choice = "";
if (num == 1){
choice = "Rock";
}
else if(num == 2){
choice = "Paper";
}
else if(num == 3){
choice = "Scissors";
}
return choice;
}
// Method determing the winner
public static String getWinner(String computerChoice, String userChoice)
{
computerChoice = computerHand(); //places computerChoice variable in computerhand
userChoice = userHand(); //does same for user choice
String winner="";
if (userChoice.equals("Rock") && computerChoice.equals("Paper")){
System.out.println("The computer wins");
return winner;
}
else if (userChoice.equals("Paper") && computerChoice.equals("Scissors")){
System.out.println(" The computer wins");
return winner;
}
else if (userChoice.equals("Scissors") && computerChoice.equals("Rock")){
System.out.println(" The computer wins ");
return winner;
}
else if (userChoice.equals("Rock") && computerChoice.equals("Paper")){
System.out.println(" The computer wins ");
return winner;
}
else if(userChoice.equals(computerChoice))
{
System.out.println(" There is no winner");
return " ";
}
else{
return winner;
}
}
}
The first problem is that userhand() and computerHand() are being called twice per "round", once at the beginning of the while loop inside the main method and once at the beginning of the getWinner() method. Elimination of the calls at the beginning of the getWinner() method should solve the repeats.
The 2nd Problem is that instead of modifying the value of winner inside the getWinner() method before returning it, you are you are simply outputting the message via println(). an example of fixing this would be converting this:
if (userChoice.equals("Rock") && computerChoice.equals("Paper"){
System.out.println("The computer wins");
return winner;
}
to this:
if (userChoice.equals("Rock") && computerChoice.equals("Paper")){
winner = "The computer wins";
return winner;
}
another minor issue is the fact that
userChoice.equals("Rock") && computerChoice.equals("Paper")
is checked twice, id just remove the entire if else block based around the
2nd check of it
Lastly i would treat the final else clause as the player wins one and set winner to something like " The player wins "
Sorry I am new to this site so not sure how this will show up. I am trying to make a simple Rock, Paper, Scissors game. After the while statement, if R, P, S isn't entered, the program just does nothing. I want it to loop back to the question at the beginning so a right choice can be entered. Also, how would I enter a print statement like "Invalid Choice Please Retry"?
package rps.gameapp;
import java.util.Scanner;
public class RPSGameApp
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String userChoice;
String playAgain;
int randNum = (int) (Math.random() * 3);
do
{
System.out.println("Welcome to Rock, Paper, Scissors Game.");
System.out.println("Pick R, P, or S.");
userChoice = sc.nextLine();
while (!userChoice.equalsIgnoreCase("P")
&& !userChoice.equalsIgnoreCase("R")
&& !userChoice.equalsIgnoreCase("S"));
String compChoice = "";
switch (randNum)
{
case 0:
compChoice = "R";
break;
case 1:
compChoice = "P";
break;
case 2:
compChoice = "S";
break;
}
System.out.println("The computer entered \"" + compChoice + "\".");
if (compChoice.equalsIgnoreCase(userChoice))
{
System.out.println("Draw");
} else if (userChoice.equalsIgnoreCase(userChoice)
&& compChoice.equalsIgnoreCase("S")
|| userChoice.equalsIgnoreCase("P")
&& compChoice.equalsIgnoreCase("R")
|| userChoice.equalsIgnoreCase("S")
&& compChoice.equalsIgnoreCase("P"))
{
System.out.println("User Wins");
} else
{
System.out.println("User Loses");
}
System.out.print(
"Do you want to play again? (Y/N)");
playAgain = sc.nextLine();
} while (playAgain.equalsIgnoreCase("Y"));
System.out.println("Thanks for Playing!");
}
}
It looks like you forgot one do for your inner do while loop.
It should be :
do {
do {
System.out.println("Welcome to Rock, Paper, Scissors Game.");
System.out.println("Pick R, P, or S.");
userChoice = sc.nextLine();
} while (!userChoice.equalsIgnoreCase("P") && !userChoice.equalsIgnoreCase("R") && !userChoice.equalsIgnoreCase("S"));
...
} while (playAgain.equalsIgnoreCase("Y"));
Without that inner do (and the curly braces surrounding that loop's body), the inner loop becomes a while loop with an empty body.
Like Eran said, you need to wrap your do-while loop in another loop, that will keep asking user for correct input. This is fully working code. One thing that could be better is the message after user inputs wrong letter.
Edit: also make sure you draw random number for every iteration.
Edit 2: to change the message depending on user input you can introduce a new variable that will keep the track of number of times you asked user for correct input. If it is 0- it means user is asked the first time and we should print "Welcome" message. It is anything other than 0- you need to ask the user for correct input. After every round we assign zero to the variable again and the cycle repeats. I have implemented this change in the code. Note that this variable can also be a boolean.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String userChoice;
String playAgain;
int iterationNumber;
while (true) {
iterationNumber = 0;
do {
if (iterationNumber == 0) {
System.out.println("Welcome to Rock, Paper, Scissors Game.");
System.out.println("Pick R, P, or S.");
} else {
System.out.println("Please enter valid letter.");
System.out.println("Pick R, P, or S.");
}
iterationNumber++;
userChoice = sc.nextLine();
} while (!userChoice.equalsIgnoreCase("P")
&& !userChoice.equalsIgnoreCase("R")
&& !userChoice.equalsIgnoreCase("S"));
String compChoice = "";
int randNum = (int) (Math.random() * 3);
switch (randNum) {
case 0:
compChoice = "R";
break;
case 1:
compChoice = "P";
break;
case 2:
compChoice = "S";
break;
}
System.out.println("The computer entered \"" + compChoice + "\".");
if (compChoice.equalsIgnoreCase(userChoice)) {
System.out.println("Draw");
} else if (userChoice.equalsIgnoreCase("R")
&& compChoice.equalsIgnoreCase("S")
|| userChoice.equalsIgnoreCase("P")
&& compChoice.equalsIgnoreCase("R")
|| userChoice.equalsIgnoreCase("S")
&& compChoice.equalsIgnoreCase("P")) {
System.out.println("User Wins");
} else {
System.out.println("User Loses");
}
System.out.print(
"Do you want to play again? (Y/N)");
playAgain = sc.nextLine();
if (playAgain.equalsIgnoreCase("N")) {
break;
}
iterationNumber = 0;
}
System.out.println("Thanks for Playing!");
}
Wrote a roshambo program, ran it once, worked fine, ran it again and the following errors popped up:
RoShamBo!
Play Game
Show Score
Quit
1
Which do you choose?
Rock
Paper
Scissors
2
Which do you choose?
Rock
Paper
Scissors
Invalid Entry, Please Try Again.
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at RoShamBo.getUserChoice(RoShamBo.java:82)
at RoShamBo.winner(RoShamBo.java:112)
at RoShamBo.main(RoShamBo.java:27)
not sure on how to deal with these type of errors, this my first time using methods so i'm thinking it has to do with how I called each method? please help.
thanks in advance.
import java.util.Scanner;
public class RoShamBo
{
public static void main(String[] args)
{
System.out.println("RoShamBo!");
System.out.println("1. Play Game");
System.out.println("2. Show Score");
System.out.println("3. Quit");
Scanner userInput = new Scanner(System.in);
if(userInput.hasNextInt())
{
int userIn = userInput.nextInt();
if(userIn == 1)
{
getUserChoice();
getCompChoice();
winner();
}
else if(userIn == 2)
{
scores();
}
else if(userIn == 3)
{
System.out.println("Qutiing: Final Score was: ");
scores();
userInput.close();
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
userInput.next();
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
userInput.next();
}
}
public static String getUserChoice()
{
// ask player for a move : playerMove
System.out.println("Which do you choose?");
System.out.println("1. Rock");
System.out.println("2. Paper");
System.out.println("3. Scissors");
Scanner input = new Scanner(System.in);
String userChoice = " ";
if (input.hasNextInt())
{
int userInput = input.nextInt();
switch(userInput)
{
case 1:
userChoice = "Rock";
break;
case 2:
userChoice = "Paper";
break;
case 3:
userChoice = "Scissors";
break;
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
input.next();
}
input.close();
return userChoice;
}
private static String getCompChoice()
{
//Method for getting Computers move
int compChoice = (int) ( 1 + (Math.random() * 3));
String compMove = " ";
switch(compChoice)
{
case 1:
compMove = "Rock";
break;
case 2:
compMove = "Paper";
break;
case 3:
compMove = "Scissors";
break;
}
return compMove;
}
public static String winner()
{
String winnerIs = " ";
String comp = getCompChoice();
String user = getUserChoice();
if(user.equals("Rock") && comp.equals("Scissors") ||
user.equals("Paper") && comp.equals("Rock") ||
user.equals("Scissors") && comp.equals("Paper"))
{
System.out.println("You Win!");
}
else
{
System.out.println("You Lose");
}
return winnerIs;
}
public static void scores()
{
int compCount = 0;
int userCount = 0;
if (winner().equals("You Win!"))
{
userCount++;
}
else
{
compCount++;
}
System.out.println("Player = " + userCount );
System.out.println("Computer = " + compCount );
}
}
Probably here
{
System.out.println("Invalid Entry, Please Try Again.");
input.next();
}
you are doing a next() without checking for has*().
Your stack gives one hint.
at java.util.Scanner.next(Unknown Source).
and
Exception in thread "main" java.util.NoSuchElementException
Turning to the documentation here:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#next%28%29
part that is of interest to you:
Throws:
NoSuchElementException - if no more tokens are available
You call .next()
but what do you want to read? Is there anything waiting in input buffer? Also, see my comment, meaning that your logic is busted.Rethink your game logic instead of fixing it.
Giving a complete answer that gets your code to run like it's supposed to would mean writing most of your code, I won't go that way. Instead, you should apply one of the most powerful debugging methods known to humans and do it yourself:
https://en.wikipedia.org/wiki/Rubber_duck_debugging
Good luck and enjoy ;)
Ok, so I have programmed a simple rock paper scissors game using user input to play. The user types their choice, a random function chooses the computers go and then a result is produced. After this the program is terminated because it has finished. I want to use a while loop so that when the game is finished, it starts again, and then the program will stop if the user types in exit or quit, which can easily be done by just saying something like while playerGo != exit, play the game blah blah. However, I cannot get this to work, can someone help me please, I'm a Java noob :)
import java.util.Scanner;
public class RockPaperScissors{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int compGoInt;
String compGo;
String playerGo;
System.out.println("You can type 'Exit' to quit the game at any time.");
System.out.print("Please enter your choice. Rock, Paper or Scissors: ");
playerGo = input.nextLine();
compGoInt = (int) (Math.random() * 3);
switch (compGoInt){
case 0:
compGo = "Rock";
break;
case 1:
compGo = "Paper";
break;
case 2:
compGo = "Scissors";
break;
default:
compGo = "Error";
System.out.println("Error.");
break;
}
if (playerGo.equals(compGo)){
System.out.println("Computer chooses "+compGo);
System.out.println("It's a draw!");
}
else if ((playerGo.equalsIgnoreCase("Rock") && compGo.equalsIgnoreCase("Scissors")) ||
(playerGo.equalsIgnoreCase("Paper") && compGo.equalsIgnoreCase("Rock")) ||
(playerGo.equalsIgnoreCase("Scissors") && compGo.equalsIgnoreCase("Paper"))){
System.out.println("Computer chooses "+compGo);
System.out.println("Player Wins!");
}
else if ((compGo.equalsIgnoreCase("Rock") && playerGo.equalsIgnoreCase("Scissors")) ||
(compGo.equalsIgnoreCase("Paper") && playerGo.equalsIgnoreCase("Rock")) ||
(compGo.equalsIgnoreCase("Scissors") && playerGo.equalsIgnoreCase("Paper"))){
System.out.println("Computer chooses "+compGo);
System.out.println("Computer Wins!");
}
else{
System.out.println("Something has gone wrong!");
System.out.println("Player chose "+playerGo);
System.out.println("Computer chose "+compGo);
}
}
}
Simply put:
while(true) {
if(playerGo.equalsIgnoreCase("Exit")) break;
else //GameLogic
}
Though, if I may say so, you should have the user choose a number, since any letter input is prone to errors.
For clarification purposes:
import java.util.Scanner;
public class RockPaperScissors{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int compGoInt;
String compGo;
String playerGo;
while(true) {
System.out.println("You can type 'Exit' to quit the game at any time.");
System.out.print("Please enter your choice. Rock, Paper or Scissors: ");
playerGo = input.nextLine();
if(playerGo.equalsIgnoreCase("Exit")) break; //Checks for exit condition.
else { //GameLogic
compGoInt = (int) (Math.random() * 3);
switch (compGoInt){
case 0:
compGo = "Rock";
break;
case 1:
compGo = "Paper";
break;
case 2:
compGo = "Scissors";
break;
default:
compGo = "Error";
System.out.println("Error.");
break;
}
if (playerGo.equals(compGo)){
System.out.println("Computer chooses "+compGo);
System.out.println("It's a draw!");
}
else if ((playerGo.equalsIgnoreCase("Rock") && compGo.equalsIgnoreCase("Scissors")) ||
(playerGo.equalsIgnoreCase("Paper") && compGo.equalsIgnoreCase("Rock")) ||
(playerGo.equalsIgnoreCase("Scissors") && compGo.equalsIgnoreCase("Paper"))){
System.out.println("Computer chooses "+compGo);
System.out.println("Player Wins!");
}
else if ((compGo.equalsIgnoreCase("Rock") && playerGo.equalsIgnoreCase("Scissors")) ||
(compGo.equalsIgnoreCase("Paper") && playerGo.equalsIgnoreCase("Rock")) ||
(compGo.equalsIgnoreCase("Scissors") && playerGo.equalsIgnoreCase("Paper"))){
System.out.println("Computer chooses "+compGo);
System.out.println("Computer Wins!");
}
else{
System.out.println("Something has gone wrong!");
System.out.println("Player chose "+playerGo);
System.out.println("Computer chose "+compGo);
}
}
}
}
}
You can add a boolean variable IsGameRunning = true.
wrap the whole login in a while loop that checks the state of IsGameRunning.
Add a case to the switch statement that checks for user input "-1", and when the user enters "-1" as input the case changes IsGameRunning variable to false.
Simple and should work
boolean running = true;
do{
System.out.println("You can type 'Exit' to quit the game at any time.");
System.out.print("Please enter your choice. Rock, Paper or Scissors: ");
playerGo = input.nextLine();
running = !(playerGo.equalsIgnoreCase('Exit') || playerGo.equalsIgnoreCase('Quit'));
if(running){
//logic
compGoInt = (int) (Math.random() * 3);
...
}
}while(running)
do while -> input needs to be asked at least once.
and for
if (playerGo.equals(compGo)){
System.out.println("Computer chooses "+compGo);
System.out.println("It's a draw!");
}
playerGo.equals(compGo) -> playerGo.equalsIgnoreCase(compGo) like the rest of your code