Segue o projeto final, dividido em alguns posts, do começo ao fim dele.
Dividi ao máximo o código em funções. Ficou esquisito onde eu não soube lidar com o state do jogo. Também usei um dicionário baixado. Quando o jogo começa, a palavra é tirada deste dicionário e colocado num .txt temporário para evitar que, enquanto o jogo durar, a palavra seja repetida. Quando o jogo ou acaba, ou é interrompido com ctrl+c, o txt temporário é deletado. Tentei evitar qualquer erro de input do usuário, como string vazio u uso de floats. Por fim, acrescentei níveis ao jogo e formatei todo o texto para facilitar a leitura no terminal.
#!/usr/bin/env python3.9
import contextlib
import random
import os
import signal
import sys
words = []
used_words = set()
def print_message1(message):
print(f"{message}\n")
def print_message2(message):
print(f"\n{message}")
def print_message3(message):
print(f"\n{message}\n")
def print_welcome_message():
print_message1("***" * 10)
print_message1("Welcome to Hangman! \U0001F3AE")
print_message1("***" * 10)
def goodbye():
print_message2("Goodbye, then... \U0001F984")
print_message3("***" * 10)
def print_success_message(secret_word):
success_message = (
"\U0001F525 " * 3
+ f"That's right! The word is {secret_word}! You're not going to \U0001F480 "
)
print_message1(success_message)
def print_failure_message(secret_word):
failure_message = (
"\U0001F62D " * 3 + "You lost, love. But it's ok, you're only \U0001F480 "
)
secret_world_reveal = f"The word was {secret_word} " + "\U0001F44B " * 3
final_message = failure_message + secret_world_reveal
print_message1(final_message)
def wrong_guess_messages(errors, guess, total_tries):
print_message2(f"That's incorrect! The word does not contain {guess}.")
print_message3(f"You have {total_tries - errors} tries left, \U0001F9C1")
def get_user_confirmation_prompt(prompt):
while True:
answer = input(prompt)
if answer == "n":
goodbye()
return False
elif answer == "y":
return True
else:
print_message3("Just y or n, buddy.")
def start_or_continue_game(already_played):
if already_played:
prompt = "Would you like to play again? Type [y] for yes or [n] for no: "
else:
prompt = "Would you like to play? Type [y] for yes or [n] for no: "
already_played = True
return get_user_confirmation_prompt(prompt), already_played
def get_level_and_tries():
level_tries_dict = {"1": 7, "2": 5, "3": 3, "4": 1}
while True:
print()
choice = input(
"Select your level (1 for 7 tries, 2 for 5 tries, 3 for 3 tries, 4 for 1 try, or q to quit): "
)
if choice in level_tries_dict:
return level_tries_dict[choice]
elif choice == "q":
return "q"
else:
print_message2("Just 1, 2, 3, 4, or q, buddy.")
def load_words():
global words
with open("dictionaries/American/2of12.txt") as f:
words = [
word.strip()
for word in f.readlines()
if set(word.strip()).issubset(set("abcdefghijklmnopqrstuvwxyz'- "))
]
def select_secret_word():
global words, used_words
if not words:
load_words()
available_words = [word for word in words if word not in used_words]
secret_word = random.choice(available_words)
used_words.add(secret_word)
return secret_word
def create_used_words_file():
with open("dictionaries/American/used_words.txt", "w") as file:
for word in used_words:
file.write(word + "\n")
def delete_used_words_file():
with contextlib.suppress(FileNotFoundError):
os.remove("dictionaries/American/used_words.txt")
def get_valid_guess(guessed_letters):
while True:
guess = input("Guess a letter: ").strip().lower()
if len(guess) > 1:
print_message3("Just one entry, buddy.")
elif len(guess) == 0:
print_message3("No empty guesses, buddy.")
elif not guess.isalpha():
print_message3("Just letters, buddy.")
elif guess in guessed_letters:
print_message3("You already guessed that letter, buddy.")
else:
return guess
def guess_is_letter(guess, secret_word, correct_guesses):
found = False
for index, letter in enumerate(secret_word):
if guess == letter:
correct_guesses[index] = letter
found = True
return found
(...)