Загрузка данных


# ===== ТАМАГОЧИ: итоговая сборка =====
from typing import List, Tuple, Callable

# Вставляй присланные методы на место строк raise NotImplementedError(...)

# ===== Ошибки — Епифанцев =====
class PetError(Exception):
    pass


class PetNotHungryError(PetError):
    pass


class PetIsSleepingError(PetError):
    pass


class PetTooTiredError(PetError):
    pass


# ===== Питомец =====
class Pet:
    # --- Демченков: состояние ---
    def __init__(self, name: str):
        self.name = name             # имя
        self.hunger = 3              # голод (0 = сыт, 10 = очень голоден)
        self.mood = 7                # настроение
        self.energy = 7              # энергия
        self.hour = 8                # время, 0..23 (старт в 8 часов)
        self.is_sleeping = False     # спит или нет (True/False)

    def __str__(self):
        status = "Спит" if self.is_sleeping else "Бодрствует"
        return (
            f"--- Статус питомца {self.name} ---\n"
            f"Голод: {self.hunger}/10\n"
            f"Настроение: {self.mood}/10\n"
            f"Энергия: {self.energy}/10\n"
            f"Время: {self.hour}:00\n"
            f"Состояние: {status}\n"
            f"------------------------"
        )

    # --- Демченков: действия ---
    def feed(self):
        if self.is_sleeping:
            raise PetIsSleepingError(f"{self.name} спит!")

        if self.hunger <= 0:
            raise PetNotHungryError(f"{self.name} не голоден!")

        self.hunger = max(0, self.hunger - 3)
        return f"{self.name} поел"

    def play(self):
        if self.is_sleeping:
            raise PetIsSleepingError(f"{self.name} спит!")

        if self.energy < 2:
            raise PetTooTiredError(f"{self.name} слишком устал для игр!")

        self.mood = min(10, self.mood + 2)
        self.energy = max(0, self.energy - 2)
        self.hunger = min(10, self.hunger + 1)
        return f"{self.name} поиграл"

    def sleep(self):
        if self.is_sleeping:
            raise PetIsSleepingError(f"{self.name} уже спит!")

        self.is_sleeping = True
        return f"{self.name} лег спать"

    def wake_up(self):
        if not self.is_sleeping:
            return f"{self.name} уже бодрствует"

        self.is_sleeping = False
        return f"{self.name} проснулся"

    # --- Стельмах: время ---
    def wants_to_sleep(self, hour):
        # Примем за ночь интервал с 22:00 до 06:00.
        return hour >= 22 or hour <= 6

    def pass_time(self, hours=1):
        # Двигает часы вперёд. Голод растёт, энергия падает. Сон бустит энергию.
        if hours <= 0:
            raise ValueError("Часы должны быть больше 0")

        for i in range(hours):
            # Переводим стрелку часов на 1 час вперёд
            self.hour = (self.hour + 1) % 24

            if self.is_sleeping:
                # Сон бустит энергию
                self.energy = min(10, self.energy + 2)
                self.hunger = min(10, self.hunger + 1)
            else:
                # Во время бодрствования голод растёт, энергия падает
                self.hunger = min(10, self.hunger + 1)
                self.energy = max(0, self.energy - 1)

        message = f"Прошло {hours} ч., сейчас {self.hour}:00"
        # Проверяем, наступила ли ночь
        if not self.is_sleeping and self.wants_to_sleep(self.hour):
            message += f". {self.name} хочет спать!"
        return message


# ===== Тесты — Епифанцев =====
# Для проверки: внизу файла замени main() на test()
def test():
    # 1. Создаём питомца (проверяем __init__)
    pet = Pet(name="Жора")
    # 2. Проверка __str__
    print(pet)
    # 3. Проверка базовых действий
    print(pet.feed())
    print(pet.play())
    # 4. Проверка течения времени и сна
    print(pet.pass_time(3))
    print(pet.sleep())
    # 5. Проверка ошибок
    # 5.1 PetIsSleepingError
    try:
        pet.play()
        print("Ошибка: PetIsSleepingError не вызвалась")
    except PetIsSleepingError:
        pass
    pet.wake_up()
    # 5.2 PetNotHungryError
    try:
        for _ in range(5):
            pet.feed()
        print("Ошибка: PetNotHungryError не вызвалась")
    except PetNotHungryError:
        pass
    # 5.3 PetTooTiredError
    try:
        for _ in range(10):
            pet.play()
            pet.pass_time(1)
        print("Ошибка: PetTooTiredError не вызвалась")
    except PetTooTiredError:
        pass
    print("Тесты завершены")


# ===== Меню и основной цикл — Шевелько =====
def choice_menu(menu: List[Tuple[str, Callable[[], str]]]) -> str:
    for id, item in enumerate(menu):
        print(f"{id + 1}. {item[0]}")  # item[0] - имя действия
    while True:
        choice = input("Выберите действие: ")
        if not choice.isdecimal():  # неправильный ввод, спрашиваем заново
            print("Неверный ввод: ожидалось число")
            continue
        choice = int(choice) - 1
        if choice < 0 or choice >= len(menu):  # нет такого пункта
            print("Неверный ввод: неверный номер пункта")
            continue
        chosen = menu[choice]
        return chosen[1]()  # вызываем действие и выходим


def main():
    print("Добро пожаловать в Тамагочи!")
    name = input("Введите имя питомца: ")
    pet = Pet(name)

    def skip_time():
        hours = input("Сколько часов пропустить: ")
        if not hours.isdecimal():  # неправильный ввод
            raise ValueError("Неверный ввод: ожидалось число")
        hours = int(hours)
        return pet.pass_time(hours)

    menu = [
        ("Покормить", pet.feed),
        ("Поиграть", pet.play),
        ("Уложить спать", pet.sleep),
        ("Разбудить", pet.wake_up),
        ("Пропустить время", skip_time),
        ("Показать состояние", lambda: str(pet)),
        ("Выйти", exit),
    ]
    while True:
        print()
        try:
            print(choice_menu(menu))
        except PetError as e:
            print(f"Нельзя: {e}")
        except ValueError as e:
            print(f"Ошибка: {e}")
        except NotImplementedError as e:
            print(f"Пока не готово: {e}")


main()