[Tutor] Please critique my hangman.py program

Alan Gauld alan.gauld at blueyonder.co.uk
Fri Jul 23 19:51:39 CEST 2004


> def random_word(word_length):
>     """Returns a random word of length word_length"""
>     file = open("hangman_words.txt","r")
>     word_list = []
>     for word in file:
>         word = word.strip()
>         if len(word) == word_length:
>             word_list.append(word)
>     file.close()

You could replace all that with a list comprehension. Something like:

word_list = [word.strip()
             for word in file("hangman_word.txt")
             if len(word) == word_lenth ]

>     if len(word_list) == 0:
>         return 0
>     else:
>         return random.choice(word_list)

      if word_list:
         return random.choice(word_list)
      else: return None


>
> def print_status (correct_so_far,incorrect,guesses):
>     """Prints the current status of the game"""
>     for i in range(len(correct_so_far)):
>         print correct_so_far[i],

      for item in correct_so_far:
          print item

>     print "\nIncorrect letters:",
>     for i in range(len(incorrect)):
>         print incorrect[i],

      for ltr in incorrect:
          print ltr

>     print "\nYou have had",guesses,"guesses so far."
>
> # Game title
> print "\n**************"
> print "*Hangman Game*"
> print "**************\n"
>
> play_again = "y"
> while string.lower(play_again) == "y":

  while play_again.lower() == "y":
OR
  while play_again in 'Yy':

>     while 1:

      while True:

>         try:
>             word_length = input("What length word do you want to
guess? ",)

No need for the comma - in fact I'm not sure what it does! I'd have
expected
an error since you are providing a tuple as a prompt, but input seems
to
accept it OK...!

>             print "Thinking, please wait.."
>             word = random_word(word_length)
>             if word == 0:
>                 print "I don't know any words that long!"
>             else:
>                 break
>         except:
>             print "That's not a proper word length!"
>     word = string.lower(word)
>
>     # Setup list to hold correct letters
>     correct_so_far = []
>     for i in range(word_length):
>         correct_so_far.append("_")

     correct_so_far = ['_'] * word_length

But you could just use a string which is esier to print later:

     xcorrect_so_far = '_' * word_length

>     # Setup some other variables
>     incorrect = []
>     guesses = 0
>     letters_guessed = 0

      guesses, letters_guessed = 0, 0

>     # Start main game loop.
>     print "\nI am thinking of a word",word_length,"letters long"
>     while letters_guessed < word_length:
>
>         # Print status of game on each pass.
>         print
>         print_status (correct_so_far,incorrect,guesses)
>
>         # Get guess from user
>         while 1:
>             guess = raw_input("Which letter would you like to try?
")
>             guess = string.lower(guess)
>             if len(guess) != 1:
>                 print "You can only guess one letter at a time!"
>             elif guess in incorrect or guess in correct_so_far:
>                 print "You've already tried that letter!"
>             elif guess not in
["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","
r","s","t","u","v","w","x","y","z"]:
>                 print "That's not a valid letter."
>             else:
>                 break
>         guesses = guesses + 1
>
>         # Evaluate guess against word
>         letter_correct = 0
>         for i in range(word_length):
>             if guess == word[i]:
>                 correct_so_far[i] = guess
>                 letter_correct=1
>                 letters_guessed = letters_guessed + 1

Personally I'd use a while loop here:

         i,letter_correct = 0,False
         while i < word_length and not letter_correct:
             if guess == word[i]:
                 correct_so_far[i] = guess
                 letter_correct=True
                 letters_guessed += 1
                 i += 1

Same length but I just think the test expresses the intention of
the loop better.


>         if letter_correct == 0:
>             incorrect.append(guess)
>
>     # Finish the game
>     print "\nWell done! You guessed the",word_length,"letter
word",word,"in",guesses,"goes."
>     print "You guessed",len(incorrect),"letters incorrectly."
>     play_again = raw_input("Do you want to play again? (y/n) ",)
> print "Goodybye!"
> # End of Program

Hope those ideas help. They are not definitively better just some
alternatives.

Alan G.



More information about the Tutor mailing list