Learn to Build Hangman in Python

The following is an excerpt from The Self-Taught Programmer: The Definitive Guide to Programming Professionally that teaches you how to build Hangman in Python. 

In this chapter, you are going to combine the concepts you’ve learned so far and build a text-based game, the classic Hangman. If you’ve never played Hangman, here’s how it works:

1. Player One picks a secret word and draws a line for each letter in it (you will use an underscore to represent each line).
2. Player Two tries to guess the word one letter at a time.
3. If Player Two guesses a letter correctly, Player One replaces the corresponding underscore with the correct letter. In this version of the game, if a letter appears twice in a word, you have to guess it twice.
OR
If Player Two guesses incorrectly, Player One draws a body part of a hanged stick figure (starting with the head).
4. If Player Two completes the word before the drawing of the hangman is complete, they win. If not, they lose.

Hangman
Hangman

In your program, the computer will be Player One, and the person guessing will be Player Two. Are you ready to build Hangman? 

Here is the beginning of your Hangman code:

# http://tinyurl.com/jhrvs94
 
 
def hangman(word):
    wrong = 0
    stages = ["",
             "________        ",
             "|               ",
             "|        |      ",
             "|        0      ",
             "|       /|\     ",
             "|       / \     ",
             "|               "
              ]
    rletters = list(word)
    board = ["__"] * len(word)
    win = False
    print("Welcome to Hangman")

First, you create a function called hangman to store the game. The function accepts a variable called word as a parameter; this is the word Player Two has to guess. You use another variable, wrong, to keep track of how many incorrect letters Player Two has guessed.

The variable stages is a list filled with strings you will use to draw your hangman. When Python prints each string in the stages list on a new line, a picture of a hangman forms. The variable rletters is a list containing each character in the variable word that keeps track of which letters are left to guess.

The variable board is a list of strings used to keep track of the hints you display to Player Two, e.g., c__t if the word is cat (and Player Two has already correctly guessed c and t). You use [“__”] * len(word) to populate the board list, with an underscore for every character in the variable word. For example, if the word is catboard starts as [“__”, “__”, “__”].

You also have a win variable that starts as False, to keep track of whether Player Two has won the game yet. Next, you print Welcome to Hangman.

The next part of your code is a loop that keeps the game going:

while wrong < len(stages) - 1:
    print("\n")
    msg = "Guess a letter"
    char = input(msg)
    if char in rletters:
        cind = rletters \
               .index(char)
        board[cind] = char
        rletters[cind] = '$'
    else:
        wrong += 1
    print((" ".join(board)))
    e = wrong + 1
    print("\n"
          .join(stages[0: e]))
    if "__" not in board:
        print("You win!")
        print(" ".join(board))
        win = True
        break

Once you are inside your loop, print a blank space to make the game look nice when it prints in the shell. Then, collect Player Two’s guess with the built-in input function and store the value in the variable guess.

If guess is in rletters (the list that keeps track of the letters in the word that Player Two hasn’t guessed yet), the player guessed correctly. If the player guessed correctly, you need to update your board list, which you use later in the game to display the letters remaining. If Player Two guessed c, you would change your board list to [“c”, “__”, “__”].

To do this, you use the index method on your rletters list to get the first index of the letter Player Two guessed, and use it to replace the underscore in board at the index with the correctly guessed letter.

There is one problem with this. Because index only returns the first index of the character you are looking for, your code will not work if the variable word has more than one of the same character. To get around this, modify rletters by replacing the character that was correctly guessed with a dollar sign, so the next time around the loop, the index function will find the next occurrence of the letter (if there is one) and it won’t stop at the first occurrence.

If on the other hand, if the player guesses an incorrect letter, you increment wrong by 1.

Next, you print the scoreboard and your hangman using the board and stages lists. The code that prints the scoreboard is ‘ ‘.join(board).

Printing the hangman is trickier. When each of the strings in your stages list prints on a new line, a complete picture of a hangman prints. You can create the entire hangman by printing ‘\n’.join(stages), which adds a new line to each string in the stages list so that each string in the list prints on a separate line.

To print your hangman at whatever stage the game is at, you slice your stages list. You start at stage 0, and slice up to the stage you are at (represented by the variable wrong) plus one. You add one because when you are slicing, the end slice does not get included in the result. This slice gives you only the strings you need to print the version of the hangman you are currently at.

Finally, you check if Player Two won the game. If there are no more underscores in the board list, they guessed all the letters and won the game. If Player Two won, you print You win! It was: and the word they correctly guessed. You also set the variable win to True, which breaks you out of your loop.

Once you break out of your loop, if Player Two won, you do nothing—the program is over. If they lost, the variable win is False. If that is the case, you print the full hangman and You lose!, followed by the word they couldn’t guess:

if not win:
    print("\n"
          .join(stages[0: \
          wrong]))
    print("You lose! It was {}."
          .format(word))

Here is your complete code:

# http://tinyurl.com/h9q2cpc
 
 
def hangman(word):
    wrong = 0
    stages = ["",
             "________        ",
             "|               ",
             "|        |      ",
             "|        0      ",
             "|       /|\     ",
             "|       / \     ",
             "|               "
              ]
    rletters = list(word)
    board = ["__"] * len(word)
    win = False
    print("Welcome to Hangman")
    while wrong < len(stages) - 1:
        print("\n")
        msg = "Guess a letter"
        char = input(msg)
        if char in rletters:
            cind = rletters \
                   .index(char)
            board[cind] = char
            rletters[cind] = '$'
        else:
            wrong += 1
        print((" ".join(board)))
        e = wrong + 1
        print("\n"
              .join(stages[0: e]))
        if "__" not in board:
            print("You win!")
            print(" ".join(board))
            win = True
            break
    if not win:
        print("\n"
              .join(stages[0: \
              wrong]))
        print("You lose! It was {}."
              .format(word))
 
 
hangman("cat")

 

Leave a Reply

Your email address will not be published. Required fields are marked *