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

Grigorij Schleifer
Grigorij Schleifer
10,365 Points

I am lost ...

Hey guys, i dont understand the whole story here ....

 private char validateGuess (char letter){
    if (! Character.isLetter(letter)) {
       throw new IllegalArgumentException ("A letter is required");
       }
         letter = Character.toLowerCase(letter);

            if(mMisses.indexOf(letter)>= 0 || mHits.indexOf(letter) >= 0) {
                throw new IllegalArgumentException (letter + "has already been guessed");
    }
             return letter;
  }

How does the method validateGuess() knows the letter we typed in ???

In the promptForGuess () method we store our guess in "guess" and send it to mGame via return mGame.applyGuess(guess);

 public boolean promptForGuess () {
       Console console = System.console();
       String guessAsString = console.readLine ("Enter a letter:  ");
       char guess = guessAsString.charAt(0);
       return mGame.applyGuess(guess); 
  }

But in Game, i can´t see any "guess", just a h..... of a lot of "letter"

:(

3 Answers

Adam Ebeid
Adam Ebeid
3,240 Points

For the first part of your question, the validateGuess function invokes when it is called by applyGuess function passing the parameter or the letter.

  public boolean promptForGuess () {
       Console console = System.console();
       String guessAsString = console.readLine ("Enter a letter:  ");
       char guess = guessAsString.charAt(0);
       return mGame.applyGuess(guess); // -----> call the function applyGuess
  }
  public boolean applyGuess(char letter) {
      letter = validateGuess(letter); // ------> call the validateGuess function
      boolean isHit = mAnswer.indexOf(letter) >= 0;
      if (isHit) {
          mHits += letter;
      } 

      else {
          mMisses += letter;
      }
  return isHit;
  }

for the second part of your question, indexOf method checks whether a given input exists into a variable or not.

Let's assume you have a box of eggs. The box has a row of 8 places. The row has each egg named as follows, EggA, EggB, EggC, EggD, EggE, EggF, EggG, EggH.

Let say we want to know the location of EggC. We know that we have 8 rows in total and the row starts from number

  1. So 0-7 is how we count. if we say Eggbox.indexOf("EggB"), this will return number 1 because EggB exists into the second place in the box of eggs. When we type "if (Eggbox.indexOf("EggB") >= 0)" we are asking, is the returned value of Eggbox.indexOf("EggB") bigger than or equals 0? The answer is yes, and it is 1. If we asked Eggbox.indexOf("EggZ"), we would get "-1" because EggZ does not exist into our egg box.

Back to your question, "mMisses.indexOf(letter)>= 0" what this does(indexOf method) is, it goes to the mMisses variable and asks it, do you have this letter(the one the user passed) then it answers with either the location of that letter or -1 which means no I don't have that one.

ex:

String mMisses = "hide";

mMisses.indexOf('d'); this will return 2 because the "d" location is 2, counting from 0. 0 = h, 1 = i, 2 = d, 3 = e.

storing mMisses.indexOf('d'); into a boolean variable.

boolean doesItExists = mMisses.indexOf('d') >= 0 // -->> will give us either true or false because the type of the variable we are storing the information here is a boolean. in this case this will return true because the letter 'd' exists and it is greater than 0.

Hope that makes sense.

Kris B
Kris B
11,107 Points

As far as I can tell, the validateGuess() method doesn't know anything about 'guess'. Unless at some point else where 'guess' is stored as 'letter', but that's not in the above code. If 'letter' were changed to 'guess' it would work, so you're right in wondering what's going on in the validateGuess() method.

I've annotated the code if that helps.

private char validateGuess (char letter){

    // if letter is a letter (not a number or symbol), throw exception
    if (! Character.isLetter(letter)) {
        throw new IllegalArgumentException ("A letter is required");
    }

    // convert letter to lowercase
   letter = Character.toLowerCase(letter);

   // checks if letter has already been guessed
   if(mMisses.indexOf(letter)>= 0 || mHits.indexOf(letter) >= 0) {
       throw new IllegalArgumentException (letter + "has already been guessed");
    }
       // return letter if there's no exceptions
       return letter;
}
Grigorij Schleifer
Grigorij Schleifer
10,365 Points

I don´t understand the consept behind the line :

if(mMisses.indexOf(letter)>= 0 || mHits.indexOf(letter) >= 0)

can someone explain it to me please ...

And in the code above i see more then 5 "letter" - where do they come from ....

the "indexOf()" method returns the index postion(number) of a specific character inside of a string, and since "mMisses" and "mHits" store the missed and hit letters as strings if we guess the same letter the index position found by the "indexOf()" method will return it greater than or equal to 0 because it has already been stored inside of the mHits and mMisses member variables, and it consequently will throw the new IllegalArgumentException of "that specific letter + has already been guessed" since it has already been stored inside of mHits and mMisses as a string depending on whether that specific letter that was guessed before was a hit or miss.

Feel free to correct me if I am wrong this is just my understanding of it. I hope this helps.