Repeat a loop already satisfied in java - java

I'm looking to repeat a "game" if it is already satisfied in my case where user has to guess the random number. I can't understand where to to get back to the main game unless i have to create another "do - while" loop inside it and retype the game again in the section where it says: System.out.println("you have tried: " + count + " times. Would you like to play again? y/n"). Is there a way to just bring back to the actual guess loop rather than create another one?
Hopefully makes sense.
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class pass {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String pass = "password123";
String input;
int guess;
int count;
count = 0;
int num;
do {
System.out.print("Enter your password: ");
input = scanner.next();
} while (!input.equals(pass));
System.out.println("Correct! Now play the guess game! Guess a number between 1 - 10.");
do {
num = ThreadLocalRandom.current().nextInt(1,10);
guess = scanner.nextInt();
count++;
if (guess == num) {
System.out.println(" Well done!");
**System.out.println("you have tried: " + count + " times. Would you like to play again? y/n");**
}
else if (guess < num) {
System.out.println("your number is smaller than the number given");
}
else {
System.out.println("your guess is too high");
}
} while (guess != num);
}
}

The simplest solution would be to move the entire "guess loop" into a separate method. Then in the case when you want it to repeat, just call the method recursively.

If you want to reuse code you can make functions (or methods here, because we are inside a class). They can be used to encapsulate code and call it from anywhere to use it.
You can define a methods like that:
public static void methodName() {
// code go here
}
Then, you can call it from anywhere like that :
pass.methodName(); // It will execute the code inside methodName()
In reality, this is a lot more complex than that, you can give methods values and return others, change the scope of it to make it internal only or reachable by other classes. But I presume that you are a beginner so I keep it simple. I strongly recommend you to make a quick research about Object Oriented Programmation!
For your code, you can put the game's while loop in a method and call it at the beginning and each time the player wants to restart the game. Good luck with your game!

I manage to do this way. It seems working but one thing is letting me down at the very last when I key in "n" or other key than "y". Exception in thread "main" java.util.InputMismatchException. Is there a more softer way to finish it?
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class pass {
public static void randomnum(){
Scanner scanner = new Scanner(System.in);
int guess;
int count;
count = 0;
int num;
do {
num = ThreadLocalRandom.current().nextInt(1,10);
guess = scanner.nextInt();
count++;
if (guess == num) {
System.out.println(" Well done!");
System.out.println("you have tried: " + count + " times.");
String answer;
do{
System.out.println("Do you want to play again? y/n");
answer = scanner.next();
if (answer.equals("y")) {
System.out.println("let's play again");
randomnum();
System.out.println("Correct! Now play the guess game! Guess a number between 1 - 10.");
}
else {
System.out.println("you are logout!");
break;
}
}while (answer.equals("Y"));
randomnum();
}
else if (guess < num) {
System.out.println("your number is smaller than the number given");
}
else {
System.out.println("your guess is too high");
}
} while (guess != num);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String pass = "password123";
String input;
do {
System.out.print("Enter your password: ");
input = scanner.next();
} while (!input.equals(pass));
System.out.println("Correct! Now play the guess game! Guess a number between 1 - 10.");
randomnum();
}
}

Related

"Guess My Number" game with only allow 3 guesses from user

I've created many different types of method in my coding as my task requires to, so I faced some problems that I'm trying to incorporate loops that allow only 3 guesses from the user. After each round, the user has the option of whether to continue playing or to stop. How should I implement that? Also, any mistakes in my coding? Thank you in advanced!
import java.util.Random;
import java.util.Scanner;
public class GuessmyGame{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
Random random = new Random();
int number = random.nextInt(100)+1;
printInstruction();
int guess = in.nextInt();
guessNum(number, guess);
numberOfTries(guessNum);
}
public static void printInstruction(){
System.out.println(" I am thinking of a number between 1 and 100.");
System.out.println(" Can you guess what it is? ");
System.out.println(" Type a number : ");
}
public static void guessNum(int number, int guess){
if (number == guess){
System.out.println("Congratulations! You got it right.");
}
else if(number > guess){
System.out.println("Your guess is too low.");
Scanner in = new Scanner(System.in);
guess = in.nextInt();
System.out.println("Your guess is: "+guess);
guessNum(number, guess);
}
else{
System.out.println( "Your guess is too high.");
Scanner in = new Scanner(System.in);
guess = in.nextInt();
System.out.println("Your guess is: "+guess);
guessNum(number, guess);
}
}
public static void numberOfTries(int guessNum){
Random random = new Random();
int number = random.nextInt(100)+1;
for(int i = 0; i < 3; i++){
System.out.println("Out of guesses!");
System.out.println("The number was " + number);
}
}
}
Use a while loop and add a boolean condition.. let's call it canContinue. You'll also need to keep track of how many times the user has attempted to guess, let's say it's called attemptCount as well as the correctness of the user's latest guess (correctGuess).
When attemptCount is 3 or correctGuess is true, prompt the user if they want to continue. If their answer suggests they don't want to continue, set canContinue to false, which causes the exit the loop and complete. Otherwise, reset attemptCount (to 0 presumably to allow another 3 attempts). The code that follows highlights the requested logic. since it's clear the code provided in the question has many bugs.
var promptToRetry = false;
while (canContinue) {
if (correctGuess) {
// Let user know their guess was correct
promptToRetry = true;
}
if (attemptCount > 2) {
// Let user know they didn't get the right number
promptToRetry = true;
}
if (promptToRetry) {
boolean wantsToTryAgain = PromptUserToTryAgain(); //Code returning bool which prompts user if they want to try again (need to implement)
if (wantsToTryAgain) {
attemptCount = 0; //Resets attempt counter
correctGuess = false; //Resets the guess
promptToRetry = false;
} else {
canContinue = false; //Causes loop to exit
}
}
...
}
}

Java scanner input loop throwing No Such Element exception after first loop

I want a program that repeatedly prompts the user to input a number and then prints whether that number is prime or not. This works once, then on the next iteration it gives a No Such Element Exception before the user can enter another input.
I've tried using IF statements with hasNext() or hasNextInt() but those never seem to be true for the same reason. I also tried using a FOR loop to iterate a fixed number of times but that gives the same error. Why is this allowing for user input the first time it loops through but not after that?
public static void primeChecker()
{
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a number: ");
int number = scan.nextInt();
if (isPrime(number)) {
System.out.println(number + " is prime");
}
else {
System.out.println(number + " is not prime");
}
scan.close();
}
public static void main(String[] args)
{
int y=1;
while(y!=0)
{
primeChecker();
}
Remove scan.close();, as it is closing the scanner.
In order to repeatedly ask the user for a number without stopping, you need to put a while around the code.
Here is my take on this challenge:
public static void primeChecker() {
while(true) {
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a number: ");
int number = scan.nextInt();
if (isPrime(number)) {
System.out.println(number + " is prime");
} else {
System.out.println(number + " is not prime");
}
}
}
public static void main(String[] args) {
primeChecker();
}
This code should repeatedly ask you for a number(after telling you what the previous answer was). It worked for me!
First of all what does your local variable have to do with the function? even if you pass it to function it won't change.
by looking at your code one thing you can do is safely remove y it has nothing to with it, and check in prime checker if number is equal to 0 System.exit(), this is one way to do it without changing much of this code.
while (true) {
primeChecker();
}
and inside primeChecker
int number = scanner.nextInt();
if (number == 0) {
System.exit(0);
}
it will terminate the programme when input is 0.
here you can learn more about System.exit:- https://www.baeldung.com/java-system-exit

How to get scanner input to not trigger third method?

I'm working on an assignment and I mostly have it finished but I am having an issue with the last method. I'm trying to write a continueGame() method that will ask the user if they want to continue to play, and accept "y" or "n". If answered "y", the program starts again. If answered "n", the program stops and a message is shown. The problem is I need it to trigger the continueGame() method only when userChoice == answer. This is a number guessing game with an object oriented approach.
I've tried to call the continueGame() method inside my else if(userChoice == answer) statement but it doesn't seem to work. Even when my other if/else if statements are triggered, it continues to the continueGame() method.
Here is the main driver for the game
import java.util.Scanner;
public class NumberGame
{
public static void main(String[] args)
{
Scanner input = new Scanner (System.in);
GameOptions opt = new GameOptions(); // Your created class
int userChoice = -1234;
int answer = -1234;
boolean keepPlaying = true;
System.out.println("Guess the Number Game\n");
while (keepPlaying == true) {
answer = (int) (Math.random() * 10)+1;
//Create a getChoice method in your class and make sure it accepts a Scanner argument
userChoice = opt.getChoice(input);
//Create a checkAnswer method in your class. Make sure it accepts two integer arguments and a Scanner argument
opt.checkAnswer(userChoice, answer, input);
// Create a continueGame method in your class and make sure it accepts a Scanner argument
keepPlaying = opt.continueGame(input);
}
System.out.println("Thanks for playing.");
}
}
Here is the class that I am working on for the methods. Note that I can not make any modifications to the main driver file.
import java.util.InputMismatchException;
import java.util.Scanner;
import java.lang.NumberFormatException;
public class GameOptions {
int count = 0;
boolean cont = true;
//getChoice Method for NumberGame
public int getChoice(Scanner scnr) {
System.out.println("Please choose a number between 1 and 10: ");
int userGuess = 0;
String input = scnr.next();
try {
userGuess = Integer.parseInt(input);
if (userGuess < 1 || userGuess > 10) {
throw new IllegalArgumentException("Invalid value. Please enter a number between 1 and 10: ");
}
}
catch(NumberFormatException e) {
System.out.println("Error - Enter Numerical Values Only");
return userGuess;
}
catch (IllegalArgumentException ex) {
System.out.println(ex.getMessage());
}
return Integer.parseInt(input);
}
public void checkAnswer(int userChoice, int answer, Scanner scnr) {
if (userChoice > answer && userChoice < 11) {
System.out.println("Too high. Try again.");
count++;
} else if (userChoice < answer && userChoice > 0) {
System.out.println("Too low. Try again.");
count++;
} else if (userChoice == answer) {
System.out.println("You got it! Number of tries: " + count);
System.out.println("Would you like to play again? (y/n)");
}
}
public static boolean continueGame(Scanner scnr) {
String input = scnr.nextLine();
if (input.toLowerCase().equals("y")){
return true;
} else if (input.toLowerCase().equals("n")){
return false;
} else {
System.out.println("Invalid entry. Please enter either y or n: ");
return continueGame(scnr);
}
}
}
So I should be able to enter a number, and if its lower than the answer it will tell me I am too low, if its higher than the answer it will tell me that its too high, if its equal it will tell me I won and prompt me to press "y" or "n" if I want to continue. Another issue I am running into is that I am getting "Would you like to play again? (y/n)" no matter whether I guess the right number or not and my only option is to hit "y" or "n"
The driver class is calling continueGame() inside the while loop. If you're not allowed to modify that class then presumably asking at every iteration is the intended behaviour.
You should move System.out.println("Would you like to play again? (y/n)"); into the continueGame() method so that it only asks when that method is called.
The way the driver is written (I guess) is coming from your instructor/lecturer/professor, right?
With the driver (as it is), you don't need to call continueGame method from checkAnswer method. The driver is going to call it.
Just run the driver and it will work. If you have a proper IDE (eclipse or Netbeans), trace through and see what the input accepted is (I think there is line-feed in the accepted answer).
Try this (I just changed the loop structure; yours is also valid):
public static boolean continueGame(Scanner scnr) {
while (true) {
String input = scnr.nextLine().trim(); // to remove white spaces and line-feed
if (input.toLowerCase().equals("y")){
return true;
} else if (input.toLowerCase().equals("n")){
return false;
} else {
System.out.println("Invalid entry. Please enter either y or n: ");
}
}
}
Added for checkAnswer method to keep the user guess the answer until he gets correct:
public static checkAnswer(/*three arguments*/) {
boolean correct = false;
while (! correct) {
// accept input
if (answer.equals(input)) {
correct = true;
// print required correct/congrats messages here
} else {
// print required input/try again messages here
}
}
// print would you like to play again with new answer y/n message here.
}
In my opinion, printing "play again with new answer y/n message" should go into continueGame method (from last portion of checkAnswer) method to stick to encapsulation concepts.

Guessing game adding a method

I need to add a method to my guessing game that i made a while ago. The method should return the value they enter but should use a loop to require re-entry until one of those two values has been specified.
Also if the user inputs a word and not an int, it should ask for a number. I know that I will need to use a string instead of an int. I'm just having trouble figuring this out. Here is what I have so far:
import java.util.Random;
import java.util.Scanner;
class GuessNumber {
static Random rand = new Random();
static Scanner scan = new Scanner(System.in);
static int number;
public static void main(String[] args) {
playGame();
}
public static void playGame() {
number = rand.nextInt(100) + 1;
System.out.println("Guess the number between 1 and 100");
while (true) {
int guess = scan.nextInt();
if (guess < number) {
System.out.println("Higher!");
} else if (guess > number) {
System.out.println("Lower!");
} else if (guess == number) {
System.out.println("Correct!");
Scanner scan2 = new Scanner(System.in);
System.out.println("do you wanna play again?[Y/N]");
String val = scan2.next();
if (val.equalsIgnoreCase("Y")) {
playGame();
} else {
break;
}
}
}
}
}
There might be a better way to do it but try something along the lines of:
String input = scan.next();
int guess;
try{
guess = Integer.parseInt(input);
//rest of the code inside while(true) loop
}
catch(Exception e){
System.out.println("You need to enter a valid number.");
}
and then for the Y/N validation:
String val = "No";
Scanner scan2 = new Scanner(System.in);
do{
System.out.println("do you wanna play again?[Y/N]");
val = scan2.next();
}
while(!val.equalsIgnoreCase("Y") && !val.equalsIgnoreCase("N"))
if (val.equalsIgnoreCase("Y")) {
playGame();
break;
} else {
break;
}
Reasoning: You will get an error if they do not enter a valid number so you need to catch the error and let them know what is wrong. I like to get input as string and try to convert it to integers. As for the do/while section... Unless they enter Y or N it will keep asking them. Once out of the loop, if the input was "Y" it will call the playGame() again and then break after it finishes (basically whenever the user types n in the next game). If it wasn't "Y" then it had to be "N" and needs to break.
Let me know if this helps. I have the full code that will work but this should be easy enough for you to implement.
When you declare your static variables, put:
static int number, guess;
To declare both numbers at the same time. Then, inside the main loop, do the following:
while (true) {
while (true) {
try {
guess = Integer.parseInt(scan.nextLine());
break;
} catch (Exception e) {
System.out.println("Not a valid number!");
continue;
}
}
//Rest of your if's, else if's, etc
}
I've tested it, and it works for me.
If you need me to I can paste in all the code, but you should be able to just nest that second while loop inside the first, before the if statements, easily enough.

If statement skipping right to else after being called once?

I'm making a simple coin toss game, and I wrote several methods to call and make my main class short and simple. After the game is played once, the first If/Else statement to ask users for input is jumping right to the Else statement without prompting for input.
package cointoss;
import java.util.Random;
import java.util.Scanner;
public class Game {
int money;
int result;
int bet;
Random rn = new Random();
Scanner in = new Scanner(System.in);
String playerPick;
String aResult;
public void setMoney(int a)
{
money = a;
}
public int getMoney()
{
return money;
}
public void getBet()
{
System.out.println("How much would you like to bet?");
bet = in.nextInt();
do{
if(bet > money)
{
System.out.println("You cannot bet more than you have!");
System.out.println("You have bet " + (bet - money) + " too many coins.");
continue;
}
else
System.out.println("You have bet " + bet + " coins.");
}
while(bet > money);
}
public void getInput()
{
System.out.println("Pick Heads or Tails");
playerPick = in.nextLine();
playerPick.toLowerCase();
if(playerPick.contains("heads"))
playerPick ="heads";
else if(playerPick.contains("tails"))
playerPick ="tails";
else
System.out.println("Invalid Selection");
}
public void flipCoin()
{
result = rn.nextInt(2);
if(result == 0)
{
aResult = "heads";
}
else
aResult = "tails";
}
public void checkResult()
{
if(playerPick.equals(aResult))
{
System.out.println("You have won!");
money += bet;
System.out.println("You now have " + money + " coins");
}
else{
System.out.println("You have lost!");
money -= bet;
System.out.println("You now have " + money + " coins");
}
}
}
My Tester Class:
package cointoss;
public class GameTest {
public static void main(String[] args)
{
Game coinToss = new Game();
coinToss.setMoney(100);
while(coinToss.getMoney() > 0)
{
coinToss.getInput();
coinToss.getBet();
coinToss.flipCoin();
coinToss.checkResult();
}
}
}
The method toLowerCase() does not change the contents of the string; String is an immutable class in Java. The toLowerCase() method returns the result. You need to change
playerPick.toLowerCase();
to
playerPick = playerPick.toLowerCase();
Your problem is that you are not reinitializing "in" as a new Scanner every time you run the tester loop. The single scanner reads a line of input and accepts that as the full answer, without acknowledging that there could be further input.
The problem is that when the user enters a line, the input buffer will contain characters followed by a "newline" (end-of-line) character. When you use nextInt, the Scanner will find and skip over an integer. But it won't skip over the end-of-line. So when you next call nextLine in getInput(), it will then find what's left of the previous line, i.e. an empty string, and return that. Some things you'll need to do:
(1) In getBet, add in.nextLine() at the end of the method, to skip past the end-of-line. nextLine will return a string but you can ignore it. See also Scanner issue when using nextLine after nextXXX
(2) getInput needs to have a loop so that if the user enters an invalid input, you go back and ask him to enter a valid string. Otherwise, it will display "Invalid Selection" but then ask for a bet, which isn't what you want.
(3) See the other answers with regard to toLowerCase.
When you use
playerPick.toLowerCase();
It does nothing because the value is not being assigned to anything. In order to change a value of an object you must assign a value to it, as below:
playerPick = Pick.toLowerCase();
This assigns the value, rather than calling an empty method
Hope this helps :)

Categories