Johnny92
Johnny92

Reputation: 37

Simple Hangman in Java. It should work but it doesn't

I am trying to make it print the word with letters that have been guessed and "*" instead of letters that haven't been guessed.

This is the part that doesn't work. I analyzed every line but I can't find out what do I do wrong :( When I write letter "e" I get "*******" instead of "e******"

 for (int i = 0; i < word.length(); i++) {
                        char letter = word.charAt(i);
                        if (command.equals(letter)) {
                            System.out.print(letter); 
                        }
                        else {
                            System.out.print('*');

                        }
 }

Whole code:

package hangman;
import java.util.Scanner;
import java.util.ArrayList;

public class Hangman {


public static void main(String[] args) {
    Scanner reader = new Scanner(System.in);
    ArrayList<String> wordList = new ArrayList<String>();
    String word = "economy";
    System.out.println("************");
    System.out.println("* Hangman *");
    System.out.println("************");
    System.out.println("");
    System.out.println("");

    while (true) {

    System.out.println("Choose a letter!");
    String command = reader.nextLine(); 
        if (command.length() == 1) {
            guess(command); 
                if (word.contains(command) && !wordList.contains(command)) {
                    wordList.add(command);
                    System.out.println(wordList.size());
                   // System.out.println(word.replaceAll("[^" + wordList + "]", "?"));
                    for (int i = 0; i < word.length(); i++) {
                        char letter = word.charAt(i);
                        if (command.equals(letter)) {
                            System.out.print(letter); 
                        }
                        else {
                            System.out.print('*');

                        }
                    }
                }
        }
        else {
            System.out.println("Write only 1 letter!");
        }

    System.out.println("Thank you for playing!");
    }
}

public static void guess(String command) {
    String word = "economy";
  if (word.contains(command)) {
      System.out.println("Yes, the letter - " + command + " - is in the word" );


  } else {
      System.out.println("The letter - " + command + " - is NOT in the word" );

  }

}

}

I know I should make separate methods, but I'm trying just to make it work at first (it seems easier for me if I've got all in one place for now) and then I will make it less messy

Thanks for help

Upvotes: 0

Views: 131

Answers (4)

bkis
bkis

Reputation: 2587

Always nice to code some simple game! Your implementation had some flaws and logical issues that would be difficult do explain in words - so let me show you commented code. I hope it's OK I refactored your code a bit:

import java.util.Scanner;
import java.util.ArrayList;

public class Hangman {

    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in); //initialize scanner for user input
        ArrayList<Character> guessedLetters = new ArrayList<Character>(); //already guesed chars (ant NOT Strings!)
        int guessCount = 0; //count guesses (because this can be more than guessedLetters.size() !)
        String word = "economy"; //your test word
        word = word.toUpperCase(); //normalize word to upper-case letters

        //print welcome banner
        System.out.println("************");
        System.out.println("* Hangman *");
        System.out.println("************\n\n");

        String command; //variable to hold the "command", outside of while

        //now the game loop begins (input is asked INSIDE WHILE CONDITION!)
        //if input is "exit", game exits
        System.out.print("Guess your first letter: ");
        while (!(command = reader.nextLine()).equalsIgnoreCase("exit")) {
            //check length right at beginning of loop!
            if (command.length() != 1) {
                System.out.println("Your input must be only one character!");
            } else {
                //get upper-case character from command
                char letter = command.toUpperCase().charAt(0);
                //check if guess is correct
                if (word.contains(String.valueOf(letter)) && !guessedLetters.contains(letter)) {
                    //add letter to guessed letters
                    guessedLetters.add(letter);
                    //display guess count
                    System.out.println("Correct! You already had " + (++guessCount) + " guess(es).");
                    //display game state
                    for (char c : word.toCharArray()) {
                        //short-hand comparison (ternary operator) of chars! Don't compare Strings with chars!
                        System.out.print(guessedLetters.contains(c) ? c : '*');
                    }
                } else {
                    System.out.println("No, that's wrong! You already had " + (++guessCount) + " guess(es).");
                }
            }
            System.out.print("\n\nGuess your next letter: ");
        }

        System.out.println("Thank you for playing!"); //say good bye
        reader.close(); //close scanner!
    }
}

Of course, you still need the logic to check if the game is won/lost. But now that everything is where it belongs, this should be no problem for you!
I hope this helps! Keep it up!

Upvotes: 1

TheWhiteRabbit
TheWhiteRabbit

Reputation: 1313

The correct solution would be to replace your test:

if (command.equals(letter)) {
  ...
}

With:

if (wordList.contains(Character.toString(letter))) {
  ...
}

In your current approach you're comparing a String with a char, which will always be false. Additionally you only compare the last entered character, meaning you'll only visibly print the last guessed character instead of all correctly guessed characters.

Upvotes: 0

Usagi Miyamoto
Usagi Miyamoto

Reputation: 6329

You are calling equals() with a char argument, which would never be equal to the String you are calling it on...

Try something like this instead:

if (command.charAt(0) == letter) {

Upvotes: 1

Vincent Passau
Vincent Passau

Reputation: 822

You compare a String and a char so the result is always false. Try to replace this code :

if (command.equals(letter)) {
    System.out.print(letter); 
}

By this code :

if (command.equals(Character.toString(letter)) {
    System.out.print(letter); 
}

From javadoc of Character :

/**
 * Returns a {@code String} object representing the
 * specified {@code char}.  The result is a string of length
 * 1 consisting solely of the specified {@code char}.
 *
 * @param c the {@code char} to be converted
 * @return the string representation of the specified {@code char}
 * @since 1.4
 */
public static String toString(char c) {
    return String.valueOf(c);
}

NB: you should close() that Scanner when you don't need it anymore.

Upvotes: 0

Related Questions