Checking if the player has won
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -23,3 +23,6 @@ WORD_LIST = [
|
||||
"squirrel",
|
||||
"tortoise",
|
||||
]
|
||||
|
||||
## Message shown when the player wins.
|
||||
MSG_WIN = "You win!"
|
||||
|
||||
@@ -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
@@ -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__":
|
||||
|
||||
@@ -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
@@ -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!"]
|
||||
|
||||
Reference in New Issue
Block a user