How to program the Hangman game in Java

As part of the articles How to program a game in Java, we have prepared for you a well-known game that we used to play in primary school. The aim of the game is to guess a hidden word, or more words, or even a whole sentence by gradually guessing the letters that make it up. The challenge, however, is that the number of guesses is limited by the number of unguessed letters. If the number of unsuccessful attempts reaches a certain threshold, the player has not guessed the riddle and has lost.

How to program the Java game Hangman (hangman, hangman, hangman)
How to program the Java game Hangman (hangman, hangman, hangman)

V článku sa dozvieš:

    You probably already know what the game is about. It’s the game Hangman (or Hanged Man or Hangman), known in English as Hangman. Today you’ll be able to program it in your favourite programming language – Java, for example.

    Game Hangman – rules

    Hangman is a guessing game for two or more players, usually played with pen and paper. These are all the tools that players need. The object of the game is to reveal the hidden word in a letter-by-letter manner. One of the players comes up with a clue and indicates the number of its letters by drawing the corresponding number of blank boxes. The remaining players then guess the individual letters they think the riddle might contain.

    After each letter is spoken, the first player writes the guessed letter in all positions where it occurs in the word in all positions of the puzzle. Or, if the letter does not appear in the clue at all, the first player draws one part of the picture of the doll on the gallows.

    The game is won by the player who guessed the riddle, if the other player (or players) fails to guess the riddle before that picture is rolled to the end. Conversely, if the word is guessed earlier, the guessing player(s) wins the game.

    The exact diagram of the figure on the gallows and how many parts it is composed of is not part of the rules, so it depends on the players’ agreement. The difficulty of the game can be varied, e.g. in addition to the aforementioned parts of the gallows, it is possible to restrict the hints of frequent consonants and vowels. To make the game easier, a specification of the category to which the word belongs can be used, e.g. plants, animals, etc.

    Exactly how and when the game was created is unknown, but it is believed to have been in the 19th century. A number of television competitions were based on a similar principle, where contestants were financially rewarded for guessing the correct letters and guessing the riddle.

    Did you know that?
    The Hanged Man game is often played in school lessons, e.g. in foreign language classes. Instead of a morbid gallows, an apple tree is used with a certain number of apples that are crossed or wiped off the board.

    The Hanged Man Game Concept

    Since Christmas has recently ended, we will be guessing Christmas-themed expressions in our game. Our program will first read from the dictionary (data file) vianoce.txt located on the classpath all the lines that will represent words that have some relation to Christmas. The game will then randomly select one of them and display it on the console using underscores separated by a space. For example, if the game selects the word snow, it will appear on the screen as: _ _ _ _.

    The game prompts the player to guess the letter he thinks is in the puzzle. The letters that are guessed have no punctuation marks such as longs and softens. To simplify the game, all letters in the riddle are written in capital letters.

    So if the player types in his guess that the letter is “s” or “S” (these are equivalent), the game converts it to a capital letter and searches for it in the puzzle. If the guessed letter is in the puzzle, it adds it to all relevant places.

    If it is not found, then instead of drawing the gallows, the game status will be continuously displayed – the number of letters of the word “END OF GAME”, which will correspond to the number of unsuccessful guesses of the letters that were not in the puzzle.

    This means that after 10 unsuccessful guesses, the full “END OF GAME” is displayed and the game round ends and a new game begins, with a new Christmas word. In our case, the letter “S” is in the clue, so the clue will be completed with this letter: S _ _ _. We can show the player the correctly guessed letter in green, the unguessed letter in red. Unsuccessful letter guesses can be shown on the screen in blue, separated by a comma.

    The game will be played for a predefined number of rounds, which will be specified when the game instance is created.

    Implementation of the Hanged Man (Hangman) game

    This program is a simple console game where the game chooses one of the Christmas-themed words and the player guesses the letters that are found in the clue. The round of the game ends after guessing the cryptic letter or after 10 unsuccessful guesses.

    ChristmasHangman class
    Class ChristmasHangman implements the overall game logic with Christmas phrases.

    package games;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.Scanner;
    
    public class ChristmasHangman {
        private static final String COLOR_RESET = "\u001B[0m";
        private static final String COLOR_RED = "\u001B[31m";
        private static final String COLOR_GREEN = "\u001B[32m";
        private static final String COLOR_BLUE = "\u001B[34m";
    
        private List<String> words;
        private int rounds;
        private static final int MAX_WRONG_GUESSES = 10;
        public  ChristmasHangman(String dictionaryPath, int rounds) throws IOException {
            this.words = Files.readAllLines(Paths.get(dictionaryPath));
            this.rounds = rounds;
        }
    
        public void startGame() {
            Scanner scanner = new Scanner(System.in);
            int currentRound = 1;
    
            while (currentRound <= rounds) {
                System.out.println("\nKolo " + currentRound + "/" + rounds);
                String word = getRandomWord().toUpperCase();
                playRound(word, scanner);
                currentRound++;
            }
    
            System.out.println("\nHra skončila. Ďakujeme za hranie!");
        }
    
        private String getRandomWord() {
            Random random = new Random();
            return words.get(random.nextInt(words.size()));
        }
    
        private void playRound(String word, Scanner scanner) {
            StringBuilder hiddenWord = initializeHiddenWord(word);
            List<Character> wrongGuesses = new ArrayList<>();
            int wrongGuessCount = 0;
    
            while (wrongGuessCount < MAX_WRONG_GUESSES) {
                System.out.println("\nTajnička: " + hiddenWord);
                System.out.println("Zlé tipy: " + formatWrongGuesses(wrongGuesses));
                System.out.print("Hádať písmeno: ");
                String guess = scanner.nextLine().toUpperCase();
    
                if (guess.length() != 1 || !Character.isLetter(guess.charAt(0))) {
                    System.out.println("Neplatný vstup! Skús jedno písmeno.");
                    continue;
                }
    
                char guessedChar = guess.charAt(0);
                if (hiddenWord.toString().contains(String.valueOf(guessedChar)) || wrongGuesses.contains(guessedChar)) {
                    System.out.println("Písmeno už bolo hádané! Skús iné.");
                    continue;
                }
    
                if (word.contains(String.valueOf(guessedChar))) {
                    revealLetter(hiddenWord, word, guessedChar);
                    System.out.println(COLOR_GREEN + "Písmeno " + guessedChar + " bolo doplnené." + COLOR_RESET);
                    if (!hiddenWord.toString().contains("_")) {
                        System.out.println("\nGratulujem! Uhadol si výraz: " + word);
                        return;
                    }
                } else {
                    wrongGuesses.add(guessedChar);
                    wrongGuessCount++;
                    System.out.println(COLOR_RED + "Písmeno " + guessedChar + " nie je v tajničke." + COLOR_RESET);
                    System.out.println("Stav: " + "KONIEC HRY".substring(0, wrongGuessCount));
                }
            }
    
            System.out.println("\nPrehral si! Hľadaný výraz bol: " + word);
        }
    
        private StringBuilder initializeHiddenWord(String word) {
            StringBuilder hiddenWord = new StringBuilder();
            for (char c : word.toCharArray()) {
                if (Character.isLetter(c)) {
                    hiddenWord.append("_ ");
                } else {
                    hiddenWord.append(c).append(" ");
                }
            }
            hiddenWord.deleteCharAt(hiddenWord.length() - 1); // Remove last space
            return hiddenWord;
        }
    
        private void revealLetter(StringBuilder hiddenWord, String word, char guessedChar) {
            for (int i = 0; i < word.length(); i++) {
                if (word.charAt(i) == guessedChar) {
                    hiddenWord.setCharAt(i * 2, guessedChar);
                }
            }
        }
    
        private String formatWrongGuesses(List<Character> wrongGuesses) {
            StringBuilder formatted = new StringBuilder();
            for (char c : wrongGuesses) {
                formatted.append(COLOR_BLUE).append(c).append(COLOR_RESET).append(", ");
            }
            return formatted.length() > 0 ? formatted.substring(0, formatted.length() - 2) : "žiadne";
        }
    }
    
    

    Constructor and key methods

    ChristmasHangman(String dictionaryPath, int rounds)
    Retrieves words from the file christmas.txt and stores them in the words list.
    Sets the number of rounds.

    StartGame()
    Starts the game for the specified number of rounds.
    Randomly selects a word to guess and calls the playRound() method.

    getRandomWord()
    Randomly selects one word from the list of words.

    playRound(String word, Scanner scanner)
    Implements the main logic of a single round of play as follows:
    The puzzle (hiddenWord) replaces letters with underscores, leaving other characters (e.g., spaces).
    The player guesses the letters to be checked in the expression. Correct guesses complete the secret word, incorrect guesses are recorded in the list of incorrect attempts. If the player guesses the whole word, the round ends with congratulations. When the maximum number of incorrect attempts has been reached, the round is ended by revealing the search term.

    initializeHiddenWord(String word)
    Creates a secret: underscores for letters and leaves the other characters.

    revealLetter(StringBuilder hiddenWord, String word, char guessedChar)
    Replaces underscores with the correct letter in all places where it appears in word.

    formatWrongGuesses(List<Character> wrongGuesses)
    Merges the incorrect characters into a string with blue color.

    Main Class

    import games.ChristmasHangman;
    
    import java.io.IOException;
    
    public class Main {
        public static void main(String[] args) {
            String dictionary = "vianoce.txt";
            int rounds = 10;
            try {
                ChristmasHangman game = new ChristmasHangman(dictionary, rounds);
                game.startGame();
            }
            catch (IOException e) {
                System.out.println("Chyba pri načítavaní slovníka: " + e.getMessage());
            }
        }
    }
    

    The Main class checks that the specified expression dictionary is available, creates an instance of the game, and runs it.

    How the Hanged Man game works

    1. The game retrieves a list of words from the dictionary and then for each round, randomly selects one expression for the player to guess.
    2. The player is shown the legend of the puzzle, but it is hidden and only the empty positions (underscores) for the letters are visible. Other characters (spaces, digits) are visible from the beginning.
    3. The player guesses the letters, with the colours distinguishing: correct guess (green), incorrect guess (red) and previous incorrect guesses (blue).
    4. The round ends if the player guesses the expression or exhausts all 10 incorrect attempts. For each incorrect guess, the player receives one letter of the word : “END OF GAME”. This is a sort of non-violent version of Hangman, so the game is suitable for young children.
    5. After all rounds have been played, the software will thank the player for playing the game.

    The output of one round of the game can look like this:

    Hangman Output

    Exercise

    The program can be further played around with to make guessing expressions easier or harder. As an exercise, you can also try to incorporate statistics into the game to see how many rounds a player wins and how many of them he loses. You can also create different kinds of dictionaries on different topics and pick a clue at random from multiple dictionaries, with you telling the guesser which category the expression belongs to.

    Download the source codes for ChristmasHangman.

    About the author

    Jozef Wagner

    Java Developer Senior

    I have been programming in Java for more than 10 years, currently I am working in msg life Slovakia as a senior Java programmer and I help customers to implement their requirements into Life Factory insurance software. In my free time I like to relax in the mountains or play a good computer game.

    Let us know about you