Looping a 2 player rock paper scissors game (Java) - java

im trying to create a 2 player rock paper scissors game with a prompt to continue or end the game. and also re-ask for your move if entered incorrectly. i've been trying to use do-while loops but i get an error every time.
it doesn't recognize the do-while i put in, because it's not reading the while(playAgain.equals("Y");
let me know what i can fix and where i should start my do and start my while. thanks!
import java.util.Scanner;
public class RPS {
public static void main(String[] args) {
//player one input
Scanner in = new Scanner(System.in);
//loop start?
do {
System.out.println("Player One, please enter your move [R/P/S]: ");
String playerOne = in.nextLine();
//verify move is valid
if (!playerOne.equals("R") && !playerOne.equals("P") && !playerOne.equals("S")) {
System.out.println("Invalid input, please enter valid move.");
} else {
//player two input
System.out.println("Player Two, please enter your move [R/P/S]: ");
String playerTwo = in.nextLine();
//verify move is valid
if (!playerTwo.equals("R") && !playerTwo.equals("P") && !playerTwo.equals("S")) {
System.out.println("Invalid input, please enter valid move.");
}
//game outcome
if (playerOne.equals(playerTwo)) {
System.out.println("You tied!");
} else if (
(playerOne.equals("R") && playerTwo.equals("S")) ||
(playerOne.equals("S") && playerTwo.equals("P")) ||
(playerOne.equals("P") && playerTwo.equals("R"))) {
System.out.println("Player One has won!");
} else if (
(playerTwo.equals("R") && playerOne.equals("S")) ||
(playerTwo.equals("S") && playerOne.equals("P")) ||
(playerTwo.equals("P") && playerOne.equals("R"))) {
System.out.println("Player Two has won!");
}}}//loop end?
while (playAgain.equals("Y"));
//prompt user to play again
System.out.println("Would you like to play again? [Y/N]");
String playAgain = in.nextLine();
if (playAgain.equals("N")) {
System.out.println("Game stopped. Thanks for playing!");
}
if (!playAgain.equals("Y") && !playAgain.equals("N")) {
System.out.println("Invalid input, please enter valid response.");
}}}

I will look further, though to improve readability|simplify logic
if (!playerOne.equals("R") && !playerOne.equals("P") && !playerOne.equals("S"))
is the same as
if (!((playerOne.equals("R") || playerOne.equals("P") || playerOne.equals("S")))
EDIT: In your logic, I don't see a case for asking the player again. This can/will lead to a logic hole.
bool inPlay = true;
while(inPlay)
{
...
if(valid plays)
{
if(tie) print tie;
else if(p1 wins) print player1;
else if(p2 wins) print player2;
inPlay = ask: want to play again?
}else
{
tell them it is invalid, loop again;
}
...
}
^This will allow you to ask again
EDIT 2: for a do-while, it is essentially the same deal:
bool inPlay = true;
do
{
above logic;
}while(inPlay);
EDIT 3: With your most recent version I see a vital flaw here:
do
{
...
}
while (playAgain.equals("Y"));//<-- semicolon
//prompt user to play again
System.out.println("Would you like to play again? [Y/N]");
...
You can't go back to the start of the do-while loop with that prompt after the semicolon ; has been reached. You need to ask that question within the curly brackets {} after the game has been finished.
EDIT 4: to expand on OP's "I'm getting an error that my playAgain variable is not initialized even when I add String playAgain;"
String playAgain = "";
do
{
...
playAgain = their answer;
...
}while(playAgain.equals("Y"));
However, I don't think you need to keep the String outside the scope of the loop, a boolean is all you need, and a boolean is easier to read. So perhaps:
//See EDIT 2 above
...
// will result in true for Y and false for !Y
playAgain = (answer == 'Y')
...

Related

Basic Java HiLow guessing game

I am fully aware this question has been asked many times, it is a classic first year problem in CSC. I am not looking for the solution to the problem itself. I think I have it basically done however I am missing something that I cannot find how to do.
Here is my code:
import java.util.Scanner;
import java.util.Random;
public class HiLow
{
public static void main (String[] args)
{
Random generator = new Random();
Scanner scan = new Scanner(System.in);
int num1,guess;
int count = 0;
num1 = generator.nextInt(100) + 1;
while(true) {
System.out.print("Enter an integer between 1 or 100 or enter 0 at anytime to quit: ");
guess = scan.nextInt();
count++;
if(guess == num1 || guess == 0) {
if(guess == 0) {
System.out.println("Thanks for playing");
break;
}
System.out.println("Congrats you've guessed correct and your total guesses is " + count );
break;
}
else if (guess > 100 || guess < 1) {
System.out.print("I see you cannot follow instructions. I said ");
count--;
}
else if (guess > num1) {
System.out.println("You have guessed too high. ");
}
else {
System.out.println("You have guessed too low.");
}
}
}
}
My problem is i am required to prompt the user at the point of "if the user quits or successfully guesses the correct number, prompt the user to see if they wish to play again". I am lost and not sure how to continue my while loop from the beginning after my breaks. Is there a way to end the break condition i have from (guess == num1 || guess ==0) and direct my program to start again at the while(true) statement?
Thanks
I will say search up continue;
Tips to help further:
The continue statement is used to bring the loop back to the start, try it instead of a break where you want the user to continue.
You need some sort of check if the user wants to continue, (try asking them to type in some specific int you check, p.s negative numbers are integers as well)
#Ahmed thinks you should continue, I would rather not break, or conditionally break.
Well there are multiple ways you could accomplish this, One would be to just to prompt the user with a "press q to quit" dialogue using the Scanner class where .next() returns the String when the user hits enter:
if(guess == num1 || guess == 0) {
if(guess == 0) {
System.out.println("Thanks for playing");
}else{
System.out.println("Congrats you've guessed correct and your total guesses is " + count );
}
System.out.println("would you like to play again [y/n]?");
if(scan.next().equals("y")){
num1 = generator.nextInt(100) + 1;
count=0;
}else{
break;
}
}
If thats what you mean. Hopefully I helped.
or maybe you can have it only quit at zero, if so just remove that second break and replace it with num1 = generator.nextInt(100) + 1; to set the new value to guess.

I can't figure out how to restart a loop, when the person enters in a wrong input

Ok so for an assignment I need to make a loop for the user to input a number 1-4 for either rock paper scissors or to end the game, but if they enter in anything other than those I need them to be able to re-enter the number but I can't seem to get my loop to restart or something similar...
Code (It's just my while loop
while(user < 5)
{
System.out.println("Please enter in a number");
computer = generator.nextInt(3) + 1;
user = keyboardIn.nextInt();
//tell the player what was chosen
if(user == 1)//player is rock
{
System.out.println ("Player is rock");
}
else if (user == 2)//player is paper
{
System.out.println ("Player is paper");
}
else if (user == 3) //player is scissors
{
System.out.println ("Player is scissors");
}
else if (user == 4)
{
System.out.println("Thank you for playing!");
break;
}
else if (user >= 5)
{
System.out.println(user + " was never an option. \nTry again.");
user = keyboardIn.nextInt();
}
//tell the player what the computer has chosen
if(computer == 1)//computer is rock
{
System.out.println ("Computer is rock");
}
else if (computer == 2)//computer is paper
{
System.out.println ("Computer is paper");
}
else if (computer == 3)//computer is scissors
{
System.out.println ("Computer is scissors");
}
//determine winner
if (user == computer) //tie
{
System.out.println("It is a tie");
}
else if (user < computer) //player is rock
{
System.out.println("Computer wins");
}
else //computer is scissors
{
System.out.println("Player wins");
}
System.out.println();
}
You can use continue to jump back to the top of the loop. Note, however, that at the top you ask for user input, and on error you do so too; that's one time too many.
You could use
boolean gameOver = false;
while(!gameOver){
if (user < 5){
....
}
}
and set gameOver = true in each of your game-ending conditions.
Replace the part:
else if (user >= 5)
{
System.out.println(user + " was never an option. \nTry again.");
user = keyboardIn.nextInt();
}
With:
else if (user >= 5)
{
System.out.println(user + " was never an option. \nTry again.");
continue;
}
Basically the continue, brakes the current loop and start over a new one, of course verifying first the condition...
However if you want your code to be a little bit more efficient, in your specific case this would be my way of doing it:
while(true) {
computer = generator.nextInt(3) + 1;
do {
System.out.println("Please enter in a number");
user = keyboardIn.nextInt();
} while(user>=5 && user<=0);
//The rest of your code deleting also the last else if statement
}
This way your code is cleaner and more maintainable. Plus you will be sure that after the code exit from the loop you will definitely have a number between 0 and 4 which would be a valid option

While loop NoSuchElementException integer input java

I'm having some trouble with a menu program I am writing for my java class. After one program is run, when the program goes to do a second loop it throws a NoSuchElementException on the line where it is supposed to take the user's input for the next program they want to run. I'm assuming it has something to do with the scanner getting messed up but I can't find the issue. Anyone have any ideas?
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
String pin;
int selection = 0;
boolean valid = false;
do {
System.out.print("Please enter the password: ");
pin = console.nextLine();
valid = checkPassword(pin);
} while (!valid);
while (selection != 4 && valid == true) {
System.out.printf("%nPlease select a number from the menu below %n1: Wage "
+ "Calculator 2: Tip Calculator 3: Grocery Discount 4: Exit %n");
selection = console.nextInt();
if (selection == 1) {
calc_wages();
} else if (selection == 2) {
calc_tip();
} else if (selection == 3) {
System.out.print("We haven't gotten this far yet");
} else if (selection == 4){
System.out.print("Thank you for using the program.");
break;
} else {
System.out.print("There is no option for what you entered. Try again");
}
selection = 0;
}
}//main
Your code so far is fine.
From what you're saying the problem starts after the user makes a selection.
In calc_wages() and/or calc_tip() it's possible that you use another Scanner object to get the user's input.
This is a source of problems.
Declare 1 Scanner object at the class level and use it throughout you code and close it only when it is no longer needed.

Need to get the entire thing in a loop, which loop is best suited? Where should I apply it?

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.");
}
}
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.
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.
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.
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.

String input doesn't work in if-else statement

I'm new to Java, and I created some sort of a mini game, and I wanted players to choose whether or not they want to play again, I tried changing my start boolean variable into static type and adding some lines of code, but the code doesn't seem to work, every time I play the game, it did ask me if I want to replay or not, but the problem is that even though I typed "yes" to the console at the end, the game doesn't seem to restart. Can anyone help me please, I would be really appreciated, thanks!
import java.util.Random;
import java.util.Scanner;
//Rocks, papers, scissors game complied by William To.
public class RockPaperScissor {
static int gamePlays = 0;
static boolean start = true;
public static void main(String[] args) {
while (start){
#SuppressWarnings("resource")
Scanner userInput = new Scanner(System.in);
Random comOutput = new Random();
System.out.println("Do you choose rock, paper or scissor?");
String userChoice = userInput.nextLine();
int comChoice = comOutput.nextInt(2);
switch (userChoice){
case "rock":
if(comChoice == 0){
System.out.println("I choose rock too! That's a draw!");
} else if(comChoice == 1){
System.out.println("I choose paper! I win!");
} else {
System.out.println("I choose scissor! You win!");
}
break;
case "paper":
if(comChoice == 0){
System.out.println("I choose rock! You win!");
} else if(comChoice == 1){
System.out.println("I choose paper too! That's a draw!");
} else {
System.out.println("I choose scissor! I win!");
}
break;
case "scissor":
if(comChoice == 0){
System.out.println("I choose rock! I win!");
} else if(comChoice == 1){
System.out.println("I choose paper! You win!");
} else {
System.out.println("I choose scissor too! That's a draw!");
}
break;
default :
System.out.println("I don't think that's an option.");
break;
}
gamePlays++;
System.out.println("You've played " + gamePlays + " games.");
//BELOW IS THE PART I want to ask, what's wrong?
System.out.println("Do you want to play again?");
String playAgain = userInput.next();
if (playAgain == "yes"){
System.out.println("Restarting game...");
start = true;
} else if (playAgain == "no") {
System.out.println("Quitting game.");
start = false;
}
}
}
}
The print out from Eclipse:
Do you choose rock, paper or scissor?
rock **//my input**
I choose paper! I win!
You've played 1 games.
Do you want to play again?
yes **//my input**
Do you choose rock, paper or scissor?
paper **//my input**
I choose paper too! That's a draw!
You've played 2 games.
Do you want to play again?
no **//my input**
Do you choose rock, paper or scissor?
Comparison between strings needs the String#equals instead of ==. So this:
if (playAgain == "yes"){
System.out.println("Restarting game...");
start = true;
} else if (playAgain == "no") {
System.out.println("Quitting game.");
start = false;
}
Has to become this:
if (playAgain.equals("yes")){
System.out.println("Restarting game...");
start = true;
} else if (playAgain.equals("no")) {
System.out.println("Quitting game.");
start = false;
}
In order to work properly.
However, I suggest to use String#equalsIgnoreCase, because with equals, the comparison is case-sensitive, so if user inputs i.e. Yes or yEs, playAgain.equals("yes") will return false
UPDATE
As Maroun Maroun says, it is better to use
"yes".equals(playAgain)
and
"no".equals(playAgain)
Because if playAgain is null it won't throw a NullPointerException
Try:
if ("yes".equals(playAgain)) {
System.out.println("Restarting game...");
start = true;
} else if ("no".equals(playAgain)) {
System.out.println("Quitting game.");
start = false;
}
String#equals() checks the character equality of string, == checks memory reference.
The problem is probably this line
if (playAgain == "yes")
(and the one later for no).
Strings in Java are objects. This means that two strings might have the same content, i.e. contain the same text, but still not be "the same" as far as == is concerned. To compare two strings and see if they contain the same text, use this:
if (playAgain.equals("yes"))
Problem is with the way in which String comparision is done.
playAgain == "yes", This check will check for object equality.
However in this case, value of object needs to be compared, following code will work for you.
playAgain.equals("yes")
You need compare string using String.equals() method and not ==
The equals method compares for the value of the string and == checks whether both the objects refer to the same same object or not.

Categories

Resources