Writing A Hangman Game (Python)

I wrote this program for the MITx: 6.00.1x Introduction to Computer Science and Programming Using Python course. This was one of the problem sets and it was a fun and easy program to write so I thought I would share my solution.

To start we need to create or download a wordlist file which contains english words that can be chosen by the AI for hangman. Here is some sample content from the wordlist I used:

a i ad am an as at ax be by do em en ex go he hi ho if in is it me my no of oh on or ox pi re so to up us...

Once we have the wordlist we can setup a couple functions to load the data and then choose a word (this code was provided as part of the exercise).

import random
import string

WORDLIST_FILENAME = 'words.txt'

def loadWordList():
    '''
    Returns a list of valid words. Words are strings of lowercase letters.

    Depending on the size of the word list, this function may
    take a while to finish.
    '''
    print 'Loading word list from file...'
    # inFile: file
    inFile = open(WORDLIST_FILENAME, 'r', 0)
    # line: string
    line = inFile.readline()
    # wordlist: list of strings
    wordlist = string.split(line)
    print '  ', len(wordlist), 'words loaded.'
    return wordlist

def chooseRandomWord(wordlist):
    '''
    wordlist (list): list of words (strings)

    Returns a word from wordlist at random
    '''
    return random.choice(wordlist)

# end of helper code
# -----------------------------------

Now lets define some more helper functions that we can use to abstract some of the tasks we need to repeatedly carry out. For starters we should check if the letter a user guesses is in the chosen word.

def checkGuess(guess, secretWord):
    '''
    guess: char, a letter that the user guessed
    returns: boolean, True if letter is in the word, False if letter is not
    '''

    if guess in secretWord:
        return True
    else:
        return False

The next function to implement is see how much of the word has been guessed. The function will return a string that can be printed to show the user what parts and how much of the word they have guessed. It will be in the following format: _ e _ _ o.

def getGuessWord(secretWord, lettersGuessed):
    '''
    secretWord: string, the word the user is guessing
    lettersGuessed: list, what letters have been guessed so far
    returns: string, comprised of letters and underscores that represents
      what letters in secretWord have been guessed so far.
    '''

    guess = ''

    for i in range(len(secretWord)):
        if secretWord[i] in lettersGuessed:
            guess += secretWord[i]
        else:
            guess += '_ '

    return guess

Once the user makes the guess and have not either guessed the word or run out of guessed, the program needs to make sure they know what letters are still available for guessing. This can be implemented as a function:

def getAvailLetters(lettersGuessed):
    '''
    lettersGuessed: list, what letters have been guessed so far
    returns: string, comprised of letters that represents what letters have not
      yet been guessed.
    '''

    lettersAvailable = ''
    for letter in 'abcdefghijklmnopqrstuvwxyz':
        if letter not in lettersGuessed:
            lettersAvailable += letter

    return lettersAvailable.lower()

The last helper function to implement is to check and see if the user has correctly guessed the word. If they got it the function returns True, otherwise False.

def isGuessed(secretWord, lettersGuessed):
    '''
    secretWord: string, the word the user is guessing
    lettersGuessed: list, what letters have been guessed so far
    returns: boolean, True if all the letters of secretWord are in lettersGuessed;
      False otherwise
    '''

    count = 0
    for letter in lettersGuessed:
        if letter in secretWord:
            count += 1

    if count == len(secretWord):
        return True
    else:
        return False

Now that all helper functions are implemented the final task is to create a hangman() function that is used as a “main” function to call whenever the game needs to be started.

def hangman(secretWord):
    '''
    secretWord: string, the secret word to guess.

    Starts up an interactive game of Hangman.

    * At the start of the game, let the user know how many
      letters the secretWord contains.

    * Ask the user to supply one guess (i.e. letter) per round.

    * The user should receive feedback immediately after each guess
      about whether their guess appears in the computers word.

    * After each round, you should also display to the user the
      partially guessed word so far, as well as letters that the
      user has not yet guessed.

    Follows the other limitations detailed in the problem write-up.
    '''

    # Load the list of words into the variable wordlist
    # so that it can be accessed from anywhere in the program

    lettersGuessed = []
    guessCount = 8

    print 'Welcome to the game, Hangman!'
    print 'I am thinking of a word that is %d letters long' % len(secretWord)

    # Make sure the user has not run out of guesses and the word was not guessed
    while not(isGuessed(secretWord, lettersGuessed)) and guessCount > 0:
        print '-------------'
        print 'You have %d guesses left.' % guessCount
        print 'Available letters: %s' % getAvailLetters(lettersGuessed)
        guess = raw_input('Please guess a letter: ').lower()

        if guess in lettersGuessed:
            print 'Oops! You've already guessed that letter: %s' % getGuessWord(secretWord, lettersGuessed)
        elif guess not in 'abcdefghijklmnopqrstuvwxyz':
            print 'Oops! That is not a letter: %s' % getGuessWord(secretWord, lettersGuessed)
        elif checkGuess(guess, secretWord):
            lettersGuessed += guess
            print 'Good guess: %s' % getGuessWord(secretWord, lettersGuessed)
        else:
            lettersGuessed += guess
            print 'Oops! That letter is not in my word: %s' % getGuessWord(secretWord, lettersGuessed)
            guessCount -= 1

    print '-------------'
    if guessCount == 0:
        print 'Sorry, you ran out of guesses. The word was %s.' % secretWord
    else:
        print 'Congratulations, you won!'

Now when the game is run, the AI should show the user what letters they have left, what parts of the word they guessed correctly and how many incorrect guesses they have left.

A game where the player wins:

Loading word list from file...
   55909 words loaded.
Welcome to the game, Hangman!
I am thinking of a word that is 6 letters long
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: a
Good guess: _ _ a_ _ _
-------------
You have 8 guesses left.
Available letters: bcdefghijklmnopqrstuvwxyz
Please guess a letter: i
Oops! That letter is not in my word: _ _ a_ _ _
-------------
You have 7 guesses left.
Available letters: bcdefghjklmnopqrstuvwxyz
Please guess a letter: o
Oops! That letter is not in my word: _ _ a_ _ _
-------------
You have 6 guesses left.
Available letters: bcdefghjklmnpqrstuvwxyz
Please guess a letter: e
Oops! That letter is not in my word: _ _ a_ _ _
-------------
You have 5 guesses left.
Available letters: bcdfghjklmnpqrstuvwxyz
Please guess a letter: b
Oops! That letter is not in my word: _ _ a_ _ _
-------------
You have 4 guesses left.
Available letters: cdfghjklmnpqrstuvwxyz
Please guess a letter: c
Oops! That letter is not in my word: _ _ a_ _ _
-------------
You have 3 guesses left.
Available letters: dfghjklmnpqrstuvwxyz
Please guess a letter: t
Oops! That letter is not in my word: _ _ a_ _ _
-------------
You have 2 guesses left.
Available letters: dfghjklmnpqrsuvwxyz
Please guess a letter: f
Good guess: _ _ a_ f_
-------------
You have 2 guesses left.
Available letters: dghjklmnpqrsuvwxyz
Please guess a letter: y
Oops! That letter is not in my word: _ _ a_ f_
-------------
You have 1 guesses left.
Available letters: dghjklmnpqrsuvwxz
Please guess a letter: r
Good guess: _ _ arf_
-------------
You have 1 guesses left.
Available letters: dghjklmnpqsuvwxz
Please guess a letter: c
Oops! You've already guessed that letter: _ _ arf_
-------------
You have 1 guesses left.
Available letters: dghjklmnpqsuvwxz
Please guess a letter: d
Good guess: d_ arf_
-------------
You have 1 guesses left.
Available letters: ghjklmnpqsuvwxz
Please guess a letter: w
Good guess: dwarf_
-------------
You have 1 guesses left.
Available letters: ghjklmnpqsuvxz
Please guess a letter: s
Good guess: dwarfs
-------------
Congratulations, you won!

A game where the player loses:

Loading word list from file...
   55909 words loaded.
Welcome to the game, Hangman!
I am thinking of a word that is 9 letters long
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: a
Good guess: a_ _ _ _ _ _ _ _
-------------
You have 8 guesses left.
Available letters: bcdefghijklmnopqrstuvwxyz
Please guess a letter: e
Good guess: a_ _ _ e_ _ e_
-------------
You have 8 guesses left.
Available letters: bcdfghijklmnopqrstuvwxyz
Please guess a letter: i
Oops! That letter is not in my word: a_ _ _ e_ _ e_
-------------
You have 7 guesses left.
Available letters: bcdfghjklmnopqrstuvwxyz
Please guess a letter: o
Oops! That letter is not in my word: a_ _ _ e_ _ e_
-------------
You have 6 guesses left.
Available letters: bcdfghjklmnpqrstuvwxyz
Please guess a letter: u
Oops! That letter is not in my word: a_ _ _ e_ _ e_
-------------
You have 5 guesses left.
Available letters: bcdfghjklmnpqrstvwxyz
Please guess a letter: b
Oops! That letter is not in my word: a_ _ _ e_ _ e_
-------------
You have 4 guesses left.
Available letters: cdfghjklmnpqrstvwxyz
Please guess a letter: c
Oops! That letter is not in my word: a_ _ _ e_ _ e_
-------------
You have 3 guesses left.
Available letters: dfghjklmnpqrstvwxyz
Please guess a letter: f
Oops! That letter is not in my word: a_ _ _ e_ _ e_
-------------
You have 2 guesses left.
Available letters: dghjklmnpqrstvwxyz
Please guess a letter: r
Good guess: a_ _ re_ _ e_
-------------
You have 2 guesses left.
Available letters: dghjklmnpqstvwxyz
Please guess a letter: d
Oops! That letter is not in my word: a_ _ re_ _ e_
-------------
You have 1 guesses left.
Available letters: ghjklmnpqstvwxyz
Please guess a letter: n
Oops! That letter is not in my word: a_ _ re_ _ e_
-------------
Sorry, you ran out of guesses. The word was aggresses.
Advertisements
This entry was posted in Programming, Python and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s