3
\$\begingroup\$

I have recently begun trying to learn Java and decided to make a basic Hangman game. The game uses a text file to retrieve a random word for the game. I am looking for some general feedback on how I can improve the structure and efficiency of my code.

public class Hangman {
private static int lives = 8;  // live count
private static char guess;  // stores user input
private static String guesses = "";  //string for each letter that has been guessed
private static boolean Solved = false;
private static void check_input(char i, ArrayList<String> word1){  //check if guess is correct and modify variables accordingly
    int count = 0; // keeps track if the guess was found in the word

    for(int a = 0; a < theword.length(); a++){  // loops through each letter in string
        if(theword.charAt(a) == Character.toLowerCase(i)){
            System.out.printf(Character.toUpperCase(i) + " was Correct!\n");
            word1.set(a, Character.toString(i));  // replaces *'s
            count +=1;  // updates count
        }

    }
    if (count == 0){
        lives = lives-1;
    }
    /*
    int pos = theword.indexOf(Character.toLowerCase(i));
    if (pos == -1) {
        lives = lives-1;


        // letter not found
    } else {
        System.out.printf(Character.toUpperCase(i) + " was Correct!\n");
        word1.set(pos, Character.toString(i));
        // letter exists at zero-based position pos
        // CAUTION: it might also exist in later positions!
    }*/
}
    private static void build_hangman(int l) {
    switch (l) {  //switch case for each live case

        case (7):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);

            //System.out.println("      ______________");

            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;
        case (6):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;
        case (5):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         ||      ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;
        case (4):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      ");
            System.out.println("         | |     ");
            System.out.println("         | |     ");
            System.out.println("         | |     ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (3):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |    ");
            System.out.println("         | |     ");
            System.out.println("         | |     ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (2):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |     /|\\");
            System.out.println("         | |      ");
            System.out.println("         | |       ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (1):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |     /|\\");
            System.out.println("         | |      |");
            System.out.println("         | |     ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (0):

            Solved = true;
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |     /|\\");
            System.out.println("         | |      |");
            System.out.println("         | |     / \\");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            System.out.println("Game Over :( The Answer was " + theword);
            System.out.print("Would you like to play again? (y/n) :");

            break;
        default:
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;


    }
}
public static String getword(String f){
    File file = new File(f);
    Random rand = new Random();
    try {


        Scanner scanwords = new Scanner(file).useDelimiter("\n");
        List<String> words = new ArrayList<String>();
        String sb;
        while(scanwords.hasNext()) {
            sb = scanwords.next();
            words.add(sb);

        }


        String[] wordArray = words.toArray(new String[0]);
        String theword = wordArray[rand.nextInt(wordArray.length)];// pick random word from those stored in array
        //
        System.out.println(theword); //debug print code comment out to not see answer
        return theword; // return it
    }
    catch (FileNotFoundException e){
        System.out.println("Looks Like your File Got an Error");  // catch invalid file exception


        System.exit(0);
        return "error";
    }


}
public static String theword;
private static final String filename = PUT FILE NAME HERE IN QUOTES;//be sure put exact location

public static void main(String args[]) {
    ArrayList<String> placeholder = new ArrayList<String>();
    Scanner input = new Scanner(System.in);
    char[] correct = {};
    char guess;// guess char


        while (true) {  //game loop
            System.out.println("Lets Play Hangman! You will be allowed " + lives + " incorrect guesses. Good Luck!");
            theword = getword(filename);// call get word function
            for (int i = 0; i < theword.length() - 1; i++) {

                placeholder.add(Character.toString('*'));
            }
            while (Solved == false) {

                if (placeholder.contains(Character.toString('*'))) {
                    Solved = false;
                } else {
                    //System.out.println(placeholder);
                    System.out.println("You Win! You correctly guessed " + theword);


                        Solved = true;
                        System.exit(0);//debug


                }
                System.out.printf("Live Count: %d \t", lives); //display lives
                System.out.print("The Word:  ");  // display word placeholders
                System.out.print(placeholder + "   ");
                if (guesses != null && !guesses.isEmpty()) { // check if player has guessed
                    System.out.println("Guesses  " + guesses); // display guesses
                } else {
                    System.out.println("Guesses:   None");
                }
                System.out.print("Guess a Letter: ");
                guess = input.next().charAt(0);//get first char of input
                guesses += guess; //add gues to string of guesses
                check_input(guess, placeholder); // call check_input method
                build_hangman(lives); // print hangman based on no. of lives


            }
            System.exit(0);// exit if solved
        }


    }
    //public boolean check_guess(){
    //   if (


}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
private static int lives = 8;  // live count
private static char guess;  // stores user input
private static String guesses = "";  //string for each letter that has been guessed
private static boolean Solved = false;

You generally don't want to make everything static.

    private int lives = 8;
    private String guesses = "";
    public String theword;

The static keyword means that every instance of the class shares that same value. But here you want each Hangman game to have a different value.

I'm not a big fan of comments to the right of code. I'd rather have them on separate lines. Here you were probably overcommenting, so I just removed them. Comments shouldn't just restate the code. They should tell us why the code is doing what it does.

The guess variable should not need to be shared across multiple methods this way. It would be more common for it to move as a return value or a parameter.

You only use Solved in one method. It doesn't need to be a field and shared among the methods. It can just be a local variable.

The field declarations should be indented from the enclosing class.

private static void check_input(char i, ArrayList<String> word1){  //check if guess is correct and modify variables accordingly

This shouldn't be static either.

    private void check_input(char guess, List<String> word1) {

It accesses internal state.

What's i? It looks like it's the current guess. Why not call it that? That would also leave i available later when you are doing the loop.

I changed the ArrayList to a List. As a general rule, we want types to be the interface rather than the implementation. This makes it easier to swap implementations later, as we code to the interface.

You may want to consider using a more specialized type, like a StringBuilder rather than a List.

            count +=1;  // updates count

More idiomatically written as

            count++;

Similarly,

        lives = lives-1;

could be written

        lives--;

In main, you need to create an object:

        Hangman game = new Hangman();
        game.play();

Then move most of the contents of the while (true) { loop into play. That will allow you to remove the static keyword.

See

public class Hangman {

    private static final String filename = "replace with correct path";
    public static Scanner input = new Scanner(System.in);
    private static Random rand = new Random();

    private int lives = 8;  // live count
    private Set<Character> guesses = new HashSet<>();
    public String theword;

    private void check_input(char guess, List<Character> word1) {  //check if guess is correct and modify variables accordingly
        int count = 0; // keeps track if the guess was found in the word

        for (int a = 0; a < theword.length(); a++) {  // loops through each letter in string
            if (theword.charAt(a) == Character.toLowerCase(guess)){
                System.out.printf(Character.toUpperCase(guess) + " was Correct!\n");
                word1.set(a, guess);  // replaces *'s
                count++;  // updates count
            }
        }

        if (count == 0){
            lives--;
        }
    }

    private static void build_hangman(int l) {
        switch (l) {  //switch case for each live case

        case (7):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);

            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;
        case (6):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;
        case (5):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         ||      ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;
        case (4):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      ");
            System.out.println("         | |     ");
            System.out.println("         | |     ");
            System.out.println("         | |     ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (3):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |    ");
            System.out.println("         | |     ");
            System.out.println("         | |     ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (2):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |     /|\\");
            System.out.println("         | |      ");
            System.out.println("         | |       ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (1):
            System.out.printf("Incorrect! Try Again! You have %d Lives\n", l);
            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |     /|\\");
            System.out.println("         | |      |");
            System.out.println("         | |     ");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            break;
        case (0):

            System.out.println("      ______________");

            System.out.println("         | |      |");
            System.out.println("         | |      0");
            System.out.println("         | |     /|\\");
            System.out.println("         | |      |");
            System.out.println("         | |     / \\");
            System.out.println("         | |");
            System.out.println("         | |");
            System.out.println("   ___________");
            System.out.println("Game Over :( The Answer was " + theword);
            System.out.print("Would you like to play again? (y/n) :");

            break;
        default:
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("         ||");
            System.out.println("   ___________");
            break;
        }
    }

    public static String getword(String f){
        File file = new File(f);
        try (Scanner scanwords = new Scanner(file)) {
            List<String> words = new ArrayList<String>();

            while (scanwords.hasNext()) {
                String sb = scanwords.nextLine();
                words.add(sb);
            }

            theword = words.get(rand.nextInt(words.size()));
            //
            System.out.println(theword); //debug print code comment out to not see answer
            return theword; // return it
        }
        catch (FileNotFoundException e){
            System.out.println("Looks Like your File Got an Error");  // catch invalid file exception

            System.exit(0);
            return "error";
        }
    }

    public void play() {
        System.out.println("Let's Play Hangman! You will be allowed " + lives + " incorrect guesses. Good Luck!");
        theword = getword(filename);// call get word function
        List<Character> placeholder = new ArrayList<>(theword.length());
        for (int i = 0; i < theword.length() - 1; i++) {
            placeholder.add('*');
        }

        while (lives > 0) {
            if (!placeholder.contains('*')) {
                System.out.println("You Win! You correctly guessed " + theword);

                System.exit(0);//debug
            }

            System.out.printf("Live Count: %d \t", lives); //display lives
            System.out.print("The Word:  ");  // display word placeholders
            System.out.print(placeholder + "   ");
            if (guesses != null && !guesses.isEmpty()) { // check if player has guessed
                System.out.println("Guesses  " + guesses); // display guesses
            } else {
                System.out.println("Guesses:   None");
            }
            System.out.print("Guess a Letter: ");
            char guess = input.next().charAt(0);//get first char of input
            guesses.add(guess); //add gues to string of guesses
            check_input(guess, placeholder); // call check_input method
            build_hangman(lives); // print hangman based on no. of lives


        }
        System.exit(0);// exit if solved
    }

    public static void main(String args[]) {

        while (true) {  //game loop
            Hangman game = new Hangman();
            game.play();
        }
    }

}

This is how to use static and object fields (class variables).

\$\endgroup\$
2
  • \$\begingroup\$ When I remove the 'static' keywords, I receive this error: java: non-static variable lives cannot be referenced from a static context. Do I need to change where i declare the variables? \$\endgroup\$
    – DIYGuy3030
    Aug 4, 2017 at 13:16
  • \$\begingroup\$ @DIYGuy3030 I added more information about how to use non-static variables. \$\endgroup\$
    – mdfst13
    Aug 5, 2017 at 2:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.