Step 3
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s

Checking if the player has won
This commit is contained in:
2026-10-04 12:40:15 +08:00
parent 15d5f7134d
commit ce87f23314
6 changed files with 66 additions and 24 deletions
+4 -2
View File
@@ -17,8 +17,8 @@ A beginner-friendly Python program that lets you play Hangman in the terminal ag
Day 7 of Udemy's *100 Days of Code™: The Complete Python Pro Bootcamp*. The game is built in five steps that follow the course:
1. Picking a random word and checking answers
2. Replacing blanks with guesses *(this step)*
3. Checking if the player has won
2. Replacing blanks with guesses
3. Checking if the player has won *(this step)*
4. Keeping track of the player's lives
5. Improving the user experience
@@ -26,6 +26,8 @@ Day 7 of Udemy's *100 Days of Code™: The Complete Python Pro Bootcamp*. The ga
**Step 2:** the word is shown as blanks (`_ _ _ _ _`). After your guess every matching blank is replaced by the letter.
**Step 3:** the game keeps asking for letters until every blank is filled, then prints "You win!". (There are no lives yet, so wrong guesses cost nothing.)
## 📋 Requirements
- Python 3.13 or newer
+3
View File
@@ -23,3 +23,6 @@ WORD_LIST = [
"squirrel",
"tortoise",
]
## Message shown when the player wins.
MSG_WIN = "You win!"
+7
View File
@@ -58,3 +58,10 @@ class Game:
@return For example `"p _ n g _ i n"`.
"""
return " ".join(c if c in self.guesses else BLANK for c in self.word)
@property
def won(self) -> bool:
"""!
@brief True when every letter of the word has been guessed.
"""
return all(c in self.guesses for c in self.word)
+19 -9
View File
@@ -3,6 +3,7 @@
@brief Command-line interface for Hangman.
"""
from hangman.constants import MSG_WIN
from hangman.game import Game, choose_word
@@ -14,18 +15,27 @@ def say(message: str = "") -> None:
print(message)
def play(game: Game) -> None:
"""!
@brief Ask for letters until every blank is filled.
@param game The game to play.
"""
say(game.display())
while not game.won:
letter = input("Guess a letter: ").strip()
if game.guess(letter):
say(f"Right, '{letter.lower()}' is in the word.")
else:
say(f"Wrong, '{letter.lower()}' is not in the word.")
say(game.display())
say(MSG_WIN)
def main() -> None:
"""!
@brief Entry point: show the blanks, take one guess and show the result.
@brief Entry point: start a game with a random word.
"""
game = Game(choose_word())
say(game.display())
letter = input("Guess a letter: ").strip()
if game.guess(letter):
say(f"Right, '{letter.lower()}' is in the word.")
else:
say(f"Wrong, '{letter.lower()}' is not in the word.")
say(game.display())
play(Game(choose_word()))
if __name__ == "__main__":
+15
View File
@@ -30,3 +30,18 @@ def test_wrong_guess_keeps_blanks():
g = Game("cat")
assert g.guess("z") is False
assert g.display() == "_ _ _"
def test_not_won_until_all_letters_guessed():
g = Game("hi")
assert not g.won
g.guess("h")
assert not g.won
g.guess("i")
assert g.won
def test_wrong_guesses_do_not_win():
g = Game("hi")
g.guess("x")
assert not g.won
+18 -13
View File
@@ -1,23 +1,28 @@
from hangman import main as cli
from hangman.game import Game
def run(monkeypatch, capsys, word, letter):
monkeypatch.setattr(cli, "choose_word", lambda: word)
monkeypatch.setattr("builtins.input", lambda _="": letter)
cli.main()
def run(monkeypatch, capsys, word, inputs):
it = iter(inputs)
monkeypatch.setattr("builtins.input", lambda _="": next(it))
cli.play(Game(word))
return capsys.readouterr().out
def test_right_guess_fills_blanks(monkeypatch, capsys):
out = run(monkeypatch, capsys, "camel", "a")
def test_play_until_won(monkeypatch, capsys):
out = run(monkeypatch, capsys, "hi", ["z", "h", "i"])
assert out.splitlines() == [
"_ _ _ _ _",
"Right, 'a' is in the word.",
"_ a _ _ _",
"_ _",
"Wrong, 'z' is not in the word.",
"_ _",
"Right, 'h' is in the word.",
"h _",
"Right, 'i' is in the word.",
"h i",
"You win!",
]
def test_wrong_guess_keeps_blanks(monkeypatch, capsys):
out = run(monkeypatch, capsys, "camel", "z")
assert "Wrong" in out
assert out.splitlines()[-1] == "_ _ _ _ _"
def test_repeated_letter_fills_all_blanks(monkeypatch, capsys):
out = run(monkeypatch, capsys, "aa", ["a"])
assert out.splitlines()[-2:] == ["a a", "You win!"]