# 6.00 Problem Set 3 solution # # Hangman # import random import string # ----------------------------------- # Helper code # (you don't need to understand this helper code) WORDLIST_FILENAME = "words.txt" def load_words(): """ 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 # end of helper code # ----------------------------------- def chooseWord(wordlist): """ wordlist (list): list of words (strings) Returns a word from wordlist at random """ # You could have also used randrange here, but I think this is a # bit cleaner. Take a look at help(random.choice) after importing # random to learn more return random.choice(wordlist) def update_hand(guess, word, revealed): """ guess (string): The letter guessed. This letter must be in word word (string): The word we're playing hangman with revealed (list of bools): if revealed[i] is True, then we've guessed the letter at word[i] Returns: Nothing Updates revealed, changing 0s to 1s in the spots corresponding to the guessed letters """ # The idea here is that we are walking through the word and the # list simultaneously -- word[i] is the letter at that spot, and # revealed[i] represents whether or not the character at that spot # has been revealed yet. # # Remember that lists are mutable, so this actually works; this # function /modifies/ the 'revealed' list. # # e.g. # word = "hello" # revealed = [F F T T T] # would be the state of the world if the user had guessed # (and we had revealed) "l" and "o" for i in range(len(revealed)): if word[i] == guess: revealed[i] = True return def get_display_hand(word, revealed): """ Returns a string that is the printable representation of word, given revealed (i.e. the letters from word when they are revealed, _ when they are not) """ output = "" for i in range(len(word)): if revealed[i]: output += word[i] else: output += "_" return output def word_solved(revealed): """ Returns True if the whole word has been revealed, False otherwise """ # I'm being cute by writing this # on one line here -- make sure # you understand how (and why) # this works. return revealed.count(False) == 0 def play_one_game(wordlist): print "Welcome to the game, Hangman!" # Initialize the variables we're going # to use to store the state of things # The word we've guessed word = chooseWord(wordlist) # Representation of which letters we've revealed # (True in slot i means "Show word[i]") revealed = [False] * len(word) # Remaining letters that can be guessed letters = [] for letter in string.lowercase: letters.append(letter) guesses = 8 print "I am thinking of a word that is", len(word), "letters long." while guesses > 0 and not word_solved(revealed): print "-" * 10 print "You have", guesses, "guesses left." print "Available letters:", ''.join(letters) print guess = raw_input("Please guess a letter: ") if guess not in letters: print "You've already guessed that letter." continue letters.remove(guess) if guess in word: update_hand(guess, word, revealed) print "Good guess: ", else: print "Oops! That letter is not in my word: ", guesses -= 1 print get_display_hand(word, revealed) print if word_solved(revealed): print "Congratulations, you won!" else: print "You lose. The word was:", word print "*" * 70 def play_game(wordlist): """ Repeatedly kick off a new game of hangman until the user responds negatively to 'Play again? """ while True: play_one_game(wordlist) again = raw_input("Play again ?") if len(again) > 0 and again[0] in ['n', 'N']: break print wordlist = load_words() if __name__ == "__main__": play_game(wordlist)