Well, as I look to your looping logic it could be maintained and working as charm, you just need to move the initialization steps from the outside, to the inside do-while loop, in the beginning.
That way, at each start of the game, everything will work.
Also you're forgetting to go to next line before reading the user choice of yes/no, as you were reading just ints, at the end your a line ahead of the line containing the verdict yes/no
I tried this code in an online compiler, and it's working :
import java.util.Scanner;
import java.util.Random;
public class Main{
public static void main(String []args){
Random random = new Random();
Scanner input = new Scanner(System.in);
final int MAX = 100;
System.out.println("Guess a number between 1 and " + MAX + ": ");
String cont = new String();
do {
System.out.println("Let's play");
//Initializations here
int answer = random.nextInt(MAX) + 1;
int guess = -1;
int numberOfGuesses = 0;
while (guess != answer) {
numberOfGuesses++;
guess = input.nextInt();
if (guess == 101) {
break;
} else if (guess > answer) {
System.out.println("Too High");
System.out.println("\nGuess again ");
} else if (guess < answer) {
System.out.println("Too Low");
System.out.println("\nGuess again: ");
} else {
System.out.println("Correct! The number was " + answer + ".");
System.out.println("It took you " + numberOfGuesses + " guesses.");
}
}
System.out.println("\nWould you like to play again (yes/no)?");
input.nextLine();//You have to go to the next line...
cont = input.nextLine();
} while (cont.equals("yes"));
System.out.println("\nThanks for playing !");
input.close();
}
}
Answer from Lahcen YAMOUN on Stack OverflowWell, as I look to your looping logic it could be maintained and working as charm, you just need to move the initialization steps from the outside, to the inside do-while loop, in the beginning.
That way, at each start of the game, everything will work.
Also you're forgetting to go to next line before reading the user choice of yes/no, as you were reading just ints, at the end your a line ahead of the line containing the verdict yes/no
I tried this code in an online compiler, and it's working :
import java.util.Scanner;
import java.util.Random;
public class Main{
public static void main(String []args){
Random random = new Random();
Scanner input = new Scanner(System.in);
final int MAX = 100;
System.out.println("Guess a number between 1 and " + MAX + ": ");
String cont = new String();
do {
System.out.println("Let's play");
//Initializations here
int answer = random.nextInt(MAX) + 1;
int guess = -1;
int numberOfGuesses = 0;
while (guess != answer) {
numberOfGuesses++;
guess = input.nextInt();
if (guess == 101) {
break;
} else if (guess > answer) {
System.out.println("Too High");
System.out.println("\nGuess again ");
} else if (guess < answer) {
System.out.println("Too Low");
System.out.println("\nGuess again: ");
} else {
System.out.println("Correct! The number was " + answer + ".");
System.out.println("It took you " + numberOfGuesses + " guesses.");
}
}
System.out.println("\nWould you like to play again (yes/no)?");
input.nextLine();//You have to go to the next line...
cont = input.nextLine();
} while (cont.equals("yes"));
System.out.println("\nThanks for playing !");
input.close();
}
}
I would organize this into a class with methods first. This breaks down each piece of logic and makes it easier to read.
- Start a "play" loop
- Inside the "play" loop, have a "guess" loop
- Store the "continue" state in a known constant
- Only check if they are correct after they made the max number of guesses.
- Seed the
Randomobject with the current system time
Also, I added a DEBUG flag to display the answer.
Update: The program is ignoring or not even asking for your "yes" input, because you were previously asking it for integers. You will need to clear/flush/reset the scanner's buffer by calling nextLine. Switching from integer to string leaves some data in the buffer. So your program will use the left-over character data in the buffer before it prompts you for your input.
import java.util.Scanner;
import java.util.Random;
public class HiLo implements Runnable {
private static boolean DEBUG = true; // Disable to not show the answer...
private static final int MAX_NUMBER = 100;
private static final int MAX_GUESSES = 5;
private static final String YES = "YES";
private final Random rand;
public HiLo() {
this.rand = new Random(System.currentTimeMillis());
}
public static void main(String[] args) {
new Thread(new HiLo()).start();
}
@Override
public void run() {
Scanner scan = new Scanner(System.in);
String cont = "";
do {
play(scan);
System.out.print("\nWould you like to play again (yes/no)? ");
cont = scan.nextLine();
System.out.println();
} while (cont.equalsIgnoreCase(YES));
scan.close();
}
public void play(Scanner scan) {
boolean correct = false;
int numberOfGuesses = 0;
int answer = rand.nextInt(MAX_NUMBER) + 1;
if (DEBUG) System.out.printf("The answer is: %d%n", answer);
System.out.printf("Guess a number between 1 and %d%n", MAX_NUMBER);
while (numberOfGuesses < MAX_GUESSES && !correct) {
numberOfGuesses++;
correct = makeGuess(scan, answer, numberOfGuesses);
}
if (numberOfGuesses <= MAX_GUESSES && correct) {
System.out.printf("Correct! The number was %d. It took you %d guesses.%n", answer, numberOfGuesses);
} else {
System.out.printf("Sorry, but you did not guess: %d", answer);
}
scan.nextLine(); // Reset...
}
public boolean makeGuess(Scanner scan, int answer, int currentGuesses) {
System.out.print("Guess: ");
int guess = scan.nextInt();
if (guess == answer) {
return true;
}
if (currentGuesses < MAX_GUESSES) {
if (guess > answer) {
System.out.print("Too High, ");
} else {
System.out.print("Too Low, ");
}
}
return false;
}
}
Sample Output
The answer is: 64
Guess a number between 1 and 100
Guess: 50
Too Low, Guess: 75
Too High, Guess: 60
Too Low, Guess: 65
Too High, Guess: 64
Correct! The number was 64. It took you 5 guesses.
Would you like to play again (yes/no)? yes
The answer is: 88
Guess a number between 1 and 100
Guess: 50
Too Low, Guess: 90
Too High, Guess: 80
Too Low, Guess: 85
Too Low, Guess: 87
Sorry, but you did not guess: 88
Would you like to play again (yes/no)? no
Videos
your whole logic is within the main()-method. I suggest you move the while{}-part into a new method like play().
In your main() implement a new while() with prompting your message and reading the input from the keyboard:
public static void main(String args[]) {
Scanner inputScanner = new Scanner(System.in);
String userInput = "";
do {
play();
System.out.print("Do you want to play again ([Y] / n)? ");
userInput = inputScanner.nextLine();
System.out.println(userInput);
} while (userInput.equals("Y") || userInput.equals(""));
}
HTH, SiS
A possible solution is to place the game in another while loop(that envelops that of the gameCount) and within the while loop create a switch statement for a variable lets say gameContinue. At the end of the game the user would receive a prompt saying whether to continue or not. Based on their answer you change the value of the variable gameContinue and there you go.
I noticed that you had this piece of code repeated four times throughout your program.
System.out.println("You win!");
System.out.println("It took you " + tries + " tries.");
System.out.println("Do you want to start again?");
System.out.println("Type 1 to start again, type 2 to quit.");
One suggestion I would make is to insert this code into a method, that will you will only need to call the method and reduce the amount of code you have. For example you can do this:
public static void winningMessage(){
System.out.println("You win!");
System.out.println("It took you " + tries + " tries.");
System.out.println("Do you want to start again?");
System.out.println("Type 1 to start again, type 2 to quit.");
}
Then in your code just call the method, winningMessage();
Another suggestion I would make to your code is to only use one Scanner object. Within your code you have more than one when you only need one. You do not need multiple scanners for each time you are going to take user input you can continue to reuse the same scanner object.
Last suggestion I would make is to declare your variables up at the top of the program.
You have loaded all your code into the main() method. That is generally not good. You should aim to keep main() relatively small and have the workings hidden in other methods that you call from main(). Use main() more for flow control than for actually playing the game. Something like:
import java.util.Random;
import java.util.Scanner;
public class GuessingGameTest {
// Shared class utilities.
Random myRand = new Random();
Scanner inScan = new Scanner(System.in);
public static void main(String[] args) {
// Introduce the game.
System.out.println("Hello and welcome to my number guessing game.");
// Play the game.
boolean playing = true;
while (playing) {
// Play one game.
playGame();
// Another game?
char reply = 'X';
while (reply != '1' && reply != '2')
System.out.println("Do you want to start again?");
System.out.println("Type 1 to start again, type 2 to quit.");
reply = inScan.nextChar();
}
if (reply == '2') {
playing = false; // Exit game.
}
}
System.out.println("Thank you for playing. Goodbye.");
}
static void playGame() {
System.out.println("Pick a number: ");
// Much code here.
}
} // end class GuessingGameTest.
I have not compiled or tested this code, so test it thoroughly before using it.
Your use of exit() is not good practice either. Let the code finish naturally, and reserve exit() for exceptional situations, not for a normal termination.
Try out this
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!");
System.out.println("Do you like to play again?[1 for Yes/0 for No]");
int val = scan2.next();
if (val == 1)
playGame();
else
break;
}
}
}
}
or rather than using same scanner you can use another scanner and get string input as follows
else if (guess == number) {
System.out.println("Correct!");
Scanner scan2 = new Scanner(System.in);
System.out.println("Do you like to play again?[Y/N]");
String val = scan2.next();
if (val.equalsIgnoreCase("Y"))
playGame();
else
break;
}
You need to exit the while when correct.
To do so, after the line:
System.out.println("Correct!");
Add another line like this:
break;
The cleanest way is to put all of the code in main in a function. Then call that function in a loop. Like this:
Scanner scanner = new Scanner(System.in);
while (true) {
runGame(scanner);
// Game has finished
System.out.println("Do you want to play again, type (5) for yes or (10) for no");
if (scanner.nextLine().equals("10")) {
break;
}
}
The scanner is passed to the function as the same one can be used there. There's no reason to have multiple scanners in your program, and it should be avoided.
Build a while (or do-while, which would be even a better choice) around it. Ask if it should be played again, if yes the condition of the while stays true, otherwise change it. Of course you have to initialize numSticks, numToTake and score to 0 again.
package test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Sticks3 {
public static void main(String[] args) throws java.lang.Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int numSticks = 21;
System.out.println("Would You Like to go first? (Yes/No)");
Scanner input = new Scanner(System.in);
String goFirst = input.nextLine();
Scanner take = new Scanner(System.in);
int numToTake = 0;
int score = 0;
boolean playAgain = true;
Scanner askPlayAgainScanner = new Scanner (System.in);
while (playAgain == true) {
numSticks = 21;
numToTake = 0;
score = 0;
while (numSticks > 0) {
if (goFirst.equals("Yes") || goFirst.equals("yes")) {
System.out.println("There are " + numSticks + " sticks ");
System.out.println("How many sticks do you want to take (1 or 2)");
numToTake = take.nextInt();
if (numToTake > 2) {
numToTake = 2;
}
else if (numToTake < 1) {
numToTake = 1;
}
numSticks = numSticks - numToTake;
if (numSticks <= 0) {
System.out.println("You lose");
System.out.println("Your score is " + score);
} else {
if ((numSticks - 2) % 3 == 0 || numSticks - 2 == 0) {
numToTake = 1;
} else {
numToTake = 2;
}
System.out.println("Computer takes " + numToTake + " sticks ");
numSticks = numSticks - numToTake;
if (numSticks <= 0) {
System.out.println(" You win ");
score++;
System.out.println("Your score is " + score);
}
}
} else {
if ((numSticks - 2) % 3 == 0 || numSticks - 2 == 0) {
numToTake = 1;
} else {
numToTake = 2;
}
System.out.println("Computer takes" + numToTake + " sticks ");
numSticks = numSticks - numToTake;
if (numSticks <= 0) {
System.out.println("You win");
score++;
System.out.println("Your score is " + score);
} else {
System.out.println("There are " + numSticks + " sticks ");
System.out.println("How many sticks do you want to take (1 or 2)");
numToTake = take.nextInt();
if (numToTake > 2) {
numToTake = 2;
} else if (numToTake < 1) {
numToTake = 1;
}
numSticks = numSticks - numToTake;
if (numSticks <= 0) {
System.out.println("You win");
score++;
System.out.println("Your score is " + score);
}
}
}
}
System.out.print("Do you want to play again? true for yes, false for no: ");
boolean askPlayAgain = askPlayAgainScanner.nextBoolean();
}
}
}
You already found a good position for adding this functionality:
System.out.println("Do you want to play again?: ");
The first step now is to also tell the user what he/she should enter after that question:
System.out.println("Do you want to play again? (enter 0 for yes and 1 for no): ");
After that we need to get the user input of course:
int number;
//If the user enters e.g. a string instead of a number, the InputMismatchException
//will be thrown and the catch-block will be executed
try {
number = input.nextInt();
//If number < 0 OR number > 1
if(number < 0 || number > 1) {
//The rest of the try-block will not be executed.
//Instead, the following catch-block will be executed.
throw new InputMismatchException();
}
break;
}
catch(InputMismatchException e) {
System.out.println("Enter 0=yes or 1=no");
//Clears the scanner to wait for the next number
//This is needed if the user enters a string instead of a number
input.nextLine();
}
If you don't know about try-catch-statements yet, I suggest to read this explanation. For details about the InputMismatchException, please see the documentation.
The problem now is that the user only has one chance to enter 0 or 1. If the user makes a wrong input the program will just stop. One solution to this problem is to just put the code in a while-loop:
int number;
while(true) {
try {
number = input.nextInt();
if(number < 0 || number > 1) {
throw new InputMismatchException();
}
break;
}
catch(InputMismatchException e) {
System.out.println("Enter 0=yes or 1=no");
input.nextLine();
}
}
After this block, we can be sure that number is either 0 or 1. So now we can add a simple if-statement to check the value:
if(number == 0) {
new Guess().doGuess();
}
return;
So all in all the code looks like this:
System.out.println("Do you want to play again? (enter 0 for yes and 1 for no): ");
int number;
while(true) {
try {
number = input.nextInt();
if(number < 0 || number > 1) {
throw new InputMismatchException();
}
break;
}
catch(InputMismatchException e) {
System.out.println("Enter 0=yes or 1=no");
input.nextLine();
}
}
if(number == 0) {
new Guess().doGuess();
}
return;
Don't forget to add the following import-statements:
import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.Random;
Try this. Basically, if the user responds with "yes" , we will call the function again.
if (tries > 9) {
System.out.println("You should be able to do better!"
+ " You have hit your ten guess limit. The number" + " was: " + answer);
System.out.println("Do you want to play again? (yes/no): "); // modified line
if("yes".equalsIgnoreCase(input.next())){ // newly added if block
answer = generateRandomNumber();
tries=0;
i=0;
win = false;
doGuess();
}
return;
}