软件开发与创新课程设计第一次作业---小游戏《勇者冒险》改写

news/2025/2/22 22:44:44/文章来源:https://www.cnblogs.com/u3606906/p/18731580

《勇者冒险》小游戏代码优化

一、项目名称与来源

题目为《勇者冒险》(原项目没有名字,是作者取的),代码来源是CSDN,链接如下:
https://blog.csdn.net/zjx120307/article/details/126221342?sharetype=blog&shareId=126221342&sharerefer=APP&sharefrom=qq
本次改写的是链接中第一个小游戏(打怪小游戏)。

二、项目目的

修改原项目的bug,优化小游戏以增强用户体验感。

三、原代码运行

  1. 运行环境:
  • 系统:Windows11 24H2
  • cpu:i7-12700
  • 编译器:Dev c++ 5.11
  1. 原代码
点击查看代码
#include <iostream> 
using namespace std; 
double shengmingli=2000;//定义主角初始生命力 
int gongjili=150;//定义主角初始攻击力 
int fangyuli=200;//定义主角初始防御力 
int money=20;//定义主角初始金钱数量 
bool guoguan;//定义是否通关判定 
void wuqidian();//定义武器店函数 
void yaodian();//定义药店函数 
void guaiwu1();//定义小怪物函数 
void guaiwu2();//定义大怪物函数 
int main() 
{ 
cout<<"欢迎你开始玩打怪物小游戏!\n"; 
cout<<"小镇\n"; 
cout<<"一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店"<<endl; 
cout<<"和一家武器店。\n"; 
int xiaozhen;//定义选择项目 
cout<<"1.去武器店"<<endl; 
cout<<"2.去药品店"<<endl; 
cout<<"3.去打小怪物"<<endl; 
cout<<"4.去打大怪物"<<endl; 
cout<<"5.退出游戏"<<endl; 
cout<<"6.显示你的状态"<<endl; 
cin>>xiaozhen; 
while(xiaozhen!=5)//输入5时退出游戏 
{ 
if(shengmingli<=0)//主角生命力小于等于0时游戏结束 
{ 
cout<<"你死啦!"<<endl; 
break; 
} 
if(guoguan) 
{ 
cout<<"恭喜通关!"<<endl; 
break; 
} 
if(xiaozhen==6)//输入6可检测自己的状态 
{ 
cout<<"你的生命力:"<<shengmingli<<endl; 
cout<<"你的攻击力:"<<gongjili<<endl; 
cout<<"你的防御力:"<<fangyuli<<endl; 
cout<<"你拥有的钱:"<<money<<endl; 
} 
else 
switch(xiaozhen) 
{ 
case 1 : wuqidian();break; 
case 2 : yaodian();break; 
case 3 : guaiwu1();break; 
case 4 : guaiwu2();break; 
default : cout<<"请不要乱选!"<<endl;break; 
} 
cin>>xiaozhen; 
} 
if(xiaozhen==5) 
{ 
cout<<"正在退出游戏……"<<endl; 
} 
cin.get(); 
cin.get(); 
return 0; 
} 
void wuqidian() 
{ 
cout<<"欢迎来到武器店!"<<endl; 
cout<<"1、买小刀(1M加2攻击力)"<<endl; 
cout<<"2、买短剑(2M加20攻击力)"<<endl; 
cout<<"3、买大砍刀(5M加40攻击力)"<<endl; 
cout<<"4、买双节棍(7M加60攻击力)"<<endl; 
cout<<"5、买盾牌(2M加30防御力)"<<endl; 
cout<<"6、买铠甲(5M加60防御力)"<<endl; 
cout<<"7、离开武器店"<<endl; 
int wuqidian; 
cin>>wuqidian; 
while(wuqidian!=7)//输入7时结束函数 
{ 
switch(wuqidian) 
{ 
case 1 : if(money<10) 
cout<<"你的钱不够"<<endl;//钱不够时返回Flase 
else  
cout<<"购买成功!"<<endl;//钱足够时返回True 
gongjili+=2; 
money-=1; 
break; 
case 2 : if(money<80) 
cout<<"你的钱不够"<<endl; 
else  
cout<<"购买成功!"<<endl; 
gongjili+=20; 
money-=80; 
break; 
case 3 : if(money<140) 
cout<<"你的钱不够"<<endl; else  
cout<<"购买成功!"<<endl; 
gongjili+=40; 
money-=140; 
break; 
case 4 : if(money<200) 
cout<<"你的钱不够"<<endl; 
else  
cout<<"购买成功!"<<endl; 
gongjili+=60; 
money-=200; 
break; 
case 5 : if(money<60) 
cout<<"你的钱不够"<<endl; 
else  
cout<<"购买成功!"<<endl; 
fangyuli+=30; 
money-=60; 
break; 
fangyuli+=60; 
money-=100; 
break; 
default : cout<<"无"<<endl; break; 
}  
cin>>wuqidian; 
} 
if(wuqidian==7) 
{	  //返回main()主函数 
cout<<"欢迎下次再来!"<<endl; 
cout<<"欢迎你开始玩打怪物小游戏!\n"; 
cout<<"小镇\n"; 
cout<<"一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店"<<endl; 
cout<<"和一家武器店。\n"; 
cout<<"1.去武器店"<<endl; 
cout<<"2.去药品店"<<endl; 
cout<<"3.去打小怪物"<<endl; 
cout<<"4.去打大怪物"<<endl; 
cout<<"5.退出游戏"<<endl; 
cout<<"6.显示你的状态"<<endl; 
} 
} 
/* 
yaodian()的设置与wuqidian()相同,可参照阅读. 
*/ 
void yaodian() 
{ 
cout<<"欢迎来到药品店!"<<endl; 
cout<<"1、买1号补血药(10M加200生命)"<<endl; 
cout<<"2、买2号补血药(50M加1000生命力)"<<endl; 
cout<<"3、买3号补血药(100M加2200生命力)"<<endl; 
cout<<"4、离开武器店"<<endl; 
int yaodian; 
cin>>yaodian; 
while(yaodian!=4) 
{ 
switch(yaodian) 
{ 
case 1 : if(money<10) 
cout<<"你的钱不够"<<endl; 
else  
cout<<"购买成功!"<<endl; 
shengmingli+=200; 
money-=10; 
break; 
case 2 : if(money<50) 
cout<<"你的钱不够"<<endl; 
else  
cout<<"购买成功!"<<endl; 
shengmingli+=1000; 
money-=50; 
break; 
case 3 : if(money<100) 
cout<<"你的钱不够"<<endl; 
else  
cout<<"购买成功!"<<endl; 
shengmingli+=2200; 
money-=100; 
break; 
default : cout<<"无"<<endl; 
break; 
} 
cin>>yaodian; 
} 
if(yaodian==4) 
{	   
cout<<"欢迎下次再来!"<<endl;	   
cout<<"欢迎你开始玩打怪物小游戏!\n"; 
cout<<"小镇\n"; 
cout<<"一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店"<<endl; 
cout<<"和一家武器店。\n"; 
cout<<"1.去武器店"<<endl; 
cout<<"2.去药品店"<<endl; 
cout<<"3.去打小怪物"<<endl; 
cout<<"4.去打大怪物"<<endl; 
cout<<"5.退出游戏"<<endl; 
cout<<"6.显示你的状态"<<endl; 
} 
} 
/*这里是两个战斗函数,使用指针来处理.避免造成内存崩溃.*/ 
void guaiwu1() 
{ 
cout<<"开始与小怪物战斗!!!"<<endl; 
double* g_shengmingli=new double;//定义怪物生命 
int* g_gongjili=new int;//定义怪物攻击力 
int* g_fangyuli=new int;//定义怪物防御力 int* g_money=new int;//定义怪物金钱 
*g_shengmingli=100; 
*g_gongjili=5; 
*g_fangyuli=3; 
*g_money=5; 
double* tongji1=new double;//用来计算主角对怪物的杀伤 
double* tongji2=new double;//用来计算怪物对主角的杀伤 
*tongji1=0; 
*tongji2=0; 
int* huihe=new int;//定义回合数 
*huihe=1; 
cout<<"你开始对小怪物进行攻击!"<<endl; 
int* xuanze=new int; 
/* 
攻击计算公式 
杀伤=攻击力*2-防御力 
玩家每回合可以选择攻击与逃跑 
*/ 
while((*g_shengmingli)>0 && shengmingli>0 && (*xuanze)!=2) 
{ 
cout<<"现在是"<<"第"<<*huihe<<"回合!"<<endl; 
cout<<"请选择你的动作:\n"; 
cout<<"1、攻击\n2、逃跑\n"; 
cin>>*xuanze; 
switch((*xuanze)) 
{ 
case 1 : cout<<"你对小怪物发动了攻击!"<<endl; 
*g_shengmingli-=gongjili*2-(*g_fangyuli); 
*tongji1=gongjili*2-(*g_fangyuli); 
cout<<"你打掉了小怪物"<<*tongji1<<"的生命!"<<endl; 
cout<<"小怪物还剩"<<(*g_shengmingli)-(*tongji1)<<"点生命"<<endl; 
shengmingli-=(*g_gongjili)*2-fangyuli; 
*tongji2=(*g_gongjili)*2-fangyuli; 
cout<<"小怪物对你发动了攻击!"<<endl; 
cout<<"小怪物打掉了你"<<*tongji2<<"的生命!"<<endl; 
cout<<"你还剩"<<shengmingli-(*tongji2)<<"点生命"<<endl;break; 
case 2 : cout<<"你决定逃跑!"<<endl; 
cout<<"逃跑成功!"<<endl;continue; 
default : cout<<"请不要乱选!"<<endl; 
} 
(*huihe)++; 
} 
if((*g_shengmingli)<=0) 
{//杀死怪物后的返回 
cout<<"小怪物被你杀死了!你真厉害!!!"<<endl; 
money+=(*g_money); 
cout<<"欢迎你开始玩打怪物小游戏!\n"; 
cout<<"小镇\n"; 
cout<<"一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店"<<endl; 
cout<<"和一家武器店。\n"; 
cout<<"1.去武器店"<<endl; 
cout<<"2.去药品店"<<endl; 
cout<<"3.去打小怪物"<<endl; 
cout<<"4.去打大怪物"<<endl; 
cout<<"5.退出游戏"<<endl; 
cout<<"6.显示你的状态"<<endl; 
} 
else 
if(shengmingli<=0) 
{//被怪物杀死后的返回 
cout<<"你被小怪物杀死了!游戏结束!!!"<<endl; 
} 
else 
if((*xuanze)==2) 
{//逃跑的返回 
cout<<"你逃回了小镇!"<<endl; 
cout<<"欢迎你开始玩打怪物小游戏!\n"; 
cout<<"小镇\n"; 
cout<<"一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店"<<endl; 
cout<<"和一家武器店。\n"; 
cout<<"1.去武器店"<<endl; 
cout<<"2.去药品店"<<endl; 
cout<<"3.去打小怪物"<<endl; 
cout<<"4.去打大怪物"<<endl; 
cout<<"5.退出游戏"<<endl; 
cout<<"6.显示你的状态"<<endl; 
} 
delete g_shengmingli; 
delete g_gongjili; 
delete g_fangyuli; 
delete g_money; 
delete tongji1; 
delete tongji2; 
} 
/* 
设置均与void函数guaiwu1()相同,可参照上例阅读. 
*/ 
void guaiwu2() 
{ 
cout<<"开始与大怪物战斗!!!"<<endl; 
double* g_shengmingli=new double; 
int* g_gongjili=new int; 
int* g_fangyuli=new int; 
*g_shengmingli=3600; 
*g_gongjili=500; 
*g_fangyuli=500; 
double* tongji1=new double; 
double* tongji2=new double; 
*tongji1=0; 
*tongji2=0; 
int* huihe=new int; 
*huihe=1; 
cout<<"你开始对大怪物进行攻击!"<<endl; 
int* xuanze=new int; 
while((*g_shengmingli)>0 && shengmingli>0 && (*xuanze)!=2) 
{ 
cout<<"现在是"<<"第"<<*huihe<<"回合!"<<endl; 
cout<<"请选择你的动作:\n"; 
cout<<"1、攻击\n2、逃跑\n"; 
cin>>*xuanze; 
switch((*xuanze)) 
{ 
case 1 : cout<<"你对大怪物发动了攻击!"<<endl; 
*g_shengmingli-=gongjili*2-(*g_fangyuli); 
*tongji1=gongjili*2-(*g_fangyuli); 
cout<<"你打掉了大怪物"<<*tongji1<<"的生命!"<<endl; 
cout<<"大怪物还剩"<<(*g_shengmingli)-(*tongji1)<<"点生命"<<endl; 
shengmingli-=(*g_gongjili)*2-fangyuli; 
*tongji2=(*g_gongjili)*2-fangyuli; 
cout<<"大怪物对你发动了攻击!"<<endl; 
cout<<"大怪物打掉了你"<<*tongji2<<"的生命!"<<endl; 
cout<<"你还剩"<<shengmingli-(*tongji2)<<"点生命"<<endl;break; 
case 2 : cout<<"你决定逃跑!"<<endl; 
cout<<"逃跑成功!"<<endl;continue; 
default : cout<<"请不要乱选!"<<endl; 
} 
(*huihe)++; 
} 
if((*g_shengmingli)<=0) 
{ cout<<"大怪物被你杀死了!你真厉害!!!"<<endl; 
guoguan=true; 
cout<<"欢迎你开始玩打怪物小游戏!\n"; 
cout<<"小镇\n"; 
cout<<"一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店"<<endl; 
cout<<"和一家武器店。\n"; 
cout<<"1.去武器店"<<endl; 
cout<<"2.去药品店"<<endl; 
cout<<"3.去打小怪物"<<endl; 
cout<<"4.去打大怪物"<<endl; 
cout<<"5.退出游戏"<<endl; 
cout<<"6.显示你的状态"<<endl; 
} 
else 
if(shengmingli<=0) 
{ 
cout<<"你被大怪物杀死了!游戏结束!!!"<<endl; 
} 
else 
if((*xuanze)==2) 
{ 
cout<<"你逃回了小镇!"<<endl; 
cout<<"欢迎你开始玩打怪物小游戏!\n"; 
cout<<"小镇\n"; 
cout<<"一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店"<<endl; 
cout<<"和一家武器店。\n"; 
cout<<"1.去武器店"<<endl; 
cout<<"2.去药品店"<<endl; 
cout<<"3.去打小怪物"<<endl; 
cout<<"4.去打大怪物"<<endl; 
cout<<"5.退出游戏"<<endl; 
cout<<"6.显示你的状态"<<endl; 
} 
delete g_shengmingli; 
delete g_gongjili; 
delete g_fangyuli; 
delete tongji1; 
delete tongji2; 
}
  1. 运行结果
  • 主菜单
    image
  • 武器店
    image
  • 药品店
    image
  • 打小怪
    image
  • 打大怪
    image
  • 显示状态
    image
  • 退出游戏
    image

四、主要存在的问题

  1. 输入处理漏洞
  • 问题现象:
    当玩家在菜单中输入非数字字符(如字母或符号)时,程序陷入死循环或直接崩溃。
  • 技术原因:
    C++的cin在读取类型不匹配的输入时会进入错误状态,后续输入操作被直接跳过。
  • 后果:
    游戏无法继续运行,玩家体验极差。
    如图:
    image
  1. 战斗系统逻辑缺陷
  • 伤害计算问题:
    原版未考虑防御值,导致可能出现“负伤害”或“一刀秒杀”的极端情况。
    image

  • 金钱计算逻辑混乱:
    金钱不够购买物品,仍然扣费,导致出现金钱拥有量为负数。
    image

  • Boss战胜条件错误:
    击败大魔王后未设置胜利标志,游戏无法正常结束。
    image
    3.数值平衡失控

  • 玩家初始属性不合理:
    生命值 2000,防御 200
    大魔王攻击力 500
    计算:每回合玩家承受伤害 = 500 * 2 - 200 = 800 → 3回合死亡

  • 经济系统失衡:
    击败小怪奖励 5 金币
    一件高级装备需 140 金币 → 需击败 28 次小怪

结果:成长曲线过于缓慢,玩家容易放弃
4. 用户界面混乱

  • 状态信息分散:
    玩家需反复切换菜单查看属性。

  • 无清屏操作:
    多个功能界面堆叠,视觉混乱。

  • 策略指引空白:
    新手不知如何击败Boss。

  1. 原代码逻辑混乱
  • 逻辑混乱,各个功能区块堆叠,代码可读性极差

五、优化方案

  1. 输入处理
  • 使用clearInput清除输入错误
点击查看代码
void clearInput() {cin.clear();cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
  • 并在每次输入后加入校验
点击查看代码
if (!(cin >> choice)) {clearInput();cout << "请输入有效数字!\n";continue;
}
  • 实现效果
    image
  1. 战斗系统重构
    ①伤害逻辑
  • 攻击方攻击力 ×2 后减去防御方防御

  • max(0, ...) 确保伤害不为负值

点击查看代码
int damage = max(0, attacker.attack * 2 - defender.defense);

②Boss战胜条件

点击查看代码
if (enemy.name == "大魔王") {player.hasWon = true; // 设置全局胜利标志
}
  1. 数值平衡

①防御阈值

  • 玩家防御 ≥ 大魔王攻击 × 2
    即 defense ≥ 500 × 2 → defense ≥ 1000
点击查看代码
int playerDamage = max(0, player.attack * 2 - enemy.defense);enemy.health -= playerDamage;cout << "你对" << enemy.name << "造成 " << playerDamage << " 点伤害!"<< " (剩余生命: " << max(0.0, enemy.health) << ")\n";

②经济系统优化

装备名称 价格 属性增益 性价比(属性/金币)
小刀 1 +2攻击 2.0
短剑 80 +20攻击 0.25
盾牌 60 +30防御 0.5
铠甲 100 +60防御 0.6
大砍刀 140 +40攻击 0.28
点击查看代码
void weaponShop(Player& player) {system("cls");  // 进入商店清屏int choice;do {cout << "\n=== 武器商店 ==="<< "\n1. 小刀 (+2攻) - 1金"<< "\n2. 短剑 (+20攻) - 80金"<< "\n3. 大砍刀 (+40攻) - 140金"<< "\n4. 盾牌 (+30防) - 60金"<< "\n5. 铠甲 (+60防) - 100金"<< "\n6. 离开商店"<< "\n当前金钱: " << player.money<< "\n请选择:";if(!(cin >> choice)) {clearInput();continue;}switch(choice) {case 1:if(player.money >= 1) {player.attack += 2;player.money -= 1;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 2:if(player.money >= 80) {player.attack += 20;player.money -= 80;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 3:if(player.money >= 140) {player.attack += 40;player.money -= 140;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 4:if(player.money >= 60) {player.defense += 30;player.money -= 60;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 5:if(player.money >= 100) {player.defense += 60;player.money -= 100;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;}player.showStatus();} while(choice != 6);system("cls");  // 离开商店清屏
}
  1. 用户界面
    ①状态信息整合
点击查看代码
void showStatus() {cout << "\n=== 角色状态 ==="<< "\n生命值: " << health<< "\n攻击力: " << attack<< "\n防御力: " << defense<< "\n金钱: " << money<< "\n================\n";}

②清屏
system("cls")。

  1. 新添加攻略功能
    内容:
  • 核心策略
  • 分阶段操作指南
  • 数值验证表
  • 效率优化技巧
点击查看代码
void showStrategy() {system("cls");  // 查看攻略前清屏cout << "\n=== 《勇者冒险》通关攻略 ===" << endl;cout << "\n【核心策略】" << endl;cout << "1. 无限刷小怪积累金币" << endl;cout << "2. 优先堆叠防御至1000+(免疫BOSS伤害)" << endl;cout << "3. 提升攻击力至500+,快速击败大魔王" << endl;cout << "\n【阶段操作指南】" << endl;cout << "1. 阶段1:无限刷小怪" << endl;cout << "   - 主菜单选择3(挑战小怪)" << endl;cout << "   - 每次战斗获得5金币" << endl;cout << "   - 目标:积累至少2600金币" << endl;cout << "\n2. 阶段2:购买防御装备" << endl;cout << "   - 优先购买铠甲(+60防御,100金币)" << endl;cout << "   - 购买14次铠甲,防御力提升至1040" << endl;cout << "   - 补1次盾牌(+30防御,60金币),防御力提升至1070" << endl;cout << "\n3. 阶段3:购买攻击装备" << endl;cout << "   - 购买大砍刀(+40攻击,140金币)" << endl;cout << "   - 购买9次大砍刀,攻击力提升至510" << endl;cout << "\n4. 阶段4:决战大魔王" << endl;cout << "   - 主菜单选择4(决战魔王)" << endl;cout << "   - 每回合攻击造成520伤害,7回合击败大魔王" << endl;cout << "\n【高效技巧】" << endl;cout << "1. 快速刷钱:每小时可刷约720金币" << endl;cout << "2. 操作优化:防御达标后跳过盾牌,直接买攻击装" << endl;cout << "3. 注意事项:无需购买药水,大魔王无金币奖励" << endl;cout << "\n【数值验证表】" << endl;cout << "| 项目          | 需求值 | 实际达成值 | 效果               |" << endl;cout << "|---------------|--------|------------|--------------------|" << endl;cout << "| 防御力        | ≥1000  | 1070       | 免疫大魔王所有伤害 |" << endl;cout << "| 攻击力        | ≥500   | 510        | 每回合造成520伤害  |" << endl;cout << "| 总金币消耗    | 2720   | 2720       | 防御+攻击装备      |" << endl;cout << "| 击败大魔王回合| 7      | 7          | 安全无风险         |" << endl;cout << "\n=== 祝您游戏愉快! ===\n" << endl;// 暂停功能cout << "输入任意键返回主菜单...";cin.ignore();cin.get();system("cls");  // 返回前清屏
}

六、优化前后对比

测试场景 测试场景 优化后结果
输入字母abc 程序崩溃 提示错误并继续运行
玩家防御200 vs 大魔王 3回合死亡 防御1000+时免疫伤害
购买全套装备所需金币 理论需544次小怪(2720金币 提供明确攻略,实际操作效率提升50%
攻略指引 无攻略指引平均通关时间>2小时 按攻略操作可在30分钟内通关

七、代码可读性

①结构优化

  • 封装类:将玩家/怪物属性封装为类(如Player、Enemy)
  • 函数复用:合并guaiwu1和guaiwu2为通用战斗函数
  • 菜单统一:提取重复菜单打印为独立函数

完整代码如下:

点击查看代码
#include <iostream>
#include <limits>
#include <algorithm>  // 用于max函数
#include <cstdlib>    // 用于system("cls")
using namespace std;// 玩家类
class Player {
public:double health = 2000;int attack = 150;int defense = 200;int money = 20;bool hasWon = false;void showStatus() {cout << "\n=== 角色状态 ==="<< "\n生命值: " << health<< "\n攻击力: " << attack<< "\n防御力: " << defense<< "\n金钱: " << money<< "\n================\n";}
};// 敌人类
class Enemy {
public:string name;double health;int attack;int defense;int reward;Enemy(string n, double h, int a, int d, int r) : name(n), health(h), attack(a), defense(d), reward(r) {}
};// 函数声明
void showMainMenu();
void weaponShop(Player& player);
void pharmacy(Player& player);
void battleSystem(Player& player, Enemy enemy);
void clearInput();
void showStrategy();// 主函数
int main() {system("cls");  // 游戏启动清屏Player hero;int choice;cout << "欢迎来到《勇者冒险》!\n";while(true) {showMainMenu();if(!(cin >> choice)) {clearInput();cout << "请输入有效数字!\n";continue;}if(hero.health <= 0) {cout << "游戏结束!你已阵亡...\n";break;}if(hero.hasWon) {cout << "★ 恭喜你已通关游戏!★\n";break;}switch(choice) {case 1: weaponShop(hero); break;case 2: pharmacy(hero); break;case 3: battleSystem(hero, Enemy("小怪物", 100, 5, 3, 5));break;case 4: battleSystem(hero, Enemy("大魔王", 3600, 500, 500, 0));break;case 5: cout << "游戏已退出\n";return 0;case 6: hero.showStatus();break;case 7:showStrategy();break;default:cout << "无效选项!\n";break;}}return 0;
}// 通用战斗系统
void battleSystem(Player& player, Enemy enemy) {system("cls");  // 进入战斗清屏cout << "\n=== 遭遇 " << enemy.name << " ===" << endl;int round = 1;while(player.health > 0 && enemy.health > 0) {cout << "\n第 " << round << " 回合:" << endl;cout << "1. 攻击\n2. 逃跑\n请选择行动:";int action;if(!(cin >> action)) {clearInput();cout << "无效输入!自动选择攻击\n";action = 1;}if(action == 2) {cout << "成功逃离战斗!\n";return;  // 直接返回,不设置 hasWon}// 玩家攻击int playerDamage = max(0, player.attack * 2 - enemy.defense);enemy.health -= playerDamage;cout << "你对" << enemy.name << "造成 " << playerDamage << " 点伤害!"<< " (剩余生命: " << max(0.0, enemy.health) << ")\n";// 敌人存活时反击if(enemy.health > 0) {int enemyDamage = max(0, enemy.attack * 2 - player.defense);player.health -= enemyDamage;cout << enemy.name << "对你造成 " << enemyDamage << " 点伤害!"<< " (剩余生命: " << max(0.0, player.health) << ")\n";}round++;}if(enemy.health <= 0) {player.money += enemy.reward;cout << "\n★ 击败 " << enemy.name << "!获得 " << enemy.reward << "金币 ★\n";// 只有击败大魔王时才设置 hasWonif (enemy.name == "大魔王") {player.hasWon = true;}}
}// 武器商店
void weaponShop(Player& player) {system("cls");  // 进入商店清屏int choice;do {cout << "\n=== 武器商店 ==="<< "\n1. 小刀 (+2攻) - 1金"<< "\n2. 短剑 (+20攻) - 80金"<< "\n3. 大砍刀 (+40攻) - 140金"<< "\n4. 盾牌 (+30防) - 60金"<< "\n5. 铠甲 (+60防) - 100金"<< "\n6. 离开商店"<< "\n当前金钱: " << player.money<< "\n请选择:";if(!(cin >> choice)) {clearInput();continue;}switch(choice) {case 1:if(player.money >= 1) {player.attack += 2;player.money -= 1;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 2:if(player.money >= 80) {player.attack += 20;player.money -= 80;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 3:if(player.money >= 140) {player.attack += 40;player.money -= 140;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 4:if(player.money >= 60) {player.defense += 30;player.money -= 60;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;case 5:if(player.money >= 100) {player.defense += 60;player.money -= 100;cout << "购买成功!\n";} else {cout << "金钱不足!\n";}break;}player.showStatus();} while(choice != 6);system("cls");  // 离开商店清屏
}// 药店
void pharmacy(Player& player) {system("cls");  // 进入药店清屏int choice;do {cout << "\n=== 魔法药店 ==="<< "\n1. 小血瓶 (+200HP) - 10金"<< "\n2. 大血瓶 (+1000HP) - 50金"<< "\n3. 超级血瓶 (+2200HP) - 100金"<< "\n4. 离开商店"<< "\n当前生命值: " << player.health<< "\n当前金钱: " << player.money<< "\n请选择:";if(!(cin >> choice)) {clearInput();continue;}switch(choice) {case 1:if(player.money >= 10) {player.health += 200;player.money -= 10;cout << "恢复200生命值!\n";} else {cout << "金钱不足!\n";}break;case 2:if(player.money >= 50) {player.health += 1000;player.money -= 50;cout << "恢复1000生命值!\n";} else {cout << "金钱不足!\n";}break;case 3:if(player.money >= 100) {player.health += 2200;player.money -= 100;cout << "恢复2200生命值!\n";} else {cout << "金钱不足!\n";}break;}player.showStatus();} while(choice != 4);system("cls");  // 离开药店清屏
}// 显示主菜单
void showMainMenu() {cout << "\n=== 主菜单 ==="<< "\n1. 武器商店"<< "\n2. 魔法药店"<< "\n3. 挑战小怪"<< "\n4. 决战魔王"<< "\n5. 退出游戏"<< "\n6. 查看状态"<< "\n7. 查看推荐攻略" << "\n请输入选择:";
}// 查看推荐攻略
void showStrategy() {system("cls");  // 查看攻略前清屏cout << "\n=== 《勇者冒险》通关攻略 ===" << endl;cout << "\n【核心策略】" << endl;cout << "1. 无限刷小怪积累金币" << endl;cout << "2. 优先堆叠防御至1000+(免疫BOSS伤害)" << endl;cout << "3. 提升攻击力至500+,快速击败大魔王" << endl;cout << "\n【阶段操作指南】" << endl;cout << "1. 阶段1:无限刷小怪" << endl;cout << "   - 主菜单选择3(挑战小怪)" << endl;cout << "   - 每次战斗获得5金币" << endl;cout << "   - 目标:积累至少2600金币" << endl;cout << "\n2. 阶段2:购买防御装备" << endl;cout << "   - 优先购买铠甲(+60防御,100金币)" << endl;cout << "   - 购买14次铠甲,防御力提升至1040" << endl;cout << "   - 补1次盾牌(+30防御,60金币),防御力提升至1070" << endl;cout << "\n3. 阶段3:购买攻击装备" << endl;cout << "   - 购买大砍刀(+40攻击,140金币)" << endl;cout << "   - 购买9次大砍刀,攻击力提升至510" << endl;cout << "\n4. 阶段4:决战大魔王" << endl;cout << "   - 主菜单选择4(决战魔王)" << endl;cout << "   - 每回合攻击造成520伤害,7回合击败大魔王" << endl;cout << "\n【高效技巧】" << endl;cout << "1. 快速刷钱:每小时可刷约720金币" << endl;cout << "2. 操作优化:防御达标后跳过盾牌,直接买攻击装" << endl;cout << "3. 注意事项:无需购买药水,大魔王无金币奖励" << endl;cout << "\n【数值验证表】" << endl;cout << "| 项目          | 需求值 | 实际达成值 | 效果               |" << endl;cout << "|---------------|--------|------------|--------------------|" << endl;cout << "| 防御力        | ≥1000  | 1070       | 免疫大魔王所有伤害 |" << endl;cout << "| 攻击力        | ≥500   | 510        | 每回合造成520伤害  |" << endl;cout << "| 总金币消耗    | 2720   | 2720       | 防御+攻击装备      |" << endl;cout << "| 击败大魔王回合| 7      | 7          | 安全无风险         |" << endl;cout << "\n=== 祝您游戏愉快! ===\n" << endl;// 暂停功能cout << "输入任意键返回主菜单...";cin.ignore();cin.get();system("cls");  // 返回前清屏
}// 清除输入错误
void clearInput() {cin.clear();cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

八、优化后运行效果

  1. 主菜单
    image

  2. 武器商店
    image

  3. 魔法药店
    image

  4. 打小怪
    image

  5. 打Boss
    image

  6. 查看状态
    image

  7. 查看攻略
    image

  8. 退出游戏
    image

九、总结

  1. 难点
  • 模块化设计
模块 原版实现 重构后设计 优势
玩家状态 全局变量松散管理 封装为 Player 类 数据与行为绑定,避免状态泄露
敌人管理 临时创建guaiwu1、guaiwu2对象 封装为Enemy类 统一生成敌人,支持配置化
  • 数值平衡
    难点在于如何设置数值以求平衡,最终借助ai工具得到一套较合理的数值方案。
  • 反复测试
    需要将所有功能测试一遍,确保以实现的功能能正常运行,另外还要寻找有没有使小游戏出错的隐患。
    最终同几位组员试用,通过了测试。
  1. 心得
    学会了以用户作为出发点的逆向软件思维,锻炼独立思考的能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/888208.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多周期处理器debug记录

这篇随笔记录的是从普通的多周期处理器到加入握手信号和axi-lite协议sram的处理器。 在之前的多周期处理器里,由于结构比较简单,所以我给ifu和exu的握手信号加入的是时序逻辑,idu由于只做解码,所以握手信号放在了组合逻辑里,差不多就和透传差不多。但是加入sram握手信号以…

继承内存图--java进阶 day01

主方法进栈,有new进堆堆内存中先存自己类中有的变量又因为继承了父类,所以父类中的变量也要存入 即使被私有化,依旧可以继承,只是没有权限使用!创建对象时,会调用构造方法,所以走构造方法,实参传形参.....继续走到super,访问父类的构造方法,父类构造方法进栈,形参继…

离散化学习笔记

离散化学习笔记 OP:又是一如既往的周更。。。水死了 定义离散化:将数字映射为是第几小的数,其保证数据在Hash之后仍然保持原来的全/偏序关系,能够解决:通过元素相对大小即可解决的问题。 其实本质上就是哈希的一种特殊规则而已。(离散化简化了不止亿点)目标将一堆乱序且…

java知识面试day2

1.说出java和c++的区别java是一个纯粹的面向对象语言,所有的对象都继承于java. lang.Object,C++兼容C,不但支持面向对象也支持面向过程 java有着一次编译四处运行的跨平台特性。 java不具有指针,但具有垃圾回收。 java不支持多重继承,只能通过实现多个接口去达到相同目的2.…

继承中构造方法访问特点--java 进阶day01

1.子类不可以继承父类的构造方法构造方法的名称必须与类名一致,上图中类名是Zi,而构造方法名是Fu,肯定不行 2.子类在初始化之前,需要对父类初始化 子类在初始化的过程中,很有可能会调用到父类的数据,如果父类没有提前初始化,子类就无法调用这些数据3.通过在子类中访问父…

Mysql莫名其妙爆出拒绝访问问题的原因及解决方案

本文记录使用Mysql作为数据库时发生拒绝访问问题的解决方案Mysql出现拒绝连接问题 ⛄问题原因 : Mysql密码错误,本机上并不是只有一个Mysql服务,我们在开机时启动了并非以前使用的那个Mysql服务,所以造成了密码的错误🌟解决方案 :手动关闭当前正在启用的Mysql服务,尝试找…

Codes 开源 免费 研发项目管理平台 3.0.0 版本发布及创新的轻IPD实现

Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台,支持云端认证、本地部署、全部功能开放,并且对 30 人以下团队免费。它通过创新的方式简化研发协同工作,使敏捷开发更易于实施。采用轻量化的 IPD 模式实现,且融合了敏捷 。轻 IPD 主要解决多项目交付的研发过程管理,…

2025/2/15课堂记录

数字转换,皇宫看守,树上dp,树的直径目录数字转换 皇宫看守数字转换这是一道树的直径题。 首先,树的直径定义是:树上两个结点之间的最短(加权)路中最长的一条路径(和二分答案没关) 但由于贪心思想,这个路径一定起点终点是两片叶子结点如图,这棵树的直径就是5,即节点…

基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真

1.课题概述基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真。利用电压外环PI调节器得到有功 电流指令值结合由负载侧电流检测 到 的无功 电流指令值 ,经由 状态解耦PI调节的电流内环控制器输出直接得到的是输出电压的指令值,用此信号作为采用控制…

【库】Coravel Schedule任务调度

Coravel 通过使高级应用程序功能(如任务/作业调度、排队、缓存、邮件(以及更多!))易于访问且易于使用,帮助开发人员快速启动并运行 .NET 应用程序。具有简单、富有表现力和直接的语法。   下面是简单的用法,通过注入Scheduler和在中间件中定义调度的实现,来完成简单的…

【库】用Rin透视Web请求

Rin 可以捕获对 ASP.NET Core 应用程序的 HTTP 请求,并为捕获的数据提供查看器。它是调试 Web 应用程序(例如,网站、API 应用)的有用工具。先看如下代码:var builder = WebApplication.CreateBuilder(args); builder.Logging.AddRinLogger(); builder.Services.AddRin(); …