Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Java Objects (Retired) Delivering the MVP Validation

Ray Wai
Ray Wai
2,355 Points

while loop evaluation confusion

I have been looking at some discussion in the forum, and I still do not have a solid grasp of the concept, so I am throwing it out here.

So I get that this line: boolean isValidGuess = false, is setting the variable isValidGuess equals false. And in this line: while (!isValidGuess), the variable isValidGuess is still false, we are not changing it.

But what does that while loop mean? How does that make the whole while loop work? I have tried removing the ! (not) out, and the loop keeps repeating and spitting out "You have 7 tries to solve." so basically it skips the promptForGuess() method, and just looping the displayProgress() method. How did it end up like that?

Thanks, Ray

Gavin Ralston
Gavin Ralston
28,770 Points

Hey Ray,

could you post your code (formatted) in a comment here? (Markdown cheatsheet below the editor window will help you format it to see)

Edit: I think I found the spot :)

Ray Wai
Ray Wai
2,355 Points
Thanks for the tip Gavin!

3 Answers

Hi Ray,

The !isValidGuess is saying that as long as isValidGuess is not false (true), the while loop which requests input of "Enter a letter: " and checks if the input is a valid guess will repeat. Once a valid guess is provided, then the code can move on to say, "You have x many guesses left".

However, if you take out the ! (not), you're telling your while loop to run as long as the variable you just set to false is true. So, that means it's going to skip the entire while loop - which includes the prompt for a letter because isValidGuess is false by default - and makes the promptForGuess method do nothing.

Hope that helps!

Ray Wai
Ray Wai
2,355 Points

Thanks for the reply Evan.

So can I say interpret the while statement as the following:

  1. In order to run the game for the first time, we need to define a isValidGuess and needs to set it to true(thats why ! isValidGuess), so we can pass it through the while loop for the first time? (Not quite sure about this still)

  2. If the word we guess is valid, we move onto try block and run the applyGuess method as well as setting the isValidGuess variable to true. Since isValidGuess is true, we start the while loop all over again, without activating the catch iae block.

  3. If the word we guess is not valid, we skip the entire try block, and onto the catch iae block, since the isValidGuess is still true, we will start the while loop all over again with the exception of running the applyGuess method. (ps. I have tried adding isValidGuess = true; at the end of the catch block, and it works just fine)

} catch (IllegalArgumentException iae) {
    console.printf("%s.  Please try again.\n", iae.getMessage());
    isValidGuess = true;
}

Hope I am not wrong. thanks again. Ray

Hi Ray,

1) isValidGuess needs to be false for the while loop to run, because the while loop takes not isValidGuess as its condition to run or not. If isValidGuess were true by default instead of false, then not true == false; the while loop would not run.

2) If the letter we enter is valid, isValidGuess is set to true, making the loop false - because the while condition is looking for the opposite of whatever isValidGuess is to determine true or false. A false while loop in the promptForGuess method means that the play() function checks whether its while loop is valid and if so, runs displayProgress() and promptForGuess() again. This goes back to why your always true isValidGuess looped the displayProgress() indefinitely; because the while loop checks !isValidGuess, it was actually always false.

3) If our guess is invalid, we skip the try block (which includes the isValidGuess = true), which means isValidGuess is still false, and not false == true so the loop runs again. Bear in mind that 'not valid' in this case means that validateGuess() is checking whether you entered a number or a letter that's already been guessed. Adding isValidGuess = true to then end of your catch block works fine, because if you break the while loop of promptForGuess(), the while loop of the play() method will just run the displayProgress() and promptForGuess() functions again as long as its own while loop is resulting true.

Ray Wai
Ray Wai
2,355 Points

Evan, thanks a lot for the help, ok so i think I am nearly getting it. Correct me if I am wrong.

  1. In short, for boolean variables to run in while loop, it has to be true? (P.S I tried setting isValidGuess to true at the begining, therefore i put while (isValidGuess), also changing the isValidGuess = true into isValidGuess = false in the try block, everything works just fine.)

  2. In short, if the word is valid, we run mGameApplyGuess() method as well as setting the isValidGuess variable to be the opposite as what we put in the while loop, the reason for that is because we want the opposite of what is in the while loop, so we do not enter it again?

  3. In short, if the word is invalid, we skip the try block, and onto the catch block, since isValidGuess is still false, the while loop is still saying "not false" which is true, so the while loop will run until it goes into the try block? (P.S Adding either isValidGuess = true or isValidGuess = false don't matter at all for the end result).

Thanks again for helping me out.

Ray

Gavin Ralston
Gavin Ralston
28,770 Points

That's correct. While loops will only ever run their code if the condition is true.

while(true) {
  // will run this code
}

while(false) {
  // will not run this code
}

That means that "isValidGuess", which is false could never run the while loop all by its lonesome.

However, through the magic of negation (the ! operator) you flip it to "not false", which is true, and get it to run. :)

while(! somethingFalse) {
}

// really looks like this, because you're plugging in the **opposite** of the value actually held there

while(not false)

// which is...

while(true)

Java while and do-while documentation will come in handy.

Take a look at the do-while statement, which you'll learn about later too, I think. It can make this exact case easier to wrap your head around because you don't have to negate anything. It will run the loop once no matter what, and then check to see if the condition is true. So you could change your code to something entirely different if it's easier to follow:

boolean needValidInput = true;

do {
   // prompt for input, at least once
} while (needValidInput); // then repeat til needValidInput gets turned false

Hi Ray,

1) A while loop needs an expression which evaluates to a boolean for it to be a valid while loop, yes.

2) Yes, the while loop has to close so that the play() loop can run again and displayProgress() before re-entering the while loop of promptForGuess().

3) The catch prints out a notice to try again, but you don't need to be told how many guesses you have remaining again, so it doesn't break the while loop.

It sounds like you've got this down, unless I'm mistaken!

Ray Wai
Ray Wai
2,355 Points

Thanks again Evan and Gavin, I think I am safe and confident enough to move on for now

Gavin Ralston
Gavin Ralston
28,770 Points

Here's the snippet I think you're talking about:

boolean isValidGuess = false;

while (! isValidGuess) {
    String guessAsString = console.readLine("Enter a letter: ");
    char guess = guessAsString.charAt(0);
    try {
        isHit = mGameApplyGuess(guess);
        isValidGuess = true;
    } catch (IllegalArgumentException iae) {
        console.printf("%s.  Please try again.\n", iae.getMessage());
    }
}

So you need a "true" condition to even enter a while loop. That's why you have the first two lines set up the way they are.

You don't have a valid guess yet, so you set isValidGuess to false. Easy enough, right?

Then you run the rest of your code while isValidGuess is false. But your while loop needs a true value to run, so you invert it with the not operator... "not false" == "true"

It'll keep running if you enter invaild guesses because it'll never switch to true if the mGameApplyGuess() method throws an error (instead triggering the code in your catch block)

You'll appreciate having a do/while loop for something like this later on. :)

Ray Wai
Ray Wai
2,355 Points

Thanks Gavin.

I am slowly getting the hang of it, I have typed out my way of thinking it above on replying to Evan's answer, feel free to go take a look and see if I am getting closer to the answer or am I wandering further away from the right path.

Short question here, the isValidGuess is always coming out as true right? No matter where it ends up at, either in the try block or the catch block, so we would always be going through the while looop again endlessly at this point?

Ray.

Grigorij Schleifer
Grigorij Schleifer
10,365 Points

Hi Ray,

the code block inside the loop will repeat if the condition inside the while parenthesis is true ...

while (hungry) {
eat();
}

So I will eat while I am hungry ...if not hungry ... I stop eating ... sory for this silly example :)

Ray Wai
Ray Wai
2,355 Points

Oh nono, your example is perfect, way to "Keep It Simple Stupid". So what if you set your hungry condition to false in the first place, so it makes your supposedly hungry variable becomes full, for example:

public boolean hungry = false;

while (!hungry) {
eat();
}

Does it now say while I am (!)NOT full, I eat?

Grigorij Schleifer
Grigorij Schleifer
10,365 Points

Right!

You are saying:

while (the value of "hungry" is not false) {
// the condition is true
do the loop !

}
Ray Wai
Ray Wai
2,355 Points

So boolean varibales in while loop has to to true in order for it to run?