#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;
}