0

This is my first Java program. The assignment is to create a program as follows:

Develop a Java program that works as follows:

1). When the program is started, it displays a message welcoming the player: "Welcome to Game Guru!"

2). Then it creates a secret random number between 1 and 20;

3), Then it displays a message saying: "Guess my magic number [1-20]: "

4). Read and check the number entered by the player.

          If is not a number, the program displays a message saying: "Should enter a number". then go back to step 3)

          If the number is out of range, the program displays a message saying: "Number out of range". Then go back to step 3)

          If the number is smaller than the secret number, the program displays a message saying: "Number too small". Then go back to step 3)

          If the number is greater than the secret number, the program displays a message saying: "Number too large". Then go back to step 3)
          If the number is the same as the secret number, the program displays a message saying: "You got it!". Then go to step 5)

5). The program displays a message saying: "Want more games?"

6). Read the player's answer. If the answer is "yes", then to step 1); If the answer is "no", then go to step 7)

7). The program displays message "Thanks for playing the game. Goobye".

I have gotten it working completely EXCEPT when entering anything other than an INT it gives an exception. I tried researching this myself and found the Try/Catch but it doesn't seem to be working for me. My instructor wont help me...despite the fact that he hasn't actually taught any of this...

Here's my code:

public static void main(String[] args) 
{
    // TODO Auto-generated method stub
    String more;

    do 
    {
        System.out.println("Welcome to Game Guru!");

        int number = 1 + (int)(Math.random() * 20);
        int guess = 0;
        Scanner input = new Scanner(System.in);

            try
                {
                    System.out.println("Guess my magic number [1-20]: ");
                    guess = input.nextInt();
                }
            catch (Exception e)
                {
                    System.out.println("Should enter an integer");
                }

        while (guess != number)
        {
            if (guess > 20 || guess < 1)
            {
                System.out.println("Number out of range");
                System.out.println("Guess my magic number [1-20]: ");
                guess = input.nextInt();
            }
            else if (guess < number)
            {
                System.out.println("Number too small");
                System.out.println("Guess my magic number [1-20]: ");
                guess = input.nextInt();
            }
            else if (guess > number)
            {
                System.out.println("Number too large");
                System.out.println("Guess my magic number [1-20]: ");
                guess = input.nextInt();
            }
        }
        if (guess == number)
        {
            System.out.println("You got it!");
        }
        System.out.println("Want more games? Please enter Y or N.");
        more = input.next();

    } while (more.equals("y") || more.equals("Y")); 

System.out.println("Thanks for playing the game. Goodbye");

}

}

Here's the console:

Welcome to Game Guru!
Guess my magic number [1-20]: 
a
Should enter an integer
Number out of range
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Unknown Source)
at java.base/java.util.Scanner.next(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
Guess my magic number [1-20]: 
at Game.main(Game.java:46)

I really appreciate any insight into this. I'm at my wits end...I should be paying Google my tuition.

TheGrinch
  • 7
  • 3
  • That's because you continue on with calculations even after the exception is raised – Andrew Li Sep 19 '18 at 00:34
  • firstly, you should move your `Scanner` declaration to before the loop secondly, if you should change from a PO `Exception` to a `InputMismatchException` thirdly, you should add a `continue` if you encounter a `InputMismatchException` so that you go to the top of the loop again. – Scary Wombat Sep 19 '18 at 00:44
  • 1
    `nextInt` won't remove the invalid data which is in the buffer, so the next time you call `nextInt`, it's still got the invalid data in it which is causing the exception. Instead, you should use `nextLine` to remove the offending data from the buffer before attempting to read more data. You might like to take a look at [Trying to prompt the user to re-enter from the catch block, but the catch block terminates?](https://stackoverflow.com/questions/52377181/trying-to-prompt-the-user-to-re-enter-from-the-catch-block-but-the-catch-block/52377513#52377513) for an example – MadProgrammer Sep 19 '18 at 00:47

5 Answers5

1

So, starting with...

try
{
    System.out.println("Guess my magic number [1-20]: ");
    guess = input.nextInt();
}
catch (Exception e)
{
    System.out.println("Should enter an integer");
}

Basically, if an exception occurs, the Scanner still contains non-numerical data in it's buffer, this means that if you then try and read the buffer again, doing something like...

guess = input.nextInt();

You will get the same exception again.

A general solution is to call input.nextLine() to clear the buffer before attempting to read new data from it. Personally, I'd use nextLine for all the inputs and Integer.parseInt to parse those elements which you want as int values, but that's me.

Since you have to ask the user for input each time they need to make a guess, you could simplify your solution by using a do-while loop instead (you have to enter the loop at least once any way), this way you could get the input, verify the value (as an int) and perform your required logic on it, all within a single basic loop...

Scanner input = new Scanner(System.in);
String more = "N";
do {
    System.out.println("Welcome to Game Guru!");

    int number = 1 + (int) (Math.random() * 20);
    int guess = 0;

    do {
        try {
            System.out.println("Guess my magic number [1-20]: ");
            String text = input.nextLine();
            guess = Integer.parseInt(text);
            if (guess > 20 || guess < 1) {
                System.out.println("Number out of range");
            } else if (guess < number) {
                System.out.println("Number too small");
            } else if (guess > number) {
                System.out.println("Number too large");
            }
        } catch (NumberFormatException e) {
            System.out.println("Should enter an integer");
        }
    } while (guess != number);

    System.out.println("You got it!");
    System.out.println("Want more games? Please enter Y or N.");
    more = input.nextLine();

} while (more.equalsIgnoreCase("y"));
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Oh my gosh thank you, thank you, thank you! I knew I had to clear the buffer out...I understood what was happening, but could NOT figure out how to do it. I will also try to simplify the code. – TheGrinch Sep 19 '18 at 01:11
0

In the try, you are giving the code you want to execute (fine). In the except statement, you are correctly printing out the error too (great).

Unfortunately, you didn't fix it!

It probably makes sense to put your try/catch in a while loop that repeats until you get valid input. That way, once it works, you move on to the rest of your logic which is dependent on getting valid input from the user in the try/catch.

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • Thank you. I actually had it in a while loop but I didn't know how to clear the buffer and it went into an infinite loop. Its back in there now. – TheGrinch Sep 19 '18 at 01:12
0

You're asking to enter an int, if the user enter another value as a String or Float you will get an exception. Add another try{} catch{} block to verify if it is an Integer otherwise cast it

Stalk
  • 19
  • 5
0

What happens in your code is that it catches that exception in the first try/catch, prints System.out.println("Should enter an integer"); and then proceeds to the rest of the do block. You need to continue after printing that message.

However, you'll encounter more bugs in that code as you continue testing, this is just to answer your question about that exception.

khachik
  • 28,112
  • 9
  • 59
  • 94
  • Can I ask what else you see? I've tested everything I can and it all seems to work... – TheGrinch Sep 19 '18 at 01:13
  • @MadProgrammer actually re-wrote it for you, so I guess this is not relevant anymore. – khachik Sep 19 '18 at 01:26
  • Ya I actually tested more and found that I had to put everything inside the try/catch or I could still get errors...I just saw he wrote everything out when I came back to check your comment lol. Didn't notice that when I first read it. – TheGrinch Sep 19 '18 at 01:39
0

The purpose of your try/ catch is to tell the user that the number they selected is not an integer. The program is not supposed to continue if you enter something other than an integer, as it says in step 4- The first if statement is used to verify that the number is an integer. Instead, you are using a try/ catch, which also stops the program, but a little differently.try/catch block The block of code in the try statement prompts the user to enter a number 1-20. If it is not, it throws the exception because the number entered is not an integer. It prints the message " Should enter an integer", and prints out the errors that should tell the user what is wrong. It is telling you there is an error in the Main class of your program, and where the problem is located. The purpose of the print statement " Should enter an integer" was to prompt the user to enter an integer the next time the program runs, so the program can then run correctly. In your case, the if statement would make more sense to use. Again, the only point of this block of code is to verify the user has entered an integer.