A Word List and the Game Loop
You've built every part: the masked word, the guess handler, the life counter, and both endings. Two things finish the game. First, the word should vary - a fixed "python" gets old. Second, all those parts should live in one function you call to play a round. This phase does both, then hands you the keys to extend it.
A list of words and a random pick
A word list is a plain list of strings. To grab one at random, the standard
library's random module has choice, which returns one item from a list:
=
=
Run it a few times - you'll get different words. That randomness is what makes the
game replayable. In the runnable blocks below we'll call random.seed(...) first
so the "random" pick is the same every run, which keeps the printed play-through
stable for you to read. On your own machine you'd drop the seed and let it be
genuinely random.
Everything in one function
Here's the move that ties the project together: take the full round from Phase 3
and wrap it in a play(word, moves, lives) function. Same logic - show, guess,
count, check - but now it's one callable thing. We pass in the guesses as moves
because there's no console here; on your machine you'd read them from the player.
=
return
return
=
break
=
continue
-= 1
# fixed pick so this run is repeatable
=
= # a simulated playthrough
Run it. With seed 2 the word comes out "python", and the move list starts with two
common-but-wrong vowels (e, a) before the right letters come in - so you watch
two lives burn, then the word fill in for a win. That's the finished game: random
word, a full round, both endings, all in one function.
The default lives=6 in the signature means you can call play(word, moves) and
get six lives, or play(word, moves, lives=3) for a harder game, without changing
the function.
A quick self-check
One assert-based check confirms the win and loss paths both work, so you know the
finished play logic is sound:
return
=
break
-= 1
return
assert ==
assert ==
Run it. The confirmation line means a clean sweep wins and three misses on three
lives loses - the two outcomes your play function rests on.
Where to take it
You have a complete game. Here are real extensions, easiest first:
| Idea | The gist |
|---|---|
| Bigger word list | Add words to WORDS. The game gets them for free. |
| Categories | Make WORDS a dict like {"animals": [...], "fruit": [...]} and pick a category, then a word. |
| A hint | After a few misses, reveal one unguessed letter: pick from set(word) - guessed. |
| Score | Count wins across rounds; award points for lives remaining at the win. |
| ASCII art | Print a stick figure that grows a limb per miss - a list of art strings indexed by misses. |
Play it for real on your machine
The browser version simulates guesses because there's no place to type. On your
own machine you can read real input. Save this as hangman.py and run it with
python hangman.py in your terminal - it asks for one letter per turn:
=
return
return
=
=
= 6
=
continue
continue
-= 1
It's the same game you built here - show, won, the life count, both endings.
The only change is the while loop reads a real guess with input() instead of
walking a fixed list, plus a check that the player typed exactly one letter. That
input-guard is the kind of thing you skip in a demo and want the moment a real
person uses it.
You built it
A row of blanks became a guess handler became a life counter became a finished, random, replayable game - each phase a piece you ran and watched work. That's the whole arc of building software: small correct parts, snapped together. Now go add a category mode, or that growing stick figure, and make it yours.