-- coding: utf-8 --

""" ПОСЛЕДНЯЯ СМЕНА Текстовый хоррор-квест """

import time import random import sys import os

============ ЦВЕТА ДЛЯ КОНСОЛИ ============

class C: RED = '\033[91m' GREEN = '\033[92m' YELLOW = '\033[93m' BLUE = '\033[94m' MAGENTA = '\033[95m' CYAN = '\033[96m' WHITE = '\033[97m' GRAY = '\033[90m' BOLD = '\033[1m' DIM = '\033[2m' END = '\033[0m' BLINK = '\033[5m'

def clear(): os.system('cls' if os.name == 'nt' else 'clear')

def slow_print(text, delay=0.03, color=''): """Печатает текст по буквам, как в старых хоррорах""" for char in text: sys.stdout.write(color + char + C.END) sys.stdout.flush() time.sleep(delay) print()

def dramatic_pause(seconds=1.5): time.sleep(seconds)

def scream(): """Имитация крика / глитча""" for _ in range(3): sys.stdout.write(C.RED + C.BLINK + "!!! " + C.END) sys.stdout.flush() time.sleep(0.2) print()

============ ИГРОВОЕ СОСТОЯНИЕ ============

class GameState: def init(self): self.sanity = 100 # Рассудок self.trust_grigory = 50 # Доверие к напарнику self.rule_b_followed = 0 # Сколько раз выбрал безопасность self.choices_made = [] self.visited_fridge = False self.time_minutes = 0 # Игровое время (от 00:00)

def damage_sanity(self, amount):
    self.sanity = max(0, self.sanity - amount)
    if amount >= 20:
        slow_print(f"  [Рассудок: -{amount} | Осталось: {self.sanity}]", 0.01, C.RED)
    else:
        slow_print(f"  [Рассудок: -{amount} | Осталось: {self.sanity}]", 0.01, C.YELLOW)

def advance_time(self, minutes):
    self.time_minutes += minutes
    h = self.time_minutes // 60
    m = self.time_minutes % 60
    return f"{h:02d}:{m:02d}"

============ ВВОД ============

def ask_choice(prompt, options): """ prompt: вопрос options: dict {'A': 'текст', 'B': 'текст', ...} """ slow_print(prompt, 0.02, C.CYAN) print() for key, text in options.items(): slow_print(f" [{key}] {text}", 0.01, C.WHITE) print() while True: choice = input(C.YELLOW + "> " + C.END).strip().upper() if choice in options: return choice slow_print("Неверный выбор. Попробуй ещё.", 0.02, C.RED)

============ СЦЕНЫ ============

def intro(): clear() print(C.RED + C.BOLD) print("=" * 50) print(" ПОСЛЕДНЯЯ СМЕНА") print("=" * 50) print(C.END) dramatic_pause(1) slow_print("Морг городской больницы №7.", 0.05, C.GRAY) dramatic_pause(0.8) slow_print("Время: 23:47.", 0.05, C.GRAY) dramatic_pause(0.8) print() slow_print("Ты — Артём, 24 года. Ночной сторож.", 0.04, C.WHITE) slow_print("Твоя первая смена.", 0.04, C.WHITE) dramatic_pause(1.2) print() slow_print("Напарник, старик Григорий, сказал тебе три правила:", 0.03, C.CYAN) dramatic_pause(0.6) slow_print(" 1. После полуночи не открывай холодильник №13.", 0.03, C.YELLOW) slow_print(" 2. Если услышишь стук изнутри — не отвечай.", 0.03, C.YELLOW) slow_print(" 3. Если свет мигнёт три раза — беги к выходу.", 0.03, C.YELLOW) dramatic_pause(1.5) print() slow_print("Ты посмеялся про себя. Старик просто пугает новичка.", 0.04, C.GRAY) dramatic_pause(2) print() slow_print("23:58. Дверь подсобки открывается.", 0.04, C.WHITE) dramatic_pause(1)

def scene_grigory(): slow_print("На пороге — Григорий. Бледный, руки трясутся.", 0.04, C.WHITE) dramatic_pause(1) slow_print('"Артём... я забыл. Четвёртое правило..."', 0.05, C.RED) dramatic_pause(1.2) slow_print('"Если ты услышишь СВОЙ СОБСТВЕННЫЙ ГОЛОС из коридора —', 0.05, C.RED) slow_print(' не выходи. Что бы он ни говорил. Даже если будет умолять."', 0.05, C.RED) dramatic_pause(2) slow_print("Григорий уходит. Хлопает входная дверь.", 0.04, C.GRAY) dramatic_pause(1.5) scream() print(C.BOLD + "00:00. Свет гаснет. На секунду." + C.END) dramatic_pause(2)

def scene_main_menu(state): clear() print(C.BOLD + C.WHITE + "=" * 50 + C.END) print(C.GRAY + f" Время: {state.advance_time(0)} | Рассудок: {state.sanity}%" + C.END) print(C.BOLD + C.WHITE + "=" * 50 + C.END) print()

choice = ask_choice(
    "Что ты делаешь?",
    {
        "A": "Пойти к холодильнику №13",
        "B": "Остаться в подсобке и запереть дверь",
        "C": "Позвонить Григорию",
        "D": "Выйти в коридор и крикнуть",
        "Q": "Выйти из игры (сдаться)"
    }
)

if choice == "Q":
    slow_print("Ты бросаешь всё и бежишь к выходу...", 0.04, C.GRAY)
    dramatic_pause(2)
    slow_print("Дверь заперта. Изнутри.", 0.05, C.RED)
    dramatic_pause(2)
    return "quit"

state.choices_made.append(choice)

if choice == "A":
    return scene_fridge(state)
elif choice == "B":
    return scene_shelter(state)
elif choice == "C":
    return scene_phone(state)
elif choice == "D":
    return scene_corridor(state)

============ СЦЕНЫ ВЕТОК ============

def scene_fridge(state): clear() state.visited_fridge = True state.advance_time(15) slow_print("Ты идёшь по длинному коридору. Лампы мигают.", 0.04, C.WHITE) dramatic_pause(1) slow_print("У холодильника №13 — лужа воды.", 0.04, C.WHITE) dramatic_pause(1) slow_print("Ты тянешь за ручку...", 0.06, C.GRAY) dramatic_pause(2.5) scream() print(C.RED + C.BOLD + "ИЗНУТРИ НА ТЕБЯ СМОТРИТ ЛИЦО. ТВОЁ ЛИЦО." + C.END) dramatic_pause(2) slow_print('"Ты опоздал на 6 лет", — шепчет оно твоим голосом.', 0.06, C.RED) dramatic_pause(2) state.damage_sanity(60) dramatic_pause(1) slow_print("Свет гаснет. Что-то холодное хватает тебя за ногу.", 0.05, C.RED) dramatic_pause(3)

ending("ОПОЗДАЛ",
       "Тебя находят утром в холодильнике №13.\n"
       "Вскрытие покажет, что ты умер 6 лет назад.\n"
       "Но кто тогда приходил на смену?")

def scene_shelter(state): clear() state.rule_b_followed += 1 state.advance_time(34) slow_print("Ты запираешь дверь. Садишься. Слушаешь дождь.", 0.04, C.WHITE) dramatic_pause(2) slow_print("00:34. Стук в дверь. Три раза. Медленно.", 0.05, C.GRAY) dramatic_pause(1.5) slow_print('"Артём, открой. Это я, Григорий. Я забыл куртку."', 0.05, C.CYAN) dramatic_pause(2) slow_print("Ты смотришь в глазок. НИКОГО НЕТ.", 0.06, C.RED) dramatic_pause(1.5) slow_print('"Артём... пожалуйста... мне холодно..."', 0.05, C.RED) dramatic_pause(2) slow_print("Ты не открываешь. Стук прекращается.", 0.04, C.GRAY) dramatic_pause(1) state.damage_sanity(10)

state.advance_time(38)
print()
print(C.RED + C.BOLD + C.BLINK + "01:12. Свет мигает ТРИ РАЗА." + C.END)
dramatic_pause(2)

choice = ask_choice(
    "Ты помнишь правило старика. Что делать?",
    {
        "A": "Бежать к выходу",
        "B": "Остаться в подсобке",
        "C": "Закрыть глаза и ждать"
    }
)

if choice == "A":
    state.advance_time(5)
    slow_print("Ты бежишь к выходу. Дверь... открыта?", 0.04, C.WHITE)
    dramatic_pause(2)
    slow_print("За ней — снова подсобка. Ты внутри. Дверь заперта.", 0.05, C.RED)
    dramatic_pause(2)
    scream()
    slow_print("Из-под двери течёт холодная вода.", 0.05, C.RED)
    dramatic_pause(1.5)
    slow_print("Ты слышишь СВОЙ голос снаружи: 'Открой. Это я, Артём.'", 0.05, C.RED)
    dramatic_pause(3)
    state.damage_sanity(40)
    ending("ПРАВИЛО ТРИ",
           "Ты не помнишь, как открыл.\n"
           "Утром нашли только твой бейдж.\n"
           "И мокрые следы, ведущие к холодильнику №13.")

elif choice == "B":
    # Скрытая концовка: накопление
    if state.rule_b_followed >= 3:
        return hidden_ending(state)
    slow_print("Ты остаёшься. Свет мигает ещё раз и гаснет.", 0.05, C.RED)
    dramatic_pause(2)
    slow_print("Ты слышишь дыхание. Оно — твоё.", 0.05, C.RED)
    dramatic_pause(2)
    state.damage_sanity(30)
    return scene_shelter_loop(state)

else:
    slow_print("Ты закрываешь глаза.", 0.04, C.GRAY)
    dramatic_pause(2)
    slow_print("Когда открываешь — ты стоишь у холодильника №13.", 0.05, C.RED)
    dramatic_pause(2)
    slow_print("Ручка сама поворачивается.", 0.05, C.RED)
    dramatic_pause(2)
    state.damage_sanity(50)
    ending("ВЕДИ МЕНЯ",
           "Ты больше не помнишь, кто ты.\n"
           "Ты просто открываешь дверь.\n"
           "Кто-то должен это делать. Теперь это ты.")

def scene_shelter_loop(state): """Второй виток для скрытой концовки""" print() state.advance_time(60) slow_print(f"{state.advance_time(0)}. Стук в дверь. Три раза.", 0.04, C.GRAY) dramatic_pause(1.5) state.damage_sanity(5)

choice = ask_choice(
    "Снова стук. Что делаешь?",
    {
        "B": "Не открывать. Молчать.",
        "A": "Открыть дверь"
    }
)
if choice == "B":
    state.rule_b_followed += 1
    state.advance_time(120)
    slow_print(f"{state.advance_time(0)}. Стук в дверь. Три раза.", 0.04, C.GRAY)
    state.damage_sanity(5)

    choice2 = ask_choice(
        "Третий раз за ночь. Что делаешь?",
        {
            "B": "Не открывать. Молчать.",
            "A": "Открыть дверь"
        }
    )
    if choice2 == "B":
        state.rule_b_followed += 1
        return hidden_ending(state)
    else:
        return scene_open_door(state)
else:
    return scene_open_door(state)

def scene_open_door(state): slow_print("Ты открываешь дверь.", 0.04, C.WHITE) dramatic_pause(1) slow_print("На пороге — Григорий. Мёртвый. Он смотрит на тебя.", 0.05, C.RED) dramatic_pause(2) slow_print('"Ты должен был молчать", — говорит он голосом ребёнка.', 0.05, C.RED) dramatic_pause(2) state.damage_sanity(100) ending("ЧЕТВЁРТОЕ ПРАВИЛО", "Тебя нашли с зашитым ртом.\n" "Врачи не смогли объяснить, как ты дышал.\n" "Ты и не дышал. Уже давно.")

def scene_phone(state): clear() state.advance_time(8) slow_print("Ты берёшь телефон. Гудки... Григорий отвечает с первого раза.", 0.04, C.WHITE) dramatic_pause(1.5) slow_print('"Артём? Слава Богу. Слушай внимательно."', 0.04, C.CYAN) dramatic_pause(1) slow_print('"Четвёртое правило — это ложь."', 0.05, C.RED) dramatic_pause(1.5) slow_print('"Я не приходил к тебе сегодня. Я уволился неделю назад."', 0.05, C.RED) dramatic_pause(1.5) slow_print('"После того, как погиб предыдущий сторож."', 0.05, C.RED) dramatic_pause(2) slow_print('"Его звали... Артём."', 0.06, C.RED + C.BOLD) dramatic_pause(3) state.damage_sanity(80) slow_print("Ты медленно поворачиваешь голову.", 0.05, C.GRAY) dramatic_pause(2) scream() print(C.RED + C.BOLD + "НА СТУЛЕ РЯДОМ С ТОБОЙ СИДИТ ТВОЙ ТРУП. ОН УЛЫБАЕТСЯ." + C.END) dramatic_pause(3) ending("ЗЕРКАЛО", "Ты — не Артём.\n" "Ты — то, что заняло его место.\n" "Ты просто не помнил об этом. До этого момента.\n\n" "Теперь ты помнишь всё.")

def scene_corridor(state): clear() state.advance_time(10) slow_print("Ты выходишь в коридор.", 0.04, C.WHITE) dramatic_pause(1) slow_print('"Есть тут кто?"', 0.05, C.YELLOW) dramatic_pause(2) slow_print("Тишина.", 0.05, C.GRAY) dramatic_pause(1.5) slow_print("Потом — ТВОЙ СОБСТВЕННЫЙ ГОЛОС из темноты в конце коридора:", 0.05, C.RED) dramatic_pause(1) slow_print('"Да. Я здесь. Иди сюда."', 0.06, C.RED) dramatic_pause(2) state.damage_sanity(20) slow_print("Ты идёшь. Ноги сами несут тебя.", 0.04, C.GRAY) dramatic_pause(2) slow_print("Из темноты выходит фигура. Это ты.", 0.05, C.RED) dramatic_pause(1) slow_print("Но у него нет глаз. И он улыбается слишком широко.", 0.05, C.RED) dramatic_pause(2) slow_print('"Теперь мы поменяемся. Ты постоишь тут. Я пойду домой."', 0.05, C.RED) dramatic_pause(1.5) slow_print('"К твоей маме. К твоей девушке. Они не заметят разницы."', 0.05, C.RED) dramatic_pause(3) state.damage_sanity(60) ending("ПОДМЕНА", "Тебя больше нет.\n" "Но каждую ночь в морге №7 кто-то слышит твой голос\n" "из темноты.\n\n" "И ждёт, когда новый сторож ответит.")

============ СКРЫТАЯ КОНЦОВКА ============

def hidden_ending(state): clear() state.advance_time(213) # 03:33 print(C.MAGENTA + C.BOLD) print("=" * 50) print(" 03:33") print("=" * 50) print(C.END) dramatic_pause(2)

slow_print("В дверь стучат.", 0.05, C.GRAY)
dramatic_pause(1)
print(C.MAGENTA + C.BOLD + "ЧЕТЫРЕ РАЗА." + C.END)
dramatic_pause(2)
slow_print('"Молодец. Ты понял."', 0.05, C.MAGENTA)
dramatic_pause(1)
slow_print('"Правил не три и не четыре. Их ПЯТЬ."', 0.05, C.MAGENTA)
dramatic_pause(1.5)
slow_print('"Пятое: не верь никому. Даже мне. Даже себе."', 0.05, C.MAGENTA)
dramatic_pause(1)
slow_print('"ОСОБЕННО СЕБЕ."', 0.06, C.MAGENTA + C.BOLD)
dramatic_pause(3)

slow_print("Свет включается.", 0.04, C.WHITE)
dramatic_pause(1.5)
slow_print("На столе лежит записка твоим почерком:", 0.04, C.WHITE)
dramatic_pause(1.5)
print()
slow_print('  "Если ты это читаешь — значит, ты ещё ты. Пока что."', 0.05, C.YELLOW)
slow_print('  "Не спи. Никогда не спи здесь."', 0.05, C.YELLOW)
slow_print('  "И главное — не смотри в зеркало в подсобке."', 0.05, C.YELLOW)
slow_print('  "Ты уже видел?"', 0.06, C.YELLOW + C.BOLD)
dramatic_pause(3)

ending("ПЯТОЕ ПРАВИЛО",
       "Ты выжил.\n"
       "Но теперь ты знаешь то, что знать не должен.\n\n"
       "И каждую ночь ты будешь слышать стук.\n"
       "Четыре раза.\n"
       "До конца жизни.",
       color=C.MAGENTA)

============ КОНЦОВКА ============

def ending(title, text, color=C.RED): print() print(color + C.BOLD) print("╔" + "═" * 48 + "╗") print("║" + f" КОНЦОВКА: {title}".ljust(48) + "║") print("╚" + "═" * 48 + "╝") print(C.END) dramatic_pause(1) print() slow_print(text, 0.04, C.WHITE) dramatic_pause(2) print() slow_print("Через неделю в газете напишут:", 0.03, C.GRAY) dramatic_pause(1) slow_print('"Ночной сторож морга №7 пропал без вести."', 0.03, C.GRAY) slow_print('"Последняя запись в журнале сделана рукой,"', 0.03, C.GRAY) slow_print('"которая не принадлежит пропавшему:"', 0.03, C.GRAY) dramatic_pause(1) print() print(C.RED + C.BOLD + " «ОНО ЕЩЁ ЗДЕСЬ»" + C.END) dramatic_pause(3) print() slow_print("В морге №7 снова открыта вакансия.", 0.04, C.WHITE) dramatic_pause(1) slow_print("Платят хорошо.", 0.06, C.GREEN + C.BOLD) dramatic_pause(3) print() print(C.GRAY + "=" * 50 + C.END) print(C.GRAY + " Спасибо за игру." + C.END) print(C.GRAY + "=" * 50 + C.END)

============ ГЛАВНЫЙ ЦИКЛ ============

def main(): try: intro() state = GameState() scene_grigory()

    # Главный игровой цикл
    while True:
        result = scene_main_menu(state)

        if result == "quit":
            slow_print("...", 0.5, C.GRAY)
            dramatic_pause(2)
            print(C.RED + C.BOLD + "Ты не можешь уйти. Ты уже здесь." + C.END)
            dramatic_pause(2)
            continue

        # Если сцена вернула строку-концовку, значит игра завершена
        if result is None:
            break

        # Проверка рассудка
        if state.sanity <= 0:
            print()
            scream()
            print(C.RED + C.BOLD + "РАССУДОК ПОТЕРЯН." + C.END)
            dramatic_pause(2)
            ending("БЕЗУМИЕ",
                   "Ты больше не помнишь, кто ты и зачем здесь.\n"
                   "Ты просто стоишь в коридоре и улыбаешься.\n"
                   "И ждёшь следующего сторожа.")

except KeyboardInterrupt:
    print()
    print(C.RED + C.BOLD + "\nТы пытаешься закрыть игру..." + C.END)
    dramatic_pause(2)
    print(C.RED + "Игра закрывает тебя." + C.END)
    dramatic_pause(2)
    print(C.GRAY + "...до следующей ночи." + C.END)

if name == "main": main()