This classic word game has the player guess the letters to a secret word. For each incorrect letter, another part of the hangman is drawn. Try to guess the complete word before the hangman completes. The secret words in this version are all animals like RABBIT and PIGEON, but you can replace these with your own set of words.
The HANGMAN_PICS
variable contains ASCII-art strings of each step of the hangman’s noose:
+--+ +--+ +--+ +--+ +--+ +--+ +--+
| | | | | | | | | | | | | |
| O | O | O | O | O | O |
| | | | /| | /|\ | /|\ | /|\ |
| | | | | / | / \ |
| | | | | | |
===== ===== ===== ===== ===== ===== =====
For a French twist on the game, you can replace the strings in the HANGMAN_PICS
variable with the following strings depicting a guillotine:
| | | |===| |===| |===| |===| |===|
| | | | | | | | | || /| || /|
| | | | | | | | | ||/ | ||/ |
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| | | | | | | |/-\| |/-\| |/-\|
| | | | | |\ /| |\ /| |\ /| |\O/|
|=== |===| |===| |===| |===| |===| |===|
When you run hangman.py, the output will look like this:
Hangman, by Al Sweigart [email protected]
+--+
| |
|
|
|
|
=====
The category is: Animals
Missed letters: No missed letters yet.
_ _ _ _ _
Guess a letter.
> e
--snip--
+--+
| |
O |
/| |
|
|
=====
The category is: Animals
Missed letters: A I S
O T T E _
Guess a letter.
> r
Yes! The secret word is: OTTER
You have won!
Hangman and Guillotine share the same game mechanics but have different presentations. This makes it easy to swap out the ASCII-art noose graphics with the ASCII-art guillotine graphics without having to change the main logic that the program follows. This separation of the presentation and logic parts of the program makes it easier to update with new features or different designs. In professional software development, this strategy is an example of a software design pattern or software architecture, which concerns itself with how to structure your programs for easy understanding and modification. This is mainly useful in large software applications, but you can also apply these principles to smaller projects.
1. """Hangman, by Al Sweigart [email protected]
2. Guess the letters to a secret word before the hangman is drawn.
3. This code is available at https://nostarch.com/big-book-small-python-programming
4. Tags: large, game, word, puzzle"""
5.
6. # A version of this game is featured in the book "Invent Your Own
7. # Computer Games with Python" https://nostarch.com/inventwithpython
8.
9. import random, sys
10.
11. # Set up the constants:
12. # (!) Try adding or changing the strings in HANGMAN_PICS to make a
13. # guillotine instead of a gallows.
14. HANGMAN_PICS = [r"""
15. +--+
16. | |
17. |
18. |
19. |
20. |
21. =====""",
22. r"""
23. +--+
24. | |
25. O |
26. |
27. |
28. |
29. =====""",
30. r"""
31. +--+
32. | |
33. O |
34. | |
35. |
36. |
37. =====""",
38. r"""
39. +--+
40. | |
41. O |
42. /| |
43. |
44. |
45. =====""",
46. r"""
47. +--+
48. | |
49. O |
50. /|\ |
51. |
52. |
53. =====""",
54. r"""
55. +--+
56. | |
57. O |
58. /|\ |
59. / |
60. |
61. =====""",
62. r"""
63. +--+
64. | |
65. O |
66. /|\ |
67. / \ |
68. |
69. ====="""]
70.
71. # (!) Try replacing CATEGORY and WORDS with new strings.
72. CATEGORY = 'Animals'
73. WORDS = 'ANT BABOON BADGER BAT BEAR BEAVER CAMEL CAT CLAM COBRA COUGAR COYOTE CROW DEER DOG DONKEY DUCK EAGLE FERRET FOX FROG GOAT GOOSE HAWK LION LIZARD LLAMA MOLE MONKEY MOOSE MOUSE MULE NEWT OTTER OWL PANDA PARROT PIGEON PYTHON RABBIT RAM RAT RAVEN RHINO SALMON SEAL SHARK SHEEP SKUNK SLOTH SNAKE SPIDER STORK SWAN TIGER TOAD TROUT TURKEY TURTLE WEASEL WHALE WOLF WOMBAT ZEBRA'.split()
74.
75.
76. def main():
77. print('Hangman, by Al Sweigart [email protected]')
78.
79. # Setup variables for a new game:
80. missedLetters = [] # List of incorrect letter guesses.
81. correctLetters = [] # List of correct letter guesses.
82. secretWord = random.choice(WORDS) # The word the player must guess.
83.
84. while True: # Main game loop.
85. drawHangman(missedLetters, correctLetters, secretWord)
86.
87. # Let the player enter their letter guess:
88. guess = getPlayerGuess(missedLetters + correctLetters)
89.
90. if guess in secretWord:
91. # Add the correct guess to correctLetters:
92. correctLetters.append(guess)
93.
94. # Check if the player has won:
95. foundAllLetters = True # Start off assuming they've won.
96. for secretWordLetter in secretWord:
97. if secretWordLetter not in correctLetters:
98. # There's a letter in the secret word that isn't
99. # yet in correctLetters, so the player hasn't won:
100. foundAllLetters = False
101. break
102. if foundAllLetters:
103. print('Yes! The secret word is:', secretWord)
104. print('You have won!')
105. break # Break out of the main game loop.
106. else:
107. # The player has guessed incorrectly:
108. missedLetters.append(guess)
109.
110. # Check if player has guessed too many times and lost. (The
111. # "- 1" is because we don't count the empty gallows in
112. # HANGMAN_PICS.)
113. if len(missedLetters) == len(HANGMAN_PICS) - 1:
114. drawHangman(missedLetters, correctLetters, secretWord)
115. print('You have run out of guesses!')
116. print('The word was "{}"'.format(secretWord))
117. break
118.
119.
120. def drawHangman(missedLetters, correctLetters, secretWord):
121. """Draw the current state of the hangman, along with the missed and
122. correctly-guessed letters of the secret word."""
123. print(HANGMAN_PICS[len(missedLetters)])
124. print('The category is:', CATEGORY)
125. print()
126.
127. # Show the incorrectly guessed letters:
128. print('Missed letters: ', end='')
129. for letter in missedLetters:
130. print(letter, end=' ')
131. if len(missedLetters) == 0:
132. print('No missed letters yet.')
133. print()
134.
135. # Display the blanks for the secret word (one blank per letter):
136. blanks = ['_'] * len(secretWord)
137.
138. # Replace blanks with correctly guessed letters:
139. for i in range(len(secretWord)):
140. if secretWord[i] in correctLetters:
141. blanks[i] = secretWord[i]
142.
143. # Show the secret word with spaces in between each letter:
144. print(' '.join(blanks))
145.
146.
147. def getPlayerGuess(alreadyGuessed):
148. """Returns the letter the player entered. This function makes sure
149. the player entered a single letter they haven't guessed before."""
150. while True: # Keep asking until the player enters a valid letter.
151. print('Guess a letter.')
152. guess = input('> ').upper()
153. if len(guess) != 1:
154. print('Please enter a single letter.')
155. elif guess in alreadyGuessed:
156. print('You have already guessed that letter. Choose again.')
157. elif not guess.isalpha():
158. print('Please enter a LETTER.')
159. else:
160. return guess
161.
162.
163. # If this program was run (instead of imported), run the game:
164. if __name__ == '__main__':
165. try:
166. main()
167. except KeyboardInterrupt:
168. sys.exit() # When Ctrl-C is pressed, end the program.
After entering the source code and running it a few times, try making experimental changes to it. The comments marked with (!)
have suggestions for small changes you can make. On your own, you can also try to figure out how to do the following:
Try to find the answers to the following questions. Experiment with some modifications to the code and rerun the program to see what effect the changes have.
missedLetters.append(guess)
on line 108?drawHangman(missedLetters, correctLetters, secretWord)
on line 85 to drawHangman(correctLetters, missedLetters, secretWord)
?['_']
on line 136 to ['*']
?print(' '.join(blanks))
on line 144 to print(secretWord)
?