#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <iomanip>
#include <sstream>

// 颜色定义 (兼容Windows和Linux/Mac)
#ifdef _WIN32
#include <windows.h>
void setColor(int color) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
#else
#include <cstdio>
void setColor(int color) {
    // ANSI escape codes for Linux/Mac
    const char* code = "\033[0m"; // Default
    switch(color) {
        case 12: code = "\033[31m"; break; // Red
        case 10: code = "\033[32m"; break; // Green
        case 14: code = "\033[33m"; break; // Yellow
        case 11: code = "\033[36m"; break; // Cyan
        case 8:  code = "\033[90m"; break; // Gray
    }
    std::cout << code;
}
#endif

enum class Color {
    WHITE = 7,
    RED = 12,
    GREEN = 10,
    YELLOW = 14,
    CYAN = 11,
    GRAY = 8
};

class GameEngine {
private:
    // 玩家状态
    int sanity;      // 理智值 (0-100)
    int health;      // 生命值 (0-100)
    std::string currentLocation;
    std::vector<std::string> inventory;
    bool isAlive;
    bool hasEscaped;

    // 游戏规则
    std::map<std::string, std::string> rules;
    
    // 地图结构: 地点 -> {方向: 目标地点}
    std::map<std::string, std::map<std::string, std::string>> worldMap;
    
    // 地点描述
    std::map<std::string, std::string> locationDescs;

    // 特殊事件标记
    bool mirrorBroken;
    bool hasKey;
    bool metShadow;

public:
    GameEngine() : sanity(100), health(100), currentLocation("Entrance"), 
                   isAlive(true), hasEscaped(false), mirrorBroken(false), 
                   hasKey(false), metShadow(false) {
        srand(time(nullptr));
        initWorld();
        initRules();
    }

    void initWorld() {
        // 定义地图连接
        worldMap["Entrance"] = {{"north", "Lobby"}, {"look", "Entrance"}};
        worldMap["Lobby"] = {{"south", "Entrance"}, {"east", "Library"}, {"west", "Cafeteria"}, {"north", "Corridor"}};
        worldMap["Library"] = {{"west", "Lobby"}, {"search", "LibrarySearch"}};
        worldMap["Cafeteria"] = {{"east", "Lobby"}, {"eat", "CafeteriaEat"}};
        worldMap["Corridor"] = {{"south", "Lobby"}, {"north", "Room101"}, {"east", "Restroom"}};
        worldMap["Room101"] = {{"south", "Corridor"}, {"inspect", "Room101Inspect"}};
        worldMap["Restroom"] = {{"west", "Corridor"}, {"mirror", "RestroomMirror"}};
        
        // 特殊场景 (虚拟节点,用于处理交互后返回)
        worldMap["LibrarySearch"] = {{"back", "Library"}};
        worldMap["CafeteriaEat"] = {{"back", "Cafeteria"}};
        worldMap["Room101Inspect"] = {{"back", "Room101"}};
        worldMap["RestroomMirror"] = {{"back", "Restroom"}};

        // 地点描述
        locationDescs["Entrance"] = "你站在公寓的大门口。铁门紧闭,周围弥漫着雾气。空气中有一股霉味。";
        locationDescs["Lobby"] = "宽敞但昏暗的大厅。前台积满了灰尘,墙上挂着一幅歪斜的画。";
        locationDescs["Library"] = "书架高耸入云,书籍杂乱无章。这里安静得可怕,只能听到你的呼吸声。";
        locationDescs["Cafeteria"] = "食堂里摆放着腐烂的食物。苍蝇嗡嗡作响。";
        locationDescs["Corridor"] = "长长的走廊,灯光忽明忽暗。尽头似乎有一扇门。";
        locationDescs["Room101"] = "一间普通的卧室,但镜子被黑布蒙住了。床头柜上有一张纸条。";
        locationDescs["Restroom"] = "洗手间的水龙头在滴水。镜子上满是污渍。";
    }

    void initRules() {
        rules["Rule 1"] = "晚上10点后不要照镜子。";
        rules["Rule 2"] = "如果在图书馆听到有人叫你的名字,不要回头。";
        rules["Rule 3"] = "食堂提供的红色肉类绝对不能吃。";
        rules["Rule 4"] = "保持理智值高于0,否则你会看到不该看的东西。";
        rules["Rule 5"] = "找到钥匙才能打开大门逃离。";
    }

    void printColored(const std::string& text, Color color) {
        setColor(static_cast<int>(color));
        std::cout << text;
        setColor(static_cast<int>(Color::WHITE));
    }

    void showStatus() {
        std::cout << "\n----------------------------------------\n";
        printColored("【状态面板】\n", Color::CYAN);
        std::cout << "当前位置: " << currentLocation << std::endl;
        std::cout << "理智值: " << sanity << "/100 ";
        if (sanity < 30) printColored("(危险!)\n", Color::RED);
        else if (sanity < 60) printColored("(警告)\n", Color::YELLOW);
        else printColored("(正常)\n", Color::GREEN);
        
        std::cout << "生命值: " << health << "/100" << std::endl;
        std::cout << "物品栏: ";
        if (inventory.empty()) std::cout << "空";
        else {
            for (const auto& item : inventory) std::cout << item << " ";
        }
        std::cout << std::endl;
        std::cout << "----------------------------------------\n";
    }

    void showRules() {
        std::cout << "\n========================================\n";
        printColored("【生存规则】\n", Color::RED);
        for (const auto& rule : rules) {
            std::cout << rule.first << ": " << rule.second << std::endl;
        }
        std::cout << "========================================\n";
    }

    void showHelp() {
        std::cout << "\n--- 操作指南 ---\n";
        std::cout << "移动: north, south, east, west (或 n, s, e, w)\n";
        std::cout << "查看: status (状态), rules (规则), look (观察)\n";
        std::cout << "交互: search (搜索), eat (吃), inspect (检查), mirror (照镜子)\n";
        std::cout << "其他: help (帮助), quit (退出)\n";
        std::cout << "----------------\n";
    }

    void updateSanity(int change) {
        sanity += change;
        if (sanity > 100) sanity = 100;
        if (sanity <= 0) {
            sanity = 0;
            triggerInsanity();
        }
    }

    void triggerInsanity() {
        printColored("\n*** 你的理智崩溃了!现实开始扭曲... ***\n", Color::RED);
        std::vector<std::string> hallucinations = {
            "墙壁在呼吸...",
            "你听到身后有脚步声...",
            "镜子里的你没有动...",
            "地板变成了沼泽..."
        };
        std::cout << hallucinations[rand() % hallucinations.size()] << std::endl;
        health -= 20;
        if (health <= 0) gameOver("理智耗尽,你陷入了永恒的疯狂。");
    }

    void processCommand(const std::string& cmd) {
        if (!isAlive) return;

        std::string lowerCmd = cmd;
        std::transform(lowerCmd.begin(), lowerCmd.end(), lowerCmd.begin(), ::tolower);

        if (lowerCmd == "quit") {
            isAlive = false;
            std::cout << "游戏退出。" << std::endl;
            return;
        }
        if (lowerCmd == "help") {
            showHelp();
            return;
        }
        if (lowerCmd == "status") {
            showStatus();
            return;
        }
        if (lowerCmd == "rules") {
            showRules();
            return;
        }
        if (lowerCmd == "look") {
            std::cout << locationDescs[currentLocation] << std::endl;
            return;
        }

        // 移动逻辑
        if (lowerCmd == "n" || lowerCmd == "north" || lowerCmd == "s" || lowerCmd == "south" ||
            lowerCmd == "e" || lowerCmd == "east" || lowerCmd == "w" || lowerCmd == "west") {
            
            std::string dir = lowerCmd;
            if (dir == "n") dir = "north";
            if (dir == "s") dir = "south";
            if (dir == "e") dir = "east";
            if (dir == "w") dir = "west";

            if (worldMap[currentLocation].find(dir) != worldMap[currentLocation].end()) {
                currentLocation = worldMap[currentLocation][dir];
                std::cout << "\n你来到了: " << currentLocation << std::endl;
                std::cout << locationDescs[currentLocation] << std::endl;
                
                // 随机遭遇事件
                if (rand() % 10 == 0 && currentLocation != "Entrance") {
                    printColored("突然,一阵寒意袭来...\n", Color::GRAY);
                    updateSanity(-5);
                }
            } else {
                std::cout << "那个方向走不通。\n";
            }
            return;
        }

        // 特殊交互逻辑
        if (currentLocation == "Library" && lowerCmd == "search") {
            handleLibrarySearch();
        } else if (currentLocation == "Cafeteria" && lowerCmd == "eat") {
            handleCafeteriaEat();
        } else if (currentLocation == "Room101" && lowerCmd == "inspect") {
            handleRoom101Inspect();
        } else if (currentLocation == "Restroom" && lowerCmd == "mirror") {
            handleRestroomMirror();
        } else if (currentLocation == "Entrance" && lowerCmd == "open") {
            handleEscape();
        } else {
            std::cout << "在这里无法执行该操作,或者指令无效。\n";
        }
    }

    void handleLibrarySearch() {
        printColored("你在书架间翻找...\n", Color::CYAN);
        if (rand() % 2 == 0) {
            std::cout << "你找到了一本日记。上面写着:'不要相信穿红衣服的人。'\n";
            updateSanity(-5);
        } else {
            std::cout << "你什么也没找到,只感到一阵眩晕。\n";
            updateSanity(-10);
        }
        // 模拟返回
        currentLocation = "Library"; 
    }

    void handleCafeteriaEat() {
        printColored("你看向餐盘...\n", Color::YELLOW);
        std::cout << "有一块红色的肉和一块面包。\n";
        std::cout << "输入 'red' 吃红肉, 'bread' 吃面包: ";
        
        std::string choice;
        std::cin >> choice;
        
        if (choice == "red") {
            printColored("你吃下了红肉。味道腥甜...\n", Color::RED);
            health -= 30;
            updateSanity(-20);
            std::cout << "你感到剧烈腹痛,理智大幅下降!\n";
        } else if (choice == "bread") {
            std::cout << "面包虽然发霉了,但还能吃。\n";
            health += 10;
            updateSanity(5);
        } else {
            std::cout << "你决定不吃。\n";
        }
        
        if (health <= 0) gameOver("你死于食物中毒。");
        currentLocation = "Cafeteria";
    }

    void handleRoom101Inspect() {
        std::cout << "你检查床头柜...\n";
        if (!hasKey) {
            std::cout << "你发现了一把生锈的钥匙!\n";
            inventory.push_back("Rusty Key");
            hasKey = true;
            printColored("获得物品: 生锈的钥匙\n", Color::GREEN);
        } else {
            std::cout << "抽屉是空的。\n";
        }
        currentLocation = "Room101";
    }

    void handleRestroomMirror() {
        std::cout << "你走向镜子...\n";
        // 简单模拟时间,这里假设如果理智低或者随机触发危险
        if (sanity < 50 || rand() % 3 == 0) {
            printColored("镜子里的倒影没有模仿你的动作,它在笑!\n", Color::RED);
            updateSanity(-30);
            health -= 10;
            if (health <= 0) gameOver("被镜中恶灵吞噬。");
        } else {
            std::cout << "镜子里只有你疲惫的脸。\n";
            updateSanity(-5);
        }
        currentLocation = "Restroom";
    }

    void handleEscape() {
        if (hasKey) {
            printColored("你用钥匙打开了大门!\n", Color::GREEN);
            std::cout << "清新的空气涌入。你逃出来了!\n";
            hasEscaped = true;
            isAlive = false;
            gameWin();
        } else {
            std::cout << "门被锁住了。你需要一把钥匙。\n";
        }
    }

    void gameOver(const std::string& reason) {
        isAlive = false;
        std::cout << "\n========================================\n";
        printColored("【GAME OVER】\n", Color::RED);
        std::cout << "死因: " << reason << std::endl;
        std::cout << "========================================\n";
    }

    void gameWin() {
        std::cout << "\n========================================\n";
        printColored("【SUCCESS】\n", Color::GREEN);
        std::cout << "恭喜你成功逃离了规则怪谈公寓!\n";
        std::cout << "最终理智: " << sanity << std::endl;
        std::cout << "========================================\n";
    }

    void run() {
        std::cout << "欢迎来到《规则怪谈:公寓逃生》\n";
        std::cout << "输入 'help' 查看操作指南,输入 'rules' 查看规则。\n";
        std::cout << locationDescs["Entrance"] << std::endl;

        std::string input;
        while (isAlive) {
            std::cout << "\n> ";
            std::getline(std::cin, input);
            
            // 简单的命令解析,取第一个单词作为命令
            std::istringstream iss(input);
            std::string cmd;
            iss >> cmd;
            
            if (!cmd.empty()) {
                processCommand(cmd);
            }
        }
    }
};

int main() {
    GameEngine game;
    game.run();
    return 0;
}