Issue with Java Guessing Game - java

I'm working on this guessing game for school. I've realized that at some point I deleted my while loop for the user's guess equalling the computer's random number and it has messed up the results of my program. I thought that I could just add a nested while loop, but that hasn't worked. I've been trying to figure this out for hours.
Any ideas how to add something like while (guess == number) to my code and keep it working?
/*
Programming Assignment #3: Guess
Peter Harmazinski
Week 8
Guessing Game
*/
import java.util.*;
public class Guess {
public static final int RANGE = 100;
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
boolean again = true;
double guessesDividedByGames = 0;
int maxGuesses = 0;
int numGames = 0;
int numGuesses = 1;
int totalGuesses = 0;
Random rand = new Random();
int number = rand.nextInt(RANGE) + 1;
int guessTracker = 0;
while(again) {
getInstructions();
int guess = getGuess(console);
numGuesses = getHigherLower(guess, number, console);
totalGuesses += numGuesses;
again = playAgain(numGuesses, console);
numGames++;
if (numGuesses > maxGuesses) {
maxGuesses = numGuesses;
}
}
guessesDividedByGames = (double)totalGuesses / numGames;
getResults(numGames, totalGuesses, guessesDividedByGames, maxGuesses);
}
//Prints instructions for user
public static void getInstructions() {
System.out.println("This program allows you to play a guessing game");
System.out.println("I will think of a number between 1 and " + RANGE);
System.out.println("and will allow you to guess until you get it.");
System.out.println("For each guess, I will tell you whether the");
System.out.println("right answer is higher or lower than your guess");
System.out.println("");
}
//Allows the user to play again if first letter of input is "y" or "Y"
public static boolean playAgain(int guessesNum, Scanner console) {
boolean anotherTime = false;
System.out.println("You got it right in " + guessesNum + " guesses.");
System.out.println("");
System.out.print("Do you want to play again? ");
String repeat = console.next();
String[] yesOrNo = repeat.split("");
System.out.println("");
if (yesOrNo[0].equals("y") || yesOrNo[0].equals("Y")) {
anotherTime = true;
}
return anotherTime;
}
//Outputs the results if the user doesn't play again
public static void getResults(int gamesTotal, int guessesTotal, double guessesDividedByGames, int guessesMax) {
System.out.println("Overall results:");
System.out.println("\ttotal games\t= " + gamesTotal);
System.out.println("\ttotal guesses\t= " + guessesTotal);
System.out.println("\tguesses/game\t= " + guessesDividedByGames);
System.out.println("\tmax guesses\t= " + guessesMax);
}
//Tells the user whether the random number is higher or lower
//and then returns the number of guesses
public static int getHigherLower(int guess, int randomNumber, Scanner console) {
int guessIncreaser = 1;
while (guess > randomNumber) {
System.out.println("lower");
guess = getGuess(console);
guessIncreaser++;
}
while (guess < randomNumber) {
System.out.println("higher");
guess = getGuess(console);
guessIncreaser++;
}
return guessIncreaser;
}
//Asks the user to guess the random number
//then returns the guess
public static int getGuess(Scanner console) {
System.out.println("I'm thinking of a number...");
System.out.print("Your Guess? ");
int playerGuess = console.nextInt();
while (playerGuess < 1 || playerGuess > RANGE) {
System.out.println("Out of range, please try again.");
System.out.print("Your Guess? ");
playerGuess = console.nextInt();
}
return playerGuess;
}
}

The problem appears to be your getHigherLower method, specifically these two while blocks:
while (guess > randomNumber) {
System.out.println("lower");
guess = getGuess(console);
guessIncreaser++;
}
while (guess < randomNumber) {
System.out.println("higher");
guess = getGuess(console);
guessIncreaser++;
}
If the user guessed a number lower than randomNumber, then higher, both while blocks would be escaped. Instead, what you want is this:
while (guess != randomNumber) {
if (guess > randomNumber) {
System.out.println("lower");
}
else {
System.out.println("higher");
}
guess = getGuess(console);
guessIncreaser++;
}

What you need is one big while loop not two little ones
while (guess != randomNumber) {
if (guess > randomNumber) {
System.out.println("lower");
} else {
System.out.println("higher");
}
guess = getGuess(console);
guessIncreaser++;
}

First off, I'm hesitant to just give you the answer in code since this is for a school project and we learn by challenging ourselves and actualizing solutions. But I'm willing to point you in the right direction.
1. getHigherLower()
As others have pointed out, your two while loops are set up to cause errors. For instance, if I first guess too low, and then too high, your method mistakenly tells me I guessed correctly. This is a big problem!
Random number = 63
Guess 1 = 34 (lower)
Guess 2 = 100 (higher)
Actually your program tells me my guess of "100" when the number is "63" is correct!
// 1st conditional check: 34 !> 63, so skips first while loop
while (guess > randomNumber) {
guess = getGuess(console);
}
// 1st conditional check: 34 < 63, so enters second while loop
// 2nd conditional check: 100 !< 63, so skips second while loop
while (guess < randomNumber) {
// guess now becomes 100, goes back to top of while loop to check condition again
guess = getGuess(console);
}
// returns and exits method here (program wrongly thinks user has guessed correctly!)
Note that you can do a
System.out.println("random number: " + number);
to test that you're actually guessing the random number correctly. You might look into some JUnit testing as well.
James Ko seems to have a good feel for a better method implementation.
2. playAgain()
You use an if statement to check if the first index in an array of strings equals "y" or "Y" but your program never continues. Why is this?
if (yesOrNo[?].equals("y") {
anotherTime = true;
}
You should consider whether user input is really being placed at the first index or not?
Hint: loop through the "yesOrNo" array and print out each index to see where the user input is being placed in the array.
for (int i = 0; i < yesOrNo.length; i++) {
System.out.println("String at index " + i + ": " + yesOrNo[i]);
}
Good luck and remember that testing is your friend!

Related

How do I include a question asking the user if they want to play again?

I am still new to Java and as such I am still figuring some things out. I have been having issues with including code asking the user if they want to play again. I have attempted putting it in the main class in a print statement which gave me an error. After that, I attempted putting it in the Guess.java class in multpile places but I just recieved errors. I have read up on the issue and some sites have suggested a while loop but I am unsure how to implement it into my current code. I have included both the main class which is called GuessingGame.java and the Guess.java class below. Thank you for any assistance that can be provided.
GuessingGame.java
public class GuessingGame {
public static void main(String[] args) {
new Guess().doGuess();
}
}
Guess.java
class Guess {
private int answer = 0;
int tries = 0;
Scanner input = new Scanner(System.in);
int guess, i;
boolean win = false;
int amount = 10;
public Guess() {
answer = generateRandomNumber();
}
//Generate a private number between 1 and a thousand
private int generateRandomNumber() {
Random rand = new Random();
return rand.nextInt(1000) + 1;
}
public void doGuess() {
while (!win) {
System.out.println("You are limited to ten attempts."
+ " Guess a number between 1 and 1000: ");
guess = input.nextInt();
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?: ");
return;
}
if (guess > 1000) {
System.out.println("Your guess is out of the range!");
} else if (guess < 1) {
System.out.println("Your guess is out of the range!");
} else if (guess == answer) {
win = true;
tries++;
} else if (guess < answer && i != amount - 1) {
System.out.println("Your guess is too low!");
tries++;
} else if (guess > answer && i != amount - 1) {
System.out.println("Your guess is too high!");
tries++;
}
}
System.out.println("Congragulations! You guessed the number!"
+ "The number was: " + answer);
System.out.println("It took you " + tries + " tries");
}
}
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;
}

How do I add a limit to the number of guesses in a number guessing game?

I cannot figure out how to add a limit to the number of guesses in my number guessing game. I have tried adding a for statement after the while statement but that made the code just stop at the tenth guess and there was no winner ever. I deleted the while statement and just did the for statement which ensured that the user got the correct answer every ninth guess. My code is divided into two classes as requested by my professor. I am including both below. I would appreciate all the help I can get. Thank you!
GuessingGame.java: Main Class
public class GuessingGame {
public static void main(String[] args) {
new Guess().doGuess();
}
}
Guess.java
class Guess {
private int answer = 0;
int tries = 0;
Scanner input = new Scanner(System.in);
int guess, i;
boolean win = false;
int amount = 10;
public Guess() {
answer = generateRandomNumber();
}
//Generate a private number between 1 and a thousand
private int generateRandomNumber() {
Random rand = new Random();
return rand.nextInt(1000) + 1;
}
public void doGuess() {
while(!win) {
System.out.println("You are limited to ten attempts."
+ "Guess a number between 1 and 1000: ");
guess = input.nextInt();
if (guess > 1000 ) {
System.out.println("Your guess is out of the range!");
} else if (guess < 1) {
System.out.println("Your guess is out of the range!");
} else if (guess == answer) {
win = true;
tries++;
} else if (guess < answer && i != amount -1) {
System.out.println("Your guess is too low!");
tries++;
} else if (guess > answer && i != amount -1) {
System.out.println("Your guess is too high!");
tries++;
}
}
System.out.println("Congragulations! You guessed the number!"
+ "The number was: " +answer);
System.out.println("It took you " + tries + " tries");
}
}
You can add an if-statement inside the while loop.
public void doGuess() {
while(!win) {
System.out.println("You are limited to ten attempts."
+ "Guess a number between 1 and 1000: ");
guess = input.nextInt();
if(tries > 9) {
...whatever you want to happen when user has reached 10 guesses...
}

How to properly pass a variable?

Here is my code, this program is a simple number guessing game, in which the computer picks a random number between 1 and x (set within the program) and the user is to guess the number using feedback from the computer stating whether each guess is higher or lower than secret number.
The code consists of 4 methods, a main method in which several variables are declared after displaying instructions for playing. Then a while loop is setup to start a new game. 3 lines into the while loop, a method is called to start playing a new game, passing both the scanner/console and an integer called guesses (which is set to 0 each time this method is called).
This integer, guesses, increments by one each time the user makes a guess and should be returned at the end of the game method, but I cannot seem to figure out why it is not being returned. It needs to be returned so it can be passed to the results method to calculate the stats that will be displayed if the user decides not to play again.
Any help would be appreciated...
import java.util.*;
public class Guess {
public static void main(String[] Args) {
Scanner console = new Scanner(System.in);
Introduction(); //required
int games = 0;
int newGame = 1;
int guesses = 0;
int maxguesses = 0;
int totalguesses = 0;
while (newGame == 1) {
String userNewGame = "";
games = games + 1;
Game(guesses,console); //required
if (guesses > maxguesses) {
guesses = maxguesses;
}
totalguesses = totalguesses + guesses;
System.out.print("Do you want to play again? ");
userNewGame = console.next();
System.out.println();
char first = userNewGame.charAt(0);
if ( first == 'Y' || first == 'y') {
newGame = 1;
}
else if ( first == 'N' || first == 'n') {
newGame = 0;
}
}
Results(games,totalguesses,maxguesses); //required
}
public static void Introduction() {
System.out.println("This program allows you to play a guessing game.");
System.out.println("I will think of a number between 1 and 100");
System.out.println("and will allow you to guess until you get it.");
System.out.println("For each guess, I will tell you whether the");
System.out.println("right answer is higher or lower than your guess.");
System.out.println();
}
public static int Game(int guesses, Scanner console) {
Random rand = new Random();
int range = 100; //Change this value to set the range the computer will require to guess ie. 100 is 1 to 100 inclusive, 5 is 1 to 5 inclusive, etc.
int number = rand.nextInt(range) + 1;
guesses = 0;
int guess = -1;
System.out.println("I'm thinking of a number...");
while (guess != number) {
System.out.print("Your guess? ");
guess = console.nextInt();
guesses = guesses + 1;
if (guess < number) {
System.out.println("higher");
}
if (guess > number) {
System.out.println("lower");
}
if (guess == number) {
System.out.println("You got it right in " + guesses + " guesses");
System.out.println();
}
}
return guesses;
}
public static void Results(int games,int totalguesses,int maxguesses) {
System.out.println("Overall results:");
System.out.println(" total games = " + games);
System.out.println(" total guesses = " + totalguesses);
System.out.println(" guesses/game = " + totalguesses / games);
System.out.println(" max guesses = " + maxguesses);
}
}
There's a handful of things going on here, and all of them kind of build on one another.
You're not capturing the result of the value you get back from Game.
You're doing some very strange things with your variables, which reduces readability.
You're going to run into issues with your Scanner down the line, as you loop through this program.
Let's start with the low-hanging fruit. Game returns an int, but it's not being assigned anywhere. Ideally, it should be assigned to the value of guesses.
guesses = Game(guesses,console); //required
...except it doesn't really make sense to pass guesses in when:
we're reassigning it in main (don't worry, the Game method will have its own copy of guesses anyway since Java is pass by value)
you explicitly assign it to 0 inside of Game anyway
So instead, you want to remove that as an argument to your method.
guesses = Game(console);
And inside of Game, you can define your own guesses variable.
public static int Game(Scanner console) {
Random rand = new Random();
int range = 100; //Change this value to set the range the computer will require to guess ie. 100 is 1 to 100 inclusive, 5 is 1 to 5 inclusive, etc.
int number = rand.nextInt(range) + 1;
int guesses = 0;
int guess = -1;
System.out.println("I'm thinking of a number...");
while (guess != number) {
System.out.print("Your guess? ");
guess = console.nextInt();
guesses = guesses + 1;
if (guess < number) {
System.out.println("higher");
}
if (guess > number) {
System.out.println("lower");
}
if (guess == number) {
System.out.println("You got it right in " + guesses + " guesses");
System.out.println();
}
}
return guesses;
}
The last obvious issue I can see is one where you're using next(), but you're not quite clearing the buffer for a Scanner.
userNewGame = console.next();
// and inside of Game()
guess = console.nextInt();
This is a surprisingly common Scanner problem, and it's easy enough to work around.
userNewGame = console.next();
console.nextLine();
// and inside of Game()
guess = console.nextInt();
console.nextLine();
Alternatively, you could use nextLine instead and not deal with next() since they both return String. The difference being that next() doesn't consume the newline character generated by Return/Enter, and nextLine() does.
Instead of just calling the Guesses method, you should use the returned value to update your variable, like so:
guesses = Game(guesses,console); //required
If you want the maxguesses to hold the max amount of guesses (among all the games), then you should update your logic after the Game method is called like so,
if (guesses > maxguesses) {
maxguesses = guesses; // not guesses = maxguesses
}
This is the whole code I am posting which works fine I think. Check it out:
import java.util.*;
public class Guess {
public static void main(String[] Args) {
Scanner console = new Scanner(System.in);
Introduction(); //required
int games = 0;
int newGame = 1;
int guesses = 0;
int maxguesses = 0;
int totalguesses = 0;
while (newGame == 1) {
String userNewGame = "";
games = games + 1;
guesses = Game(guesses,console); //required
if (guesses > maxguesses) {
maxguesses = guesses;
}
totalguesses = totalguesses + guesses;
System.out.print("Do you want to play again? ");
userNewGame = console.next();
System.out.println();
char first = userNewGame.charAt(0);
if ( first == 'Y' || first == 'y') {
newGame = 1;
}
else if ( first == 'N' || first == 'n') {
newGame = 0;
}
}
Results(games,totalguesses,maxguesses); //required
}
public static void Introduction() {
System.out.println("This program allows you to play a guessing game.");
System.out.println("I will think of a number between 1 and 100");
System.out.println("and will allow you to guess until you get it.");
System.out.println("For each guess, I will tell you whether the");
System.out.println("right answer is higher or lower than your guess.");
System.out.println();
}
public static int Game(int guesses, Scanner console) {
Random rand = new Random();
int range = 100; //Change this value to set the range the computer will require to guess ie. 100 is 1 to 100 inclusive, 5 is 1 to 5 inclusive, etc.
int number = rand.nextInt(range) + 1;
guesses = 0;
int guess = -1;
System.out.println("I'm thinking of a number...");
while (guess != number) {
System.out.print("Your guess? ");
guess = console.nextInt();
guesses = guesses + 1;
if (guess < number) {
System.out.println("higher");
}
if (guess > number) {
System.out.println("lower");
}
if (guess == number) {
System.out.println("You got it right in " + guesses + " guesses");
System.out.println();
}
}
return guesses;
}
public static void Results(int games,int totalguesses,int maxguesses) {
System.out.println("Overall results:");
System.out.println(" total games = " + games);
System.out.println(" total guesses = " + totalguesses);
System.out.println(" guesses/game = " + totalguesses / games);
System.out.println(" max guesses = " + maxguesses);
}
}
Sample output:
This program allows you to play a guessing game.
I will think of a number between 1 and 100
and will allow you to guess until you get it.
For each guess, I will tell you whether the
right answer is higher or lower than your guess.
I'm thinking of a number...
Your guess? 10
higher
Your guess? 50
lower
Your guess? 40
lower
Your guess? 30
lower
Your guess? 20
lower
Your guess? 15
You got it right in 6 guesses
Do you want to play again? y
I'm thinking of a number...
Your guess? 50
higher
Your guess? 80
higher
Your guess? 90
lower
Your guess? 85
You got it right in 4 guesses
Do you want to play again? n
Overall results:
total games = 2
total guesses = 10
guesses/game = 5
max guesses = 6

Why does my HiLo game allow guesses outside of the 0-10 range?

I have a quick question about this HiLo game that I have been trying to fix from a while now. When I run the program it counts guesses outside of the 0-10 range, but I don't want it to do that. How do I fix that? Here is my code.
import java.util.Random; // Random number generator class
import java.util.Scanner; // reads user inputs
public class HiLo
{
public static void main(String[] args)
{
// declare variables
final int MAX = 10;
int answer, guess;
int numberOfTries = 0;
String again;
Scanner Keyboard = new Scanner(System.in);
do
{
System.out.print(" I'm thinking of a number between 0 and "
+ MAX + ". Guess what it is: ");
guess = Keyboard.nextInt();
// guess
Random generator = new Random(); // Random number generator. 0 to 10.
answer = generator.nextInt(MAX) + 1;
if (guess > 10) // if guess is bigger than 10 then error message
{
System.out.println("ERROR – Your guess is out of the range 0 to 10.");
}
if (guess < 0) // if guess is smaller than 0 then error message
{
System.out.println("ERROR – Your guess is out of the range 0 to 10.");
}
while (guess != answer) // If guess is not the answer
{
if (guess > answer) // If guess is more than the answer
{
System.out.println("You guessed too high! \nTry again:");
guess = Keyboard.nextInt();
}
if (guess < answer)// If guess is less than the answer
{
System.out.println("Too Low! \nTry again:");
guess = Keyboard.nextInt();
}
numberOfTries = numberOfTries + 1;
}// end of the loop
// display result
if (guess == answer)
{
numberOfTries += 1;
System.out.println("YOU WIN!");
System.out.println("It took you " + numberOfTries + " tries!");
System.out.println();
System.out.print("Do you want to play again(Y/N)?");
}
Keyboard.nextLine(); // skip over enter key
again = Keyboard.nextLine();
numberOfTries = 0;
} while (again.equalsIgnoreCase("Y"));
} // end of class
} // end of main
You report the error but you don't continue; (and use a logical ||) like this
if (guess < 0 || guess > 10) {
System.out.println ("ERROR – Your guess is out of the range 0 to 10.");
again = "Y"; // <-- make sure we'll re-evaluate.
continue; // <-- Add then skip the rest of the loop body
}

How would I add "You got it right in ... guesses!"

I need to add "You got it right in ... guesses!" but I'm not exactly sure how. Can someone please explain to me how to do this in java?
I would like it to display a println at the end saying how many tries it took for the user to get the number correct.
import java.util.*;
public class prog210c
{
public static void main()
{
Scanner sc = new Scanner(System.in);
Random rn = new Random();
int randomNum = rn.nextInt(90) + 10;
System.out.println("I am thinking of a number between 1 and 100");
while (true) {
System.out.print("What do you think it is? ");
int guess = sc.nextInt();
if(guess < randomNum)
{
System.out.println("Higher--Try Again");
}
else if(guess > randomNum)
{
System.out.println("Lower--Try Again");
}
else if(guess == randomNum)
{
System.out.println("Correct!");
break;
}
else
{
System.out.println("Enter a number between 1 and 100");
}
}
//System.out.println("You got it right in " + + " guesses");
} //end main
} //end class
Just create some int variable to store your number of attempts in and increment it every time you read in a guess.
int attempts = 0;
System.out.println("I am thinking of a number between 1 and 100");
while (true) {
System.out.print("What do you think it is? ");
int guess = sc.nextInt();
attempts++;
/**
* The rest of your loop code here.
*/
}
System.out.println("You got it right in " + attempts + " guesses");
The simplest way to do this is declared a counter integer, and in your logic increment it every time the user attempts.
int guessCounter = 0;
while(true) // Also do not use an infinite while loop, have an expression that can be terminated
{
...obtain input
if(guess < randomNum)
{
...
guessCounter++;
}
else if (guess > randomNum){
....
guessCounter++;
}
System.Out.println("The number of attempts " + guessCounter);
}
You could do this by creating a variable to store the number of tries, like an int, and then add one to the int every time the user guesses, by using variable++:
public static void main(){
Scanner sc = new Scanner(System.in);
Random rn = new Random();
int tries = 0;
int randomNum = rn.nextInt(90) + 10;
System.out.println("I am thinking of a number between 1 and 100");
while(true){
System.out.print("What do you think it is? ");
int guess = sc.nextInt();
//Rest of your code here
}
System.out.println("You got it right in " + tries + " guesses");
}
and if you want to go even above and beyond, you could make it so it says You got it right in 1 guess instead of it saying You got it right in 1 guesses, if the user gets the number correct on their first try. We can do this by using the ternary Java operator, which is pretty much a compact if-statement:
String s = (tries == 1 ? "guess" : "guesses");
What this is pretty much doing is: if this is true ? do this : else do this
Now we can change the You got it right in... part of your program to say guess instead of guesses if the user guesses the number on their first try:
String s = (tries == 1 ? "guess" : "guesses");
System.out.println("You got it right in " + tries + "" + s);

Categories

Resources