2

This is my code. It is fairly simple, I am just asking the user for a guess, and telling them if they are correct, high or low to the number. To continuously ask, I made a while loop.

Although, I am not sure why or how it works the way it does. I initialize the int as -1 for guess, and it seems to work. Why wont this work without initializing it at all, and why a negative number to begin with. Doing this just seems to be a bit out of place. I am guessing this isn't common practice?

Thanks again! :)

import java.util.Scanner;
public class numGuess
{
public static void main(String[] args)
{
    //generate random number between 1 and 100
    int number = (int)(Math.random() * 101);

    Scanner input = new Scanner(System.in);
    System.out.println("Guess a number between 1 and 100");

    int guess = -1;
    while (guess != number)
    {
       System.out.print("\nEnter your guess: ");

       guess = input.nextInt();


       if (guess == number)
           System.out.println("you are correct, the number is " + number);
       else if (guess > number)
           System.out.println("your guess is too high");
       else
           System.out.println("your guess is too low");
    }
}

}

jpX
  • 29
  • 2
  • 9
  • Because you are comparing the variable guess with number in while loop, so the compiler enforces you to set a default vale for that variable. – Hariharan Dec 07 '14 at 17:36
  • Since the question has already been answered I'd like to point out that class names ought to start with capital letters and not camelCase like fields and methods. Therefore `numGuess` should be `NumGuess`. – Juxhin Dec 07 '14 at 17:37
  • Can you tell me how you want to compare the value of `number` with *nothing*? Neither can the compiler, therefore he needs a value in `guess`. – Tom Dec 07 '14 at 17:38
  • take a look at Random.nextInt(int i): http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int) – keuleJ Dec 07 '14 at 18:39

4 Answers4

2

Java is a strongly typed language and thus requires a variable to be defined before it can be used.

You have to define guess before you can use it. The loop will work as long as guess is initially defined to be anything that is not number.

You could define guess like so to make sure it's different. You would never want to do this. I just want to show that pretty much any initial value could be used to initialize guess.

int guess = number - 1;

You could also use a do..while loop to not initially assign it. This would be the preferred way of doing it since you're not making any assumptions.

int guess;
do {
   System.out.print("\nEnter your guess: ");

   guess = input.nextInt();


   if (guess == number)
       System.out.println("you are correct, the number is " + number);
   else if (guess > number)
       System.out.println("your guess is too high");
   else
       System.out.println("your guess is too low");
}while(guess != number);

This the loop runs once and assigns guess from the user input directly instead of having to assign it before yourself.

Kassym Dorsel
  • 4,773
  • 1
  • 25
  • 52
  • 1
    int guess = number -1 is a kludge. It's not semantically correct. It simply happens to work. If you're going to use a flag value please don't randomize it without a good reason. Your maintenance developer will thank you. – candied_orange Dec 07 '14 at 17:47
  • So here you are running the user's guess though the loop first? So int guess = -1; while (guess != number) so the guess in the condition is NOT the guess from the user? – jpX Dec 07 '14 at 17:50
  • @CandiedOrange, I agree. It was more of an example that pretty much any value could be used as long as it was different the the initial number value. Not something I would ever do. – Kassym Dorsel Dec 07 '14 at 17:50
  • A do while runs at least once. This way you don't have to randomly assign an initial guess. You get the first guess directly from the user and do the check after. – Kassym Dorsel Dec 07 '14 at 17:51
  • It's the same variable. You assign the user's input to the `guess` variable. In your initial code you needed `guess` to be defined so you "took" the first guess for the user and made sure it was wrong so you could check that it was indeed wrong. With the do..while loop you let the user make the first guess. – Kassym Dorsel Dec 07 '14 at 17:54
  • If you agree then please update your answer. Otherwise the do-while is a good idea. – candied_orange Dec 07 '14 at 18:28
1

There is no hard and fast rule to have -1 as guess value in your case. You could even initialize it to value greater than 101 or any number other than between 0 - 101.

Alternatively, you could use do while loop like below if you dont want to initialize it:

int guess;
do {
    System.out.print("\nEnter your guess: ");

   guess = input.nextInt();


   if (guess == number)
       System.out.println("you are correct, the number is " + number);
   else if (guess > number)
       System.out.println("your guess is too high");
   else
       System.out.println("your guess is too low");
} while (guess != number);
SMA
  • 36,381
  • 8
  • 49
  • 73
0

-1 is a sentinel value. That is, it's an invalid value for your program's purpose, and in particular, it's not the value of anything returned by (int) (Math.random() * 101) (which, BTW, generates a number between 0 and 100, not 1 and 100).


One way to avoid the "double duty" of guess is to change the loop to unconditionally loop, and then use break to break out of the loop if the guess is correct. Like so:

while (true) {
   System.out.print("\nEnter your guess: ");

   int guess = input.nextInt();

   if (guess == number) {
       System.out.println("you are correct, the number is " + number);
       break;
   } else if (guess > number) {
       System.out.println("your guess is too high");
   } else {
       System.out.println("your guess is too low");
   }
}

(Notice that I've added braces to your if block so that there can be multiple statements in the branches.) This is probably the cleanest way to do it.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • Alright. So a follow up would be, why do I HAVE to state that beforehand? Am I telling the loop that "hey they are going to guess something between 0-100, but I set the value at -1 first because it is not part of the parameters I set up" ? A little lost. – jpX Dec 07 '14 at 17:39
  • @user3457747 You don't have to. You can instead use a `do`/`while` loop as explained in Kassym's answer. – C. K. Young Dec 07 '14 at 17:40
  • I think I am just confusing the guess used for the conditions and the 'guess' that is from the user inside of the if statements – jpX Dec 07 '14 at 17:56
  • Right, in that case, you'd be better off using `do`/`while`, where `guess` won't be made to do "double duty". :-) – C. K. Young Dec 07 '14 at 17:59
  • Gotcha. Still using what I have for example purposes, why wont it work if I then change the 'int guess = =1;' to something like 'int guessloop = =1;' and it still will not work? The loop will not terminate even if I guess the number correctly. – jpX Dec 07 '14 at 18:03
  • Well, if you changed to `guessloop`, that means that your actual human guess isn't updating it, right? (Hard to tell without seeing your changed code in front of me.) In that case, the loop condition will always stay true, and so you won't exit the loop. – C. K. Young Dec 07 '14 at 18:11
  • I've also updated the post to suggest an alternative that uses an unconditional loop paired with `break` to exit the loop. You may find that easier to work with. (BTW, were you the one who posted in my Ask Me Anything? If so, I appreciate it. :-)) – C. K. Young Dec 07 '14 at 18:17
0

You are using -1 as a flag (sentinel) value. It's a value that the user is not allowed to guess so it indicates no guess has happened yet. If you don't initialize it at all then it would start at zero, the flag value would be zero, the user shouldn't be allowed to guess zero and the random number should never be zero.

In other words you should be able to work with zero as your flag value. However, you're Math.random() doesn't seem to exclude zero. Take a look at Math.random() explained.

//generate random number between 1 and 100
int number = (int)(Math.random() * 101);

Should be

int number = (int)(Math.random() * 100) + 1;

Math.random() has a range from [0, 1). That means 0 is included but 1 is not. Your existing code will pick numbers from 0 to 100. You told the user you were going to pick from 1 to 100. Unless you intend to cheat that needs fixing.

It's also a nightmarish bug to test for since it only happens 1% of the time. Read the documentation for Math.random() carefully.

If you write a test that run's until value has been every number is supposed to be able to be it will only stop when you don't have a bug. As nightmarish as that is it turns out if you have it programmed correctly and let it loop 459 times there will only be a 1% chance that it hasn't picked 0 simply by chance. So you shouldn't have to wait to long for the test. I can show you the math behind that if you care.

Also, you may wish to consider a do-while loop so you don't need a flag in the first place. But do while or not you need to fix your Math.random() line.

Community
  • 1
  • 1
candied_orange
  • 7,036
  • 2
  • 28
  • 62