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