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

Is there a reason why I need this return statement from the example, if so, could you explain why?

Here are my three classes for you to see.

import java.util.Scanner;

class Prompter  {
  private Game game;

  public Prompter(Game game) {
    this.game = game;
  }

  public boolean promptForGuess() {
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter a letter:   ");
    String guessInput = scanner.nextLine();
    char guess = guessInput.charAt(0);
    boolean isHit = false;
    try {
      isHit= game.applyGuess(guess);
    } catch(IllegalArgumentException iae) {
      System.out.println(iae.getMessage());
    }

   return isHit;
  }

  public void displayProgress() {
    System.out.printf("You have %d tries left to solve:   %s%n", game.getRemainingTries(), game.getCurrentProgress()); 
  }
}
class Game {
  public static final int MAX_MISSES = 7;
  private String answer;
  private String hits;
  private String misses;

  // Class Constructor
  public Game(String answer) {
    this.answer = answer;
    hits = "";
    misses = "";
  }

  public boolean applyGuess(char letter) {
    if (hits.indexOf(letter) != -1 || misses.indexOf(letter) != -1) {
      throw new IllegalArgumentException(letter + " has already been guessed"); 
    } 
    boolean isHit = answer.indexOf(letter) != -1;
    if (isHit) {
      hits += letter;
    } else {
      misses += letter;
    }
    return isHit;                               
  }

  public int getRemainingTries() {
    return MAX_MISSES - misses.length();
  }

  public String getCurrentProgress() {
    String progress = "";
    for (char letter : answer.toCharArray()) {
      char display = '-';
      if (hits.indexOf(letter) != -1) {
        display = letter;
      }
      progress += display;
    }
    return progress;
  }
}
public class Hangman {

  public static void main(String[] args) {
    // Create new instance of Game
    Game game = new Game("treehouse");
    Prompter prompter = new Prompter(game);
    while (game.getRemainingTries() > 0) {
      prompter.displayProgress();
      prompter.promptForGuess();
    }
  }
}

Is there a reason that Prompter.prompForGuess(); is returning a value at this point in the example? Nothing seems to call the method that needs a return value, and the program seems to run when I remove it myself. Am I missing something? ...

I have not gone on to other examples yet so its possible it is used in the future, but for now is my thought process correct? Thanks for the help!

3 Answers

Jason,

I see no reason why a return statement for promptForGuess() or applyGuess() would be necessary, apart from the facts that both method declarations currently indicate a boolean return value, and the local variable isHit in promptForGuess() is assigned to a call to the method applyGuess(). If you change the return type on promptForGuess() to void and remove the return statement, the program should still run. The try-catch block in promptForGuess() attempts to call applyGuess(), and if the method executes and returns successfully, promptForGuess() attempts to assign the return value from applyGuess() to the local variable isHit. It will still go through this process whether or not isHit is returned at the end of the method. As the program is currently written, returning isHit in promptForGuess() seems to have no effect.

In applyGuess(), the same is true. However, changing the return type in applyGuess() to void and removing the return statement at the end of the method will result in a NoSuchMethodError when a user attempts to guess a letter. I believe this is because inside promptForGuess(), your program is attempting to assign the return value from applyGuess() to the local variable isHit. When you convert applyGuess() into a void method, it no longer returns a value, and promptForGuess() ends up searching for a version of applyGuess() with a return value to assign to isHit. Because no such version of applyGuess() exists, the program throws a NoSuchMethodError. To fix this, simply remove the assignment of the local variable isHit to the method applyGuess() in promptForGuess(). Just call applyGuess() in the try block instead.

As you continue with this program, you will end up writing another version of the applyGuess() method (in other words, overloading the method). The additional version of applyGuess() will also include a return statement that returns a call to the original version of applyGuess(). You will need to make sure that the additional version of applyGuess() is also a void method and it only calls the other version of applyGuess(), rather than attempting to return it.

It is certainly possible that I have missed something in my analysis. If someone notices something I have missed, please let me know.

I hope that helps. Best of luck!

This help so much, and is exactly what I was looking for. Thank you so much!

I believe that it is used as a way to determine if a hit or miss was scored and may be implemented later. I do not see anything using that particular boolean value at this point though.

How about the return statement in applyGuess();? As I understand it, the return value is there because the try..catch statement is passing the argument and requires a response since it is a boolean statement. Is my thinking correct or am I missing something? I'm just trying to wrap my head around how this works before moving on!

The return statement, as best as I can tell, is there as a result to applyGuess(), when applyGuess() is called in promptForGuess()'s try block, it is seeing if it is possible. Otherwise the value for isHit defaults to 'false'.

I think I may be misunderstanding your question, but I do think you are correct in that the method promptForGuess() must have a return statement of type boolean.

If applyGuess() sets isHit to 'true' or 'false', the method will exit on that return and nothing below the 'try' block will even be attempted to execute. Otherwise the second return is a fallback if the try-catch block fails.

I'm sorry if that doesn't help, I'm not sure I am being as clear as I would hope.

I guess I’m just trying to work out how this programming is running as is. To connect the dots if you will. The return statement in applyGuess(); seems to be holding me back. I haven’t tried it yet, but would that try..catch statement work correctly if the method was void and the return statement was removed? It seems if it were removed that would keep promptForGuess(); from applying true or false, thus making it unable to pass the argument through due to out of scope issues in the catch.. try statement. I think that is what is going on but some kind of affirmation from someone more experienced would make me feel a lot better.

I am probably not the best person to give an answer, hopefully someone more experienced will chime in soon. It sounds like you understand it decently though.

As the program stands currently, if applyGuess() is converted to a void function, the 'catch' block will throw an exception which will force exit the program.

If the try{} catch{} is removed, but the applyGuess() method is left as a void function, it will still throw an error as you are attempting to pass a void function into a variable, or essentially trying to pass nothing into a variable.

The return statement after the try{} catch{} is more or less there to provide a guaranteed return from the method.