Add 6 task: gallows game on Python
This commit is contained in:
parent
ec91d9a606
commit
effe469b9e
1 changed files with 321 additions and 0 deletions
321
src/Lesson_2/6.py
Normal file
321
src/Lesson_2/6.py
Normal file
|
|
@ -0,0 +1,321 @@
|
||||||
|
import os
|
||||||
|
from random import choice
|
||||||
|
|
||||||
|
|
||||||
|
# Встроенные слова для игры
|
||||||
|
STANDART_WORDS = [
|
||||||
|
"банан",
|
||||||
|
"пончик",
|
||||||
|
"граната",
|
||||||
|
"помидор",
|
||||||
|
"торнадо",
|
||||||
|
"паркет",
|
||||||
|
"иллюзия",
|
||||||
|
"ссора",
|
||||||
|
"барабулька",
|
||||||
|
"рыбак",
|
||||||
|
"сторож",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Важные сообщения для вывода и рендера
|
||||||
|
MESSAGES = {
|
||||||
|
"start_message": "Добро пожаловать в Весельницу!\n"
|
||||||
|
+ "Для начала необходимо загрузить словарь слов для угадывания.\n"
|
||||||
|
+ "\nВсе слова должны быть записаны только с использованием "
|
||||||
|
+ "кириллицы, все буквы строчные.\n"
|
||||||
|
+ "1 - Использовать только встроеннный словарь.\n"
|
||||||
|
+ "2 - Ввести свои слова по одному.\n"
|
||||||
|
+ "3 - Ввести строку своих слов, разделенных пробелами.",
|
||||||
|
"word_field": "{}\nДлина слова: {}",
|
||||||
|
"attemps_info": "Попытка: {}/{}",
|
||||||
|
"commands_info": ""
|
||||||
|
+ "Во время разгадки слова вы можете воспользоваться "
|
||||||
|
+ "следующими командами:\n"
|
||||||
|
+ "1. Если вы устали отгадывать слово, то введите 'СДАЮСЬ'.\n"
|
||||||
|
+ "2. Если вы захотите выключить приложение, то введите 'СТОП'.",
|
||||||
|
"jester_25": ""
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ "--|-- ",
|
||||||
|
"jester_50": ""
|
||||||
|
+ " ---- \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ "--|-- ",
|
||||||
|
"jester_75": ""
|
||||||
|
+ " ---- \n"
|
||||||
|
+ " | |\n"
|
||||||
|
+ " | 0\n"
|
||||||
|
+ " | \n"
|
||||||
|
+ " | \n"
|
||||||
|
+ "--|-- ",
|
||||||
|
"jester_99": ""
|
||||||
|
+ " ---- \n"
|
||||||
|
+ " | |\n"
|
||||||
|
+ " | 0\n"
|
||||||
|
+ " | /|\\\n"
|
||||||
|
+ " | \n"
|
||||||
|
+ "--|-- ",
|
||||||
|
"jester_100": ""
|
||||||
|
+ " ---- \n"
|
||||||
|
+ " | |\n"
|
||||||
|
+ " | 0 - {}\n"
|
||||||
|
+ " | /|\\\n"
|
||||||
|
+ " | / \\ \n"
|
||||||
|
+ "--|-- ",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class JesterState:
|
||||||
|
"""Хранение информации и состоянии текущей сессии."""
|
||||||
|
|
||||||
|
def __init__(self, max_attemps: int):
|
||||||
|
"""Инициализация объекта JesterState.
|
||||||
|
|
||||||
|
Аргументы:
|
||||||
|
max_attemps (int): максимальное кол-во попыток в сессии.
|
||||||
|
"""
|
||||||
|
self.is_alive = True
|
||||||
|
self.current_attemp = 1
|
||||||
|
self.max_attemps = max_attemps
|
||||||
|
|
||||||
|
def wrong_answer(self) -> None:
|
||||||
|
"""Обработка неправильного угадывания"""
|
||||||
|
self.current_attemp += 1
|
||||||
|
|
||||||
|
if self.current_attemp > self.max_attemps:
|
||||||
|
self.is_alive = False
|
||||||
|
|
||||||
|
def get_percent(self) -> int:
|
||||||
|
"""Получение процента завершенности виселицы
|
||||||
|
|
||||||
|
Вывод:
|
||||||
|
int: процентное представление: 0 <= percent <= 100
|
||||||
|
"""
|
||||||
|
return int(self.current_attemp / self.max_attemps * 100)
|
||||||
|
|
||||||
|
|
||||||
|
def render_word_field(current_string: str) -> None:
|
||||||
|
"""Рендер поля строки для угадывания слова.
|
||||||
|
|
||||||
|
Аргументы:
|
||||||
|
current_string (str): строка со всеми (не)угаданными буквами.
|
||||||
|
"""
|
||||||
|
print(
|
||||||
|
MESSAGES["word_field"].format(
|
||||||
|
current_string.replace("", " ")[1:],
|
||||||
|
len(current_string),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def render_jester_state(jester_state: JesterState) -> None:
|
||||||
|
"""Рендер виселицы.
|
||||||
|
|
||||||
|
Аргументы:
|
||||||
|
jester_state (JesterState): информация о состоянии сессии.
|
||||||
|
"""
|
||||||
|
percent = jester_state.get_percent()
|
||||||
|
|
||||||
|
if percent <= 25:
|
||||||
|
print(MESSAGES["jester_25"])
|
||||||
|
|
||||||
|
elif percent <= 50:
|
||||||
|
print(MESSAGES["jester_50"])
|
||||||
|
|
||||||
|
elif percent <= 75:
|
||||||
|
print(MESSAGES["jester_75"])
|
||||||
|
|
||||||
|
elif percent <= 99:
|
||||||
|
print(MESSAGES["jester_99"])
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
MESSAGES["jester_100"].format(
|
||||||
|
"спасите" if jester_state.is_alive else "x_x (здох)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if jester_state.is_alive:
|
||||||
|
print(
|
||||||
|
MESSAGES["attemps_info"].format(
|
||||||
|
jester_state.current_attemp,
|
||||||
|
jester_state.max_attemps,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def clear_screen() -> None:
|
||||||
|
"""Метод для быстрой очистки экрана"""
|
||||||
|
if os.name == "nt":
|
||||||
|
os.system("cls")
|
||||||
|
else:
|
||||||
|
os.system("clear")
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_words() -> list[str]:
|
||||||
|
"""Получение дополнительных слов для загадывания от пользователя,
|
||||||
|
используется только в связке с ENTER.
|
||||||
|
|
||||||
|
Вывод:
|
||||||
|
list[str]: список всех указанных пользователем слов.
|
||||||
|
"""
|
||||||
|
words = list()
|
||||||
|
print("Вводите слова через ENTER...")
|
||||||
|
print("Введите пустую строчку, если хотите закончить набор слов.")
|
||||||
|
print()
|
||||||
|
while word := input("> "):
|
||||||
|
words.append(word)
|
||||||
|
|
||||||
|
return words
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_guess(
|
||||||
|
random_word_len: int,
|
||||||
|
current_string: str,
|
||||||
|
jester_state: JesterState,
|
||||||
|
) -> str:
|
||||||
|
"""Окно для получения догадки пользователя со всеми рендерами.
|
||||||
|
|
||||||
|
Аргументы:
|
||||||
|
random_word_len (int): длина загаданного слова.
|
||||||
|
current_string (str): строка со всеми (не)угаданными буквами.
|
||||||
|
jester_state (JesterState): информация о состоянии сессии.
|
||||||
|
|
||||||
|
Вывод:
|
||||||
|
str: обработанная догадка пользователя или команда.
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
clear_screen()
|
||||||
|
|
||||||
|
render_word_field(current_string)
|
||||||
|
render_jester_state(jester_state)
|
||||||
|
|
||||||
|
guess = input("Введите вашу догадку:\n> ")
|
||||||
|
|
||||||
|
if guess == "СДАЮСЬ":
|
||||||
|
return guess
|
||||||
|
|
||||||
|
if guess == "СТОП":
|
||||||
|
return guess
|
||||||
|
|
||||||
|
if len(guess) == random_word_len:
|
||||||
|
return guess
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
"\nДлина вашего слова не совпадает "
|
||||||
|
+ "с длиной загаданного!\n"
|
||||||
|
+ f"Длина загаданного: {random_word_len}\n"
|
||||||
|
+ f"Длина вашего слова: {len(guess)}"
|
||||||
|
)
|
||||||
|
input("\nНажмите ENTER, чтобы продолжить...")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Основная функция для запуска игры."""
|
||||||
|
clear_screen()
|
||||||
|
print(MESSAGES["start_message"])
|
||||||
|
|
||||||
|
mode = int(input("> "))
|
||||||
|
|
||||||
|
words = list()
|
||||||
|
|
||||||
|
match mode:
|
||||||
|
case 1:
|
||||||
|
words = STANDART_WORDS
|
||||||
|
case 2:
|
||||||
|
clear_screen()
|
||||||
|
words = get_user_words()
|
||||||
|
case 3:
|
||||||
|
clear_screen()
|
||||||
|
print("Введите строчку всех слов через пробел...")
|
||||||
|
words = input("> ").split()
|
||||||
|
|
||||||
|
if mode != 1:
|
||||||
|
clear_screen()
|
||||||
|
print("Хотите ли вы включить в набор слов стандартные слова?")
|
||||||
|
answer = input("да/нет\n> ").lower()
|
||||||
|
if answer == "да":
|
||||||
|
for standart_word in STANDART_WORDS:
|
||||||
|
if standart_word not in words:
|
||||||
|
words.append(standart_word)
|
||||||
|
|
||||||
|
clear_screen()
|
||||||
|
if len(words) == 0:
|
||||||
|
print("Ваш словарь пуст! Запустите программу заново!!!")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
print(f"Ваш словарь: {", ".join(words)}" + ".")
|
||||||
|
print("\n" + MESSAGES["commands_info"])
|
||||||
|
|
||||||
|
input("Нажмите ENTER, чтобы продолжить...")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
random_word = choice(words)
|
||||||
|
|
||||||
|
current_string = "_" * len(random_word)
|
||||||
|
|
||||||
|
jester_state = JesterState(10)
|
||||||
|
|
||||||
|
is_win = False
|
||||||
|
|
||||||
|
while True:
|
||||||
|
guess = get_user_guess(
|
||||||
|
len(random_word), current_string, jester_state
|
||||||
|
)
|
||||||
|
|
||||||
|
if guess == "СДАЮСЬ":
|
||||||
|
jester_state.is_alive = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if guess == "СТОП":
|
||||||
|
exit()
|
||||||
|
|
||||||
|
raw_current_string = list()
|
||||||
|
|
||||||
|
for idx, (true_letter, guess_letter) in enumerate(
|
||||||
|
zip(random_word, guess)
|
||||||
|
):
|
||||||
|
if true_letter == guess_letter:
|
||||||
|
raw_current_string.append(true_letter)
|
||||||
|
else:
|
||||||
|
raw_current_string.append(current_string[idx])
|
||||||
|
|
||||||
|
current_string = "".join(raw_current_string)
|
||||||
|
|
||||||
|
if guess == random_word or current_string == random_word:
|
||||||
|
is_win = True
|
||||||
|
break
|
||||||
|
|
||||||
|
else:
|
||||||
|
jester_state.wrong_answer()
|
||||||
|
|
||||||
|
if not jester_state.is_alive:
|
||||||
|
break
|
||||||
|
|
||||||
|
clear_screen()
|
||||||
|
|
||||||
|
if is_win:
|
||||||
|
print("Ты отгадал слово!\n")
|
||||||
|
print("!! (⌒▽⌒) !!")
|
||||||
|
else:
|
||||||
|
print("Вы проиграли и были повешены :(")
|
||||||
|
render_jester_state(jester_state)
|
||||||
|
|
||||||
|
print(f"Загаданное слово: {random_word}")
|
||||||
|
|
||||||
|
if is_win:
|
||||||
|
print(f"Число попыток: {jester_state.current_attemp}")
|
||||||
|
|
||||||
|
answer = input("\nПродолжим? да/нет\n> ")
|
||||||
|
if answer.lower() != "да":
|
||||||
|
exit()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue