地狱闯关游戏2.0
2026-02-01 09:34:16
发布于:浙江
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
const int WIDTH = 15;
const int HEIGHT = 15;
// 枚举地形类型
enum Terrain {
GRASS = '.', // 草地
TREE = '#', // 树木
WATER = '~', // 水
WALL = '|', // 墙
TREASURE = '$' // 宝藏
};
// 怪物类型
enum MonsterType { GOBLIN, ORC, DRAGON, SLIME, ZOMBIE, MAX_TYPES };
// 玩家结构体
struct Player {
int x, y;
int health;
int maxHealth;
int attack;
int defense;
int level;
int exp;
int expToNextLevel;
int gold;
Player() : x(0), y(0), health(100), maxHealth(100), attack(10),
defense(5), level(1), exp(0), expToNextLevel(100), gold(0) {}
void levelUp() {
level++;
exp -= expToNextLevel;
expToNextLevel = static_cast<int>(expToNextLevel * 1.5);
maxHealth += 20;
health = maxHealth;
attack += 5;
defense += 2;
cout << "\n╔══════════════════════════╗" << endl;
cout << "║ 等级提升! ║" << endl;
cout << "║ 现在是 " << level << " 级 ║" << endl;
cout << "║ 生命值 +20 ║" << endl;
cout << "║ 攻击力 +5 ║" << endl;
cout << "║ 防御力 +2 ║" << endl;
cout << "╚══════════════════════════╝" << endl;
cout << "按任意键继续...";
_getch();
}
void gainExp(int amount) {
exp += amount;
cout << "获得 " << amount << " 点经验值" << endl;
if (exp >= expToNextLevel) {
levelUp();
}
}
void heal(int amount) {
health = min(health + amount, maxHealth);
cout << "恢复 " << amount << " 点生命值" << endl;
}
void takeDamage(int damage) {
int actualDamage = max(1, damage - defense);
health -= actualDamage;
cout << "受到 " << actualDamage << " 点伤害" << endl;
}
bool isAlive() const {
return health > 0;
}
};
// 怪物结构体
struct Monster {
int x, y;
int health;
int maxHealth;
int attack;
int defense;
int expReward;
int goldReward;
string name;
char symbol;
MonsterType type;
Monster(int x, int y, MonsterType type) {
this->x = x;
this->y = y;
switch(type) {
case GOBLIN:
health = maxHealth = 25;
attack = 6;
defense = 2;
expReward = 25;
goldReward = rand() % 20 + 5;
name = "哥布林";
symbol = 'g';
break;
case ORC:
health = maxHealth = 40;
attack = 9;
defense = 4;
expReward = 40;
goldReward = rand() % 30 + 10;
name = "兽人";
symbol = 'o';
break;
case DRAGON:
health = maxHealth = 100;
attack = 15;
defense = 8;
expReward = 100;
goldReward = rand() % 100 + 50;
name = "龙";
symbol = 'D';
break;
case SLIME:
health = maxHealth = 15;
attack = 4;
defense = 1;
expReward = 15;
goldReward = rand() % 10 + 2;
name = "史莱姆";
symbol = 's';
break;
case ZOMBIE:
health = maxHealth = 30;
attack = 7;
defense = 3;
expReward = 30;
goldReward = rand() % 15 + 5;
name = "僵尸";
symbol = 'z';
break;
}
this->type = type;
}
bool isAlive() const {
return health > 0;
}
};
// 物品结构体
struct Item {
string name;
int healthBonus;
int attackBonus;
int defenseBonus;
int price;
char symbol;
bool consumable;
Item(string n, int h, int a, int d, int p, char s, bool c)
: name(n), healthBonus(h), attackBonus(a), defenseBonus(d),
price(p), symbol(s), consumable(c) {}
};
// 游戏类
class Game {
private:
vector<vector<char>> displayMap;
vector<vector<Terrain>> terrainMap;
vector<Monster> monsters;
vector<Item> items;
Player player;
int turnCount;
public:
Game() : turnCount(0) {
initializeMaps();
initializeItems();
generateMonsters(5);
generateItems(8);
}
void initializeMaps() {
// 初始化显示地图
displayMap.resize(HEIGHT, vector<char>(WIDTH, '.'));
// 初始化地形地图
terrainMap.resize(HEIGHT, vector<Terrain>(WIDTH, GRASS));
// 随机生成地形
srand(time(0));
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
int r = rand() % 100;
if (r < 10) {
terrainMap[i][j] = TREE;
displayMap[i][j] = '#';
} else if (r < 20) {
terrainMap[i][j] = WATER;
displayMap[i][j] = '~';
} else if (r < 25) {
terrainMap[i][j] = WALL;
displayMap[i][j] = '|';
}
}
}
// 确保起点是草地
terrainMap[player.y][player.x] = GRASS;
}
void initializeItems() {
// 创建物品
items.push_back(Item("小血瓶", 20, 0, 0, 10, '+', true));
items.push_back(Item("大血瓶", 50, 0, 0, 25, '+', true));
items.push_back(Item("攻击药剂", 0, 5, 0, 30, '!', true));
items.push_back(Item("防御药剂", 0, 0, 3, 30, '!', true));
items.push_back(Item("铁剑", 0, 8, 0, 50, '/', false));
items.push_back(Item("钢盾", 0, 0, 5, 50, 'o', false));
items.push_back(Item("魔法杖", 0, 12, 0, 80, '*', false));
items.push_back(Item("钻石", 0, 0, 0, 100, '$', true));
}
void generateMonsters(int count) {
for (int i = 0; i < count; i++) {
int x, y;
do {
x = rand() % WIDTH;
y = rand() % HEIGHT;
} while ((x == player.x && y == player.y) || terrainMap[y][x] != GRASS);
MonsterType type = static_cast<MonsterType>(rand() % MAX_TYPES);
monsters.push_back(Monster(x, y, type));
displayMap[y][x] = monsters.back().symbol;
}
}
void generateItems(int count) {
for (int i = 0; i < count; i++) {
int x, y;
do {
x = rand() % WIDTH;
y = rand() % HEIGHT;
} while ((x == player.x && y == player.y) || terrainMap[y][x] != GRASS);
terrainMap[y][x] = TREASURE;
displayMap[y][x] = '$';
}
}
void display() {
system("cls");
// 显示标题
cout << "╔══════════════════════════════════════════╗" << endl;
cout << "║ 地下城冒险 - 加强版 ║" << endl;
cout << "╚══════════════════════════════════════════╝" << endl;
// 显示地图
cout << "地图:" << endl;
cout << "╔";
for (int j = 0; j < WIDTH; j++) cout << "══";
cout << "╗" << endl;
for (int i = 0; i < HEIGHT; i++) {
cout << "║";
for (int j = 0; j < WIDTH; j++) {
if (i == player.y && j == player.x) {
cout << "P ";
} else {
cout << displayMap[i][j] << " ";
}
}
cout << "║" << endl;
}
cout << "╚";
for (int j = 0; j < WIDTH; j++) cout << "══";
cout << "╝" << endl;
// 显示玩家状态
displayHUD();
// 显示图例
cout << "\n图例: P=玩家";
for (const auto& monster : monsters) {
if (monster.isAlive()) {
cout << ", " << monster.symbol << "=" << monster.name;
}
}
cout << ", #=树木, ~=水, |=墙, $=宝藏" << endl;
}
void displayHUD() {
cout << "\n══════════════════════════════════════════" << endl;
cout << " 玩家状态:" << endl;
cout << " 生命值: " << player.health << "/" << player.maxHealth;
cout << " | 等级: " << player.level;
cout << " | 经验: " << player.exp << "/" << player.expToNextLevel << endl;
cout << " 攻击力: " << player.attack;
cout << " | 防御力: " << player.defense;
cout << " | 金币: " << player.gold << endl;
cout << "══════════════════════════════════════════" << endl;
}
bool canMoveTo(int x, int y) {
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
return false;
}
// 检查地形是否可通行
Terrain terrain = terrainMap[y][x];
return terrain == GRASS || terrain == TREASURE;
}
void movePlayer(int dx, int dy) {
int newX = player.x + dx;
int newY = player.y + dy;
if (canMoveTo(newX, newY)) {
player.x = newX;
player.y = newY;
turnCount++;
// 检查是否遇到怪物
checkMonsterEncounter();
// 检查是否拾取物品
checkItemPickup();
// 怪物随机移动
moveMonsters();
} else {
cout << "无法移动到此位置!" << endl;
cout << "按任意键继续...";
_getch();
}
}
void checkMonsterEncounter() {
for (auto& monster : monsters) {
if (monster.isAlive() && monster.x == player.x && monster.y == player.y) {
startCombat(monster);
break;
}
}
}
void checkItemPickup() {
if (terrainMap[player.y][player.x] == TREASURE) {
treasureFound();
}
}
void treasureFound() {
system("cls");
cout << "╔══════════════════════════════════╗" << endl;
cout << "║ 发现宝藏! ║" << endl;
cout << "╚══════════════════════════════════╝" << endl;
// 随机获得物品
int goldFound = rand() % 50 + 20;
int itemIndex = rand() % items.size();
Item foundItem = items[itemIndex];
cout << "你找到了:" << endl;
cout << "金币: " << goldFound << endl;
cout << "物品: " << foundItem.name << endl;
player.gold += goldFound;
// 询问是否使用物品
if (foundItem.consumable) {
cout << "\n要使用 " << foundItem.name << " 吗?(y/n): ";
char choice;
cin >> choice;
if (choice == 'y' || choice == 'Y') {
useItem(foundItem);
} else {
cout << "物品已保存到背包。" << endl;
}
} else {
cout << "\n装备 " << foundItem.name << " 吗?(y/n): ";
char choice;
cin >> choice;
if (choice == 'y' || choice == 'Y') {
equipItem(foundItem);
} else {
cout << "物品已保存到背包。" << endl;
}
}
// 移除宝藏
terrainMap[player.y][player.x] = GRASS;
displayMap[player.y][player.x] = '.';
cout << "按任意键继续...";
_getch();
}
void useItem(const Item& item) {
player.heal(item.healthBonus);
player.attack += item.attackBonus;
player.defense += item.defenseBonus;
cout << "使用了 " << item.name << "!" << endl;
}
void equipItem(const Item& item) {
player.attack += item.attackBonus;
player.defense += item.defenseBonus;
cout << "装备了 " << item.name << "!" << endl;
cout << "攻击力: +" << item.attackBonus << endl;
cout << "防御力: +" << item.defenseBonus << endl;
}
void startCombat(Monster& monster) {
system("cls");
cout << "╔══════════════════════════════════════╗" << endl;
cout << "║ 遭遇战斗! ║" << endl;
cout << "║ vs " << monster.name << " ║" << endl;
cout << "╚══════════════════════════════════════╝" << endl;
int round = 1;
while (monster.isAlive() && player.isAlive()) {
cout << "\n第 " << round << " 回合:" << endl;
cout << "══════════════════════════════════" << endl;
cout << "你的生命值: " << player.health << "/" << player.maxHealth << endl;
cout << monster.name << "的生命值: " << monster.health << "/" << monster.maxHealth << endl;
cout << "══════════════════════════════════" << endl;
// 玩家行动
cout << "\n选择行动:" << endl;
cout << "1. 攻击" << endl;
cout << "2. 防御(减少50%伤害)" << endl;
cout << "3. 逃跑(50%成功率)" << endl;
cout << "选择: ";
int choice;
cin >> choice;
bool defending = false;
switch (choice) {
case 1: { // 攻击
int damage = max(1, player.attack - monster.defense / 2);
monster.health -= damage;
cout << "你对" << monster.name << "造成了 " << damage << " 点伤害!" << endl;
break;
}
case 2: { // 防御
defending = true;
cout << "你进入防御姿态!" << endl;
break;
}
case 3: { // 逃跑
if (rand() % 100 < 50) {
cout << "成功逃跑!" << endl;
cout << "按任意键继续...";
_getch();
return;
} else {
cout << "逃跑失败!" << endl;
}
break;
}
default:
cout << "无效选择,自动攻击!" << endl;
monster.health -= player.attack;
break;
}
// 怪物行动
if (monster.isAlive()) {
int monsterDamage = max(1, monster.attack - player.defense);
if (defending) {
monsterDamage = max(1, monsterDamage / 2);
cout << monster.name << "的攻击被格挡!" << endl;
}
player.takeDamage(monsterDamage);
if (!player.isAlive()) {
cout << "\n你被" << monster.name << "击败了!" << endl;
break;
}
}
round++;
if (player.isAlive() && monster.isAlive()) {
cout << "\n按任意键继续下一回合...";
_getch();
system("cls");
}
}
if (player.isAlive()) {
cout << "\n══════════════════════════════════" << endl;
cout << "胜利!你击败了" << monster.name << "!" << endl;
player.gainExp(monster.expReward);
player.gold += monster.goldReward;
cout << "获得 " << monster.goldReward << " 金币" << endl;
// 移除死亡的怪物
displayMap[monster.y][monster.x] = '.';
}
cout << "按任意键继续...";
_getch();
}
void moveMonsters() {
for (auto& monster : monsters) {
if (monster.isAlive()) {
// 10%概率移动
if (rand() % 100 < 10) {
int dx = (rand() % 3) - 1; // -1, 0, 1
int dy = (rand() % 3) - 1; // -1, 0, 1
int newX = monster.x + dx;
int newY = monster.y + dy;
if (canMoveTo(newX, newY)) {
displayMap[monster.y][monster.x] = '.';
monster.x = newX;
monster.y = newY;
displayMap[monster.y][monster.x] = monster.symbol;
}
}
}
}
}
void showInventory() {
system("cls");
cout << "╔══════════════════════════════════════╗" << endl;
cout << "║ 背包 ║" << endl;
cout << "╚══════════════════════════════════════╝" << endl;
cout << "金币: " << player.gold << endl;
cout << "══════════════════════════════════════" << endl;
cout << "商店物品(按数字购买):" << endl;
for (size_t i = 0; i < items.size(); i++) {
cout << i+1 << ". " << items[i].name;
cout << " (";
if (items[i].healthBonus > 0) cout << "生命+" << items[i].healthBonus << " ";
if (items[i].attackBonus > 0) cout << "攻击+" << items[i].attackBonus << " ";
if (items[i].defenseBonus > 0) cout << "防御+" << items[i].defenseBonus << " ";
cout << ") - " << items[i].price << "金币" << endl;
}
cout << "\n0. 返回游戏" << endl;
cout << "选择: ";
int choice;
cin >> choice;
if (choice > 0 && choice <= items.size()) {
Item& item = items[choice - 1];
if (player.gold >= item.price) {
player.gold -= item.price;
cout << "购买了 " << item.name << "!" << endl;
if (item.consumable) {
cout << "要立即使用吗?(y/n): ";
char useChoice;
cin >> useChoice;
if (useChoice == 'y' || useChoice == 'Y') {
useItem(item);
}
} else {
cout << "要立即装备吗?(y/n): ";
char equipChoice;
cin >> equipChoice;
if (equipChoice == 'y' || equipChoice == 'Y') {
equipItem(item);
}
}
} else {
cout << "金币不足!" << endl;
}
cout << "按任意键继续...";
_getch();
}
}
void saveGame() {
ofstream file("savegame.txt");
if (file.is_open()) {
file << player.x << " " << player.y << " "
<< player.health << " " << player.maxHealth << " "
<< player.attack << " " << player.defense << " "
<< player.level << " " << player.exp << " "
<< player.expToNextLevel << " " << player.gold << " "
<< turnCount;
file.close();
cout << "游戏已保存!" << endl;
} else {
cout << "保存失败!" << endl;
}
cout << "按任意键继续...";
_getch();
}
void loadGame() {
ifstream file("savegame.txt");
if (file.is_open()) {
file >> player.x >> player.y
>> player.health >> player.maxHealth
>> player.attack >> player.defense
>> player.level >> player.exp
>> player.expToNextLevel >> player.gold
>> turnCount;
file.close();
cout << "游戏已加载!" << endl;
} else {
cout << "没有找到保存文件!" << endl;
}
cout << "按任意键继续...";
_getch();
}
void showHelp() {
system("cls");
cout << "╔══════════════════════════════════════╗" << endl;
cout << "║ 游戏帮助 ║" << endl;
cout << "╚══════════════════════════════════════╝" << endl;
cout << "移动: W(上), A(左), S(下), D(右)" << endl;
cout << "商店: B (打开背包/商店)" << endl;
cout << "保存: V (保存游戏)" << endl;
cout << "加载: L (加载游戏)" << endl;
cout << "退出: Q (退出游戏)" << endl;
cout << "══════════════════════════════════════" << endl;
cout << "战斗说明:" << endl;
cout << "- 攻击: 对敌人造成伤害" << endl;
cout << "- 防御: 减少受到的伤害" << endl;
cout << "- 逃跑: 有50%几率逃离战斗" << endl;
cout << "══════════════════════════════════════" << endl;
cout << "地图符号说明:" << endl;
cout << "P = 玩家" << endl;
cout << "g = 哥布林, o = 兽人, D = 龙" << endl;
cout << "s = 史莱姆, z = 僵尸" << endl;
cout << "# = 树木 (无法通过)" << endl;
cout << "~ = 水 (无法通过)" << endl;
cout << "| = 墙 (无法通过)" << endl;
cout << "$ = 宝藏 (可以获得物品)" << endl;
cout << "══════════════════════════════════════" << endl;
cout << "按任意键返回游戏...";
_getch();
}
void run() {
char input;
bool running = true;
while (running && player.isAlive()) {
display();
cout << "\n移动(WASD) | 商店(B) | 保存(V) | 加载(L) | 帮助(H) | 退出(Q): ";
cin >> input;
switch (tolower(input)) {
case 'w':
movePlayer(0, -1);
break;
case 's':
movePlayer(0, 1);
break;
case 'a':
movePlayer(-1, 0);
break;
case 'd':
movePlayer(1, 0);
break;
case 'b':
showInventory();
break;
case 'v':
saveGame();
break;
case 'l':
loadGame();
break;
case 'h':
showHelp();
break;
case 'q':
running = false;
cout << "确定退出游戏吗?(y/n): ";
cin >> input;
if (tolower(input) != 'y') running = true;
break;
default:
cout << "无效输入!" << endl;
cout << "按任意键继续...";
_getch();
break;
}
// 随机生成新怪物
if (turnCount % 10 == 0 && monsters.size() < 8) {
MonsterType type = static_cast<MonsterType>(rand() % MAX_TYPES);
int x, y;
do {
x = rand() % WIDTH;
y = rand() % HEIGHT;
} while ((x == player.x && y == player.y) ||
terrainMap[y][x] != GRASS ||
displayMap[y][x] != '.');
monsters.push_back(Monster(x, y, type));
displayMap[y][x] = monsters.back().symbol;
}
}
if (!player.isAlive()) {
system("cls");
cout << "╔══════════════════════════════════════╗" << endl;
cout << "║ 游戏结束! ║" << endl;
cout << "║ 你被击败了... ║" << endl;
cout << "╚══════════════════════════════════════╝" << endl;
cout << "最终等级: " << player.level << endl;
cout << "获得金币: " << player.gold << endl;
cout << "游戏回合: " << turnCount << endl;
}
cout << "\n按任意键退出...";
_getch();
}
};
int main() {
srand(static_cast<unsigned>(time(0)));
Game game;
game.run();
return 0;
}
全部评论 1
我把它复制进devc++怎么老会报错
2025-06-01 来自 云南
0我也是
2025-06-01 来自 上海
0哪里报错?
2025-06-02 来自 浙江
1
就像这样2025-06-02 来自 云南
2
























有帮助,赞一个