//CZ原创水印 
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector>
#include <fstream>
#include <cstdio>
using namespace std;

// 全局变量
int san = 100, clue = 0, day = 1, deathCount = 0;
int money = 400, courage = 50, dormFavor = 0;
string playerName;
bool hasNote = false, hasCard = false, hasKey = false;
bool hasFlash = false, hasFood = false, hasRadio = false, hasTalisman = false;
bool metGhost = false, savedDorm = false, ruleBroken = false;
bool gameWin = false, isHardMode = false, trueEnding = false;
bool visited4F = false, visitedRoof = false, visitedHall = false;
string weather[] = {"晴天", "阴天", "雨夜", "血月"};
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

// 函数提前声明
void showTitle(string t, int c);
void waitKey();
void fourFloorEvent();
void exploreMap();
void useItem();
void shop();
void showRules();
void noteEvent();
void cardEvent();
void firstNight();
void meetDormKeeper();
void blackGirlEvent();
void roofFinal();
void randomEvent();
bool checkSanity();
void daySummary();
void saveGame();
void loadGame();

// 控制台颜色
void setColor(int c)
{
	SetConsoleTextAttribute(hConsole, c);
}

// 逐字慢速打印
void slowPrint(string t, int s = 30)
{
	for (char ch : t)
	{
		cout << ch;
		Sleep(s);
	}
}

// 标题界面
void showTitle(string t, int c)
{
	system("cls");
	setColor(c);
	cout << "================================" << endl;
	cout << "          " << t << "          " << endl;
	cout << "================================" << endl << endl;
	setColor(7);
}

// 按任意键继续
void waitKey()
{
	cout << endl << "按任意键继续...";
	getch();
}

// 存档
void saveGame()
{
	ofstream out("save_dorm.txt");
	out << san << " " << clue << " " << day << " " << deathCount << " " << money << " " << courage << " " << dormFavor << endl;
	out << hasNote << " " << hasCard << " " << hasKey << " " << hasFlash << " " << hasFood << " " << hasRadio << " " << hasTalisman << endl;
	out << metGhost << " " << savedDorm << " " << ruleBroken << " " << gameWin << " " << isHardMode << endl;
	out << visited4F << " " << visitedRoof << " " << visitedHall << " " << trueEnding << endl;
	out << playerName << endl;
	out.close();
	showTitle("存 档 成 功", 10);
	slowPrint("游戏进度已安全保存!");
	Sleep(1000);
}

// 读档
void loadGame()
{
	ifstream in("save_dorm.txt");
	if (!in)
	{
		showTitle("读 档 失 败", 12);
		slowPrint("未找到存档文件,请开始新游戏!");
		waitKey();
		return;
	}
	in >> san >> clue >> day >> deathCount >> money >> courage >> dormFavor;
	in >> hasNote >> hasCard >> hasKey >> hasFlash >> hasFood >> hasRadio >> hasTalisman;
	in >> metGhost >> savedDorm >> ruleBroken >> gameWin >> isHardMode;
	in >> visited4F >> visitedRoof >> visitedHall >> trueEnding;
	in >> playerName;
	in.close();
	showTitle("读 档 成 功", 10);
	slowPrint("欢迎回来," + playerName + "!");
	Sleep(1000);
}

// 宿舍楼生存规则
void showRules()
{
	showTitle("宿 舍 楼 生 存 规 则", 11);
	setColor(14);
	cout << "【1】22:30 后禁止离开宿舍" << endl;
	cout << "【2】禁止回应楼道里的哭声" << endl;
	cout << "【3】电梯禁止按4楼,不存在4楼" << endl;
	cout << "【4】镜子出现第二人影立刻闭眼" << endl;
	cout << "【5】听到口哨声必须捂住耳朵" << endl;
	cout << "【6】不要接受陌生人递来的饮料" << endl;
	cout << "【7】零点整绝对不要看向窗外" << endl;
	cout << "【8】4楼禁止独自进入" << endl;
	cout << "【9】不要完全相信穿黑衣的女生" << endl;
	cout << "【10】捡到褪色学生证务必收好" << endl;
	setColor(7);
	cout << endl << "违反规则,将会被永远留在宿舍楼!" << endl;
	waitKey();
}

// 楼下便利店商店
void shop()
{
	showTitle("楼 下 便 利 店", 10);
	cout << "当前金钱:" << money << "¥" << endl << endl;
	cout << "1. 手电筒(200¥)- 黑暗区域必备" << endl;
	cout << "2. 夹心面包(150¥)- 恢复30理智" << endl;
	cout << "3. 老式收音机(300¥)- 驱散灵异" << endl;
	cout << "4. 平安护身符(500¥)- 免疫一次死亡" << endl;
	cout << "5. 退出商店" << endl << endl;
	cout << "请选择:";
	char c = getch();
	if (c == '1' && money >= 200)
	{
		hasFlash = true;
		money -= 200;
		slowPrint("你购买了手电筒!");
	}
	else if (c == '2' && money >= 150)
	{
		hasFood = true;
		money -= 150;
		slowPrint("你购买了夹心面包!");
	}
	else if (c == '3' && money >= 300)
	{
		hasRadio = true;
		money -= 300;
		slowPrint("你购买了老式收音机!");
	}
	else if (c == '4' && money >= 500)
	{
		hasTalisman = true;
		money -= 500;
		slowPrint("你购买了平安护身符!");
	}
	else if (c != '5')
		slowPrint("金钱不足!");
	waitKey();
}

// 使用道具
void useItem()
{
	showTitle("道 具 栏", 11);
	cout << "当前持有道具:" << endl;
	if (hasFood) cout << "1. 夹心面包(恢复30理智)" << endl;
	if (hasFlash) cout << "2. 手电筒(黑暗照明)" << endl;
	if (hasRadio) cout << "3. 收音机(驱散鬼魂)" << endl;
	if (hasTalisman) cout << "4. 平安护身符(免死一次)" << endl;
	cout << "5. 退出道具栏" << endl << endl;
	cout << "选择要使用的道具:";
	char c = getch();
	if (c == '1' && hasFood)
	{
		san += 30;
		if (san > 100) san = 100;
		hasFood = false;
		slowPrint("你吃下面包,精神缓和!理智+30");
	}
	else if (c == '2' && hasFlash)
	{
		slowPrint("手电筒亮起,黑暗不再恐怖!");
		courage += 10;
	}
	else if (c == '3' && hasRadio)
	{
		slowPrint("收音机发出沙沙白噪音,周遭阴冷消散!");
		metGhost = false;
		san += 10;
	}
	else if (c == '4' && hasTalisman)
	{
		slowPrint("护身符微微发热,一层屏障护住了你。");
	}
	waitKey();
}

// 地图探索
void exploreMap()
{
	showTitle("宿 舍 楼 地 图", 11);
	cout << "当前天气:" << weather[rand() % 4] << endl << endl;
	cout << "1. 你的宿舍(安全区域)" << endl;
	cout << "2. 宿舍楼走廊(中等危险)" << endl;
	cout << "3. 四楼区域(高危区域)" << endl;
	cout << "4. 楼顶天台(极高危险)" << endl;
	cout << "5. 返回主菜单" << endl << endl;
	cout << "选择探索区域:";
	char c = getch();
	if (c == '1')
	{
		showTitle("宿舍房间", 10);
		slowPrint("你回到宿舍,这里暂时安全。");
		san += 5;
	}
	else if (c == '2')
	{
		visitedHall = true;
		showTitle("宿舍走廊", 12);
		slowPrint("日光灯管不断闪烁,空气冰冷潮湿。");
		if (rand() % 2 == 0)
		{
			slowPrint("你在窗台捡到一张泛黄纸条!线索+1");
			clue += 1;
		}
		else
		{
			slowPrint("身后传来缓慢的脚步声……\n理智-10");
			san -= 10;
		}
	}
	else if (c == '3')
	{
		visited4F = true;
		fourFloorEvent();
	}
	else if (c == '4')
	{
		visitedRoof = true;
		if (day < 7)
		{
			showTitle("天台大门", 12);
			slowPrint("天台铁门牢牢锁死,第七天才会开启!");
		}
		else
			roofFinal();
	}
	waitKey();
}

// 每日行动菜单
void dailyAction()
{
	showTitle("第" + to_string(day) + "天 - 行 动 选 择", 11);
	cout << "1. 区域探索  2. 使用道具  3. 前往便利店" << endl;
	cout << "4. 查看规则  5. 保存游戏  6. 读取游戏" << endl;
	cout << endl << "请选择行动:";
	char c = getch();
	if (c == '1') exploreMap();
	else if (c == '2') useItem();
	else if (c == '3') shop();
	else if (c == '4') showRules();
	else if (c == '5') saveGame();
	else if (c == '6') loadGame();
}

// 游戏开局
void gameStart()
{
	system("cls");
	setColor(12);
	cout << "╔═════════════════════════════════╗" << endl;
	cout << "║     规 则 怪 谈 - 午 夜 宿 舍     ║" << endl;
	cout << "║            完 整 版               ║" << endl;
	cout << "╚═════════════════════════════════╝" << endl << endl;
	setColor(7);

	showTitle("难 度 选 择", 11);
	cout << "1. 普通模式(理智正常消耗,新手推荐)" << endl;
	cout << "2. 困难模式(理智双倍消耗,硬核挑战)" << endl;
	char c = getch();
	if (c == '2') isHardMode = true;

	showTitle("入 住 第 一 天", 11);
	cout << "请输入你的名字:";
	cin >> playerName;
	system("cls");

	setColor(14);
	cout << "========================================" << endl;
	cout << "           深秋 雨夜 23:05              " << endl;
	cout << "========================================" << endl << endl;
	setColor(7);

	slowPrint(playerName + ",你因为校外租房涨价,临时住进老旧宿舍楼。\n");
	Sleep(800);
	slowPrint("宿管大爷递来一张纸,严肃提醒你务必遵守上面的规则。\n");
	Sleep(800);
	setColor(12);
	slowPrint("'一旦打破规则,你永远无法离开这栋楼!'\n");
	setColor(7);
	Sleep(1000);
	showRules();

	slowPrint("打扫房间时,你发现前住户遗留三样物品:\n");
	cout << "1. 残破笔记\n";
	cout << "2. 褪色学生证\n";
	cout << "3. 生锈铁门钥匙\n";
	cout << "选择带走一件物品:";
	char choice = getch();
	if (choice == '1')
	{
		hasNote = true;
		slowPrint("\n你收下残破笔记...");
	}
	else if (choice == '2')
	{
		hasCard = true;
		slowPrint("\n你收下褪色学生证...");
	}
	else if (choice == '3')
	{
		hasKey = true;
		slowPrint("\n你收下生锈钥匙...");
	}
	slowPrint("\n夜幕彻底降临,楼道响起模糊口哨声,恐怖悄然到来...");
	Sleep(1500);
}

// 残破笔记剧情
void noteEvent()
{
	showTitle("残 破 笔 记", 14);
	slowPrint("纸上字迹越来越扭曲,记录着两年前的悲剧:\n\n");
	Sleep(1000);
	setColor(12);
	cout << "「9月22日」" << endl;
	setColor(7);
	slowPrint("小雅和小晚是最好朋友,却因为误会彻底决裂。");
	Sleep(800);
	setColor(12);
	cout << endl << "「9月24日」" << endl;
	setColor(7);
	slowPrint("争吵不断,小雅摔坏了两人的合照。");
	Sleep(800);
	setColor(12);
	cout << endl << "「9月26日」" << endl;
	setColor(7);
	slowPrint("天台争执,小晚失足跌落……");
	Sleep(800);
	setColor(12);
	cout << endl << "「9月28日」" << endl;
	setColor(7);
	slowPrint("四楼储物柜存放着小晚遗物,钥匙在往届租客手里。");
	Sleep(800);
	setColor(12);
	cout << endl << "「9月30日」" << endl;
	setColor(7);
	slowPrint("她不肯离去,怨恨笼罩整栋宿舍楼,下一个就是我……");
	clue += 5;
	dormFavor += 16;
	san -= 15;
	cout << endl << endl << "线索+5,理智-15,小晚好感度+16,当前线索:" << clue << endl;
	waitKey();
}

// 褪色学生证剧情
void cardEvent()
{
	showTitle("褪 色 学 生 证", 14);
	slowPrint("证件照片上,女孩笑容苍白,名字:林晚。\n");
	Sleep(1000);
	slowPrint("背面用铅笔淡淡写着一行字:\n");
	setColor(12);
	slowPrint("'小雅,我不想带着恨意一直徘徊……'");
	setColor(7);
	Sleep(1000);
	slowPrint("\n恍惚之间,照片上女孩的视线转向了你!");
	san -= 25;
	clue += 3;
	metGhost = true;
	dormFavor += 10;
	cout << endl << "理智-25,线索+3,小晚好感度+10" << endl;
	waitKey();
}

// 第一夜剧情
void firstNight()
{
	showTitle("第 一 夜 - 恐 惧 入 眠", 12);
	slowPrint("你躺在床上,窗外雨水拍打玻璃。\n");
	Sleep(1000);
	slowPrint("朦胧梦境中,天台边缘站着一个孤单身影。\n");
	Sleep(1000);
	slowPrint("'没有人愿意听懂我的委屈……'");
	Sleep(1000);
	cout << endl << "你猛然惊醒,墙上时钟显示:00:00" << endl;
	setColor(12);
	cout << "【规则7警告】绝对不要看向窗外!" << endl;
	setColor(7);
	cout << endl << "1. 好奇看向窗外" << endl;
	cout << "2. 紧闭双眼默念规则" << endl;
	cout << "3. 蒙住脑袋不敢动弹" << endl;
	char choice = getch();
	if (choice == '1')
	{
		ruleBroken = true;
		slowPrint("\n窗外一张惨白面孔紧贴玻璃,空洞双眼盯着你!");
		san -= 50;
	}
	else if (choice == '2')
	{
		slowPrint("\n严格遵守规则,惊险度过第一夜。");
		san += 10;
		courage += 5;
	}
	else
	{
		slowPrint("\n巨大恐惧压迫心神,精神持续消耗。");
		san -= 25;
	}
	waitKey();
}

// 宿管支线
void meetDormKeeper()
{
	showTitle("第" + to_string(day) + "天 - 守 楼 大 爷", 14);
	slowPrint("你在走廊碰到宿管大爷,他叹气看着你。\n");
	Sleep(1000);
	slowPrint("'我守这栋楼十几年,两年前那件事我全都看见。'");
	Sleep(1000);
	slowPrint("'小晚意外离世,执念不散困在这里,诅咒所有住户。'");
	Sleep(1000);
	slowPrint("'小雅活在无尽愧疚之中,灵魂同样被困宿舍楼。'");
	clue += 4;
	dormFavor += 5;
	cout << endl << "线索+4,小晚好感度+5" << endl;
	cout << "1. 询问化解执念办法 2. 询问完整真相 3. 询问小雅下落" << endl;
	char c = getch();
	if (c == '1')
	{
		slowPrint("\n'找到遗物与道歉信,解开误会,她才能放下执念。'");
		clue += 3;
	}
	else if (c == '2')
	{
		slowPrint("\n'只是争执意外,小雅从来没有想要伤害她。'");
		dormFavor += 20;
	}
	else if (c == '3')
	{
		slowPrint("\n'小雅的魂魄,日复一日在楼内寻找赎罪机会。'");
		clue += 2;
	}
	waitKey();
}

// 黑衣小雅事件
void blackGirlEvent()
{
	showTitle("黑 衣 女 孩", 13);
	slowPrint("一名黑衣女生出现在走廊,她就是小雅。\n");
	Sleep(1000);
	slowPrint("'帮帮我,我想要和小晚好好道歉。'");
	Sleep(1000);
	cout << "1. 选择相信她 2. 警惕拒绝 3. 交出遗物" << endl;
	char c = getch();
	if (c == '1')
	{
		slowPrint("\n小雅十分感激,内心愧疚得到一丝宽慰!");
		dormFavor += 35;
		clue += 3;
	}
	else if (c == '2')
	{
		slowPrint("小雅表情慢慢变得阴冷诡异……");
		san -= 50;
	}
	else if (c == '3' && savedDorm)
	{
		slowPrint("\n你将遗物交给她,泪水从她脸颊滑落。");
		trueEnding = true;
		clue += 7;
	}
	waitKey();
}

// 四楼探索
void fourFloorEvent()
{
	showTitle("四 楼 - 执 念 迷 境", 8);
	setColor(8);
	cout << "空气阴冷死寂,远处断断续续传来女孩啜泣声。" << endl << endl;
	setColor(7);
	if (!hasKey)
	{
		slowPrint("储物柜区域铁门紧锁,布满抓痕,需要钥匙开启。");
		waitKey();
		return;
	}
	if (!hasFlash)
	{
		slowPrint("四周伸手不见五指,没有手电筒无法前进!");
		waitKey();
		return;
	}
	slowPrint("钥匙打开铁门,手电筒光芒刺破黑暗。\n");
	Sleep(1000);
	slowPrint("一排老旧储物柜,最内侧柜子微微敞开。\n");
	Sleep(1000);
	cout << "1. 打开储物柜 2. 搜寻角落 3. 立刻逃离四楼" << endl;
	char choice = getch();
	if (choice == '1')
	{
		slowPrint("\n柜子内:破损合照 + 手写道歉信 + 小晚随身发圈!");
		Sleep(1000);
		slowPrint("\n'如果能重来,我不会和你吵架。'");
		clue += 5;
		savedDorm = true;
		san += 25;
		dormFavor += 25;
	}
	else if (choice == '2')
	{
		slowPrint("\n你触碰到一片冰冷,仿佛握住一只冰凉手掌!");
		san -= 50;
	}
	else
	{
		slowPrint("\n你狂奔离开四楼,巨大寒意紧紧跟随。");
		courage -= 15;
		san -= 30;
	}
	waitKey();
}

// 天台最终决战(多结局)
void roofFinal()
{
	showTitle("第7天 - 天 台 终 局", 12);
	if (!savedDorm)
	{
		slowPrint("林晚漂浮在天台边缘,周身缠绕浓重黑雾。\n");
		Sleep(1000);
		slowPrint("'你没能理解我的痛苦,留下来永远陪我吧!'");
		if (hasTalisman)
		{
			slowPrint("\n护身符爆发微光,替你挡下致命攻击!");
			hasTalisman = false;
			san = 20;
		}
		else
		{
			san -= 999;
			setColor(12);
			cout << endl << "=== 坏结局:永恒囚笼 ===" << endl;
		}
	}
	else if (trueEnding && dormFavor >= 80)
	{
		slowPrint("你拿出合照与信件,两道身影缓缓显现。\n");
		Sleep(1000);
		slowPrint("'我早就不怪你了。' '对不起,小晚。'");
		Sleep(1000);
		slowPrint("\n两道光影相拥消散,宿舍楼的诅咒彻底消散。");
		setColor(10);
		cout << endl << "=== 真结局:误会消融 ===" << endl;
		gameWin = true;
	}
	else
	{
		slowPrint("你拿出遗物,林晚脸上浮现释然的笑意。\n");
		Sleep(1000);
		slowPrint("'谢谢你,我终于可以放下执念离开了……'");
		Sleep(1000);
		slowPrint("\n虚影随风散去,笼罩宿舍楼的阴霾消失。");
		setColor(10);
		cout << endl << "=== 好结局:执念解脱 ===" << endl;
		gameWin = true;
	}
	waitKey();
}

// 随机灵异事件
void randomEvent()
{
	vector<string> events = {
		"电梯数字乱跳,短暂出现不存在的4楼标识",
		"镜子里的人影迟迟没有模仿你的动作",
		"门外女孩轻声呼喊:能陪我说说话吗",
		"天花板滴落冰凉水珠,闻起来带着铁锈味",
		"广播自动播放两年前校园文艺晚会录音",
		"耳边持续传来梳头声,房间只有你一人",
		"墙面渗出暗色水渍,慢慢拼成“别走”",
		"你的影子分裂为两道,一黑一白",
		"整条走廊灯光全部熄灭,角落闪过白影",
		"手机自动拨号,听筒传来悲伤的口哨声"
	};
	int idx = rand() % events.size();
	showTitle("诡 异 事 件", 12);
	slowPrint(events[idx] + "...\n");
	Sleep(1000);
	int lose = isHardMode ? 30 : 20;
	san -= lose;
	slowPrint("理智-" + to_string(lose));
	if (idx < 3)
	{
		setColor(12);
		cout << endl << "【疑似违反规则】额外扣除理智15点!" << endl;
		setColor(7);
		san -= 15;
		ruleBroken = true;
	}
	waitKey();
}

// 理智检测
bool checkSanity()
{
	if (san <= 0)
	{
		showTitle("理 智 崩 溃", 12);
		slowPrint("你的精神彻底瓦解,永远被困在午夜宿舍楼……\n");
		deathCount++;
		setColor(12);
		cout << "死亡次数:" << deathCount << endl;
		setColor(7);
		cout << "重新开始游戏?(y/n):";
		if (getch() == 'y')
		{
			san = 100;
			clue = 0;
			day = 1;
			money = 400;
			hasNote = hasCard = hasKey = false;
			metGhost = savedDorm = ruleBroken = false;
			return true;
		}
		return false;
	}
	if (san < 30)
	{
		setColor(12);
		cout << "??  警告:理智濒临崩溃  ??" << endl;
		setColor(7);
		Sleep(1000);
	}
	return true;
}

// 每日状态总结
void daySummary()
{
	showTitle("第" + to_string(day) + "天 总 结", 10);
	cout << "【角色状态】" << endl;
	cout << "理智值:" << san << "/100    线索:" << clue << "/25" << endl;
	cout << "金钱:" << money << "¥    勇气:" << courage << "/100" << endl;
	cout << "小晚好感度:" << dormFavor << "/100" << endl << endl;
	cout << "【持有道具】" << endl;
	if (hasNote) cout << "残破笔记 ";
	if (hasCard) cout << "学生证 ";
	if (hasKey) cout << "铁门钥匙 ";
	if (hasFlash) cout << "手电筒 ";
	if (hasFood) cout << "面包 ";
	if (hasRadio) cout << "收音机 ";
	if (hasTalisman) cout << "平安符 ";
	cout << endl;
	waitKey();
}

// 主函数
int main()
{
	srand((unsigned int)time(0));
	CONSOLE_CURSOR_INFO cursorInfo;
	GetConsoleCursorInfo(hConsole, &cursorInfo);
	cursorInfo.bVisible = false;
	SetConsoleCursorInfo(hConsole, &cursorInfo);

	system("title 规则怪谈:午夜宿舍楼");
	system("mode con cols=60 lines=30");

	setColor(12);
	cout << "╔═════════════════════════════════╗" << endl;
	cout << "║     规 则 怪 谈 - 午 夜 宿 舍   ║" << endl;
	cout << "║            完 整 版             ║" << endl;
	cout << "╚═════════════════════════════════╝" << endl << endl;
	setColor(7);
	slowPrint("欢迎入住午夜宿舍楼,活下去,解开尘封往事...");
	Sleep(1500);

	cout << "1. 新游戏    2. 读取存档" << endl;
	char c = getch();
	if (c == '2') loadGame();
	else gameStart();

	// 游戏主循环
	while (day <= 7)
	{
		dailyAction();
		if (day == 1) firstNight();
		else if (day == 2 && hasNote) noteEvent();
		else if (day == 2 && hasCard) cardEvent();
		else if (day == 3) meetDormKeeper();
		else if (day == 4 && dormFavor >= 50) blackGirlEvent();
		else if (day >= 5 && day <= 6)
		{
			for (int i = 0; i < 2; i++)
			{
				randomEvent();
				if (!checkSanity()) break;
			}
		}
		else if (day == 7)
		{
			roofFinal();
			break;
		}

		if (!checkSanity()) break;
		daySummary();
		day++;
		money += 100;
	}

	// 恢复光标
	cursorInfo.bVisible = true;
	SetConsoleCursorInfo(hConsole, &cursorInfo);
	if (gameWin)
	{
		system("cls");
		setColor(10);
		slowPrint("恭喜你解开执念,活着走出午夜宿舍楼!");
		Sleep(2000);
	}
	system("cls");
	showTitle("游 戏 结 束", 12);
	cout << "感谢游玩《规则怪谈:午夜宿舍楼》!" << endl;
	return 0;
}