#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <random>
#include <algorithm>
#include <memory>
#include <cstdlib>
#include <ctime>
#include <limits>
using namespace std;
// 前向声明
class Item;
class Character;
class Player;
class Enemy;
class NPC;
class Location;
class Game;
// 物品基类
class Item {
protected:
string name;
string description;
bool stackable;
int value;
public:
Item(const string& n, const string& d, bool s, int v)
: name(n), description(d), stackable(s), value(v) {}
virtual ~Item() = default;
const string& getName() const { return name; }
const string& getDescription() const { return description; }
bool isStackable() const { return stackable; }
int getValue() const { return value; }
virtual void use(Player* player) = 0;
virtual unique_ptr<Item> clone() const = 0;
};
// 武器类
class Weapon : public Item {
private:
int damage;
int durability;
int maxDurability;
public:
Weapon(const string& n, const string& d, int v, int dam, int dur)
: Item(n, d, false, v), damage(dam), durability(dur), maxDurability(dur) {}
int getDamage() const { return damage; }
int getDurability() const { return durability; }
int getMaxDurability() const { return maxDurability; }
void reduceDurability() {
if (durability > 0) durability--;
}
void repair() { durability = maxDurability; }
void use(Player* player) override;
unique_ptr<Item> clone() const override {
return make_unique<Weapon>(*this);
}
};
// 防具类
class Armor : public Item {
private:
int defense;
int durability;
int maxDurability;
public:
Armor(const string& n, const string& d, int v, int def, int dur)
: Item(n, d, false, v), defense(def), durability(dur), maxDurability(dur) {}
int getDefense() const { return defense; }
int getDurability() const { return durability; }
int getMaxDurability() const { return maxDurability; }
void reduceDurability() {
if (durability > 0) durability--;
}
void repair() { durability = maxDurability; }
void use(Player* player) override;
unique_ptr<Item> clone() const override {
return make_unique<Armor>(*this);
}
};
// 消耗品类
class Consumable : public Item {
private:
int effectValue;
enum EffectType { HEAL, BUFF_ATTACK, BUFF_DEFENSE, POISON, STRENGTHEN } effectType;
public:
Consumable(const string& n, const string& d, bool s, int v, int val, EffectType type)
: Item(n, d, s, v), effectValue(val), effectType(type) {}
void use(Player* player) override;
unique_ptr<Item> clone() const override {
return make_unique<Consumable>(*this);
}
};
// 关键物品类
class KeyItem : public Item {
private:
string requiredFor;
public:
KeyItem(const string& n, const string& d, const string& req)
: Item(n, d, false, 0), requiredFor(req) {}
const string& getRequiredFor() const { return requiredFor; }
void use(Player* player) override;
unique_ptr<Item> clone() const override {
return make_unique<KeyItem>(*this);
}
};
// 角色基类
class Character {
protected:
string name;
int health;
int maxHealth;
int attack;
int defense;
bool isAlive;
public:
Character(const string& n, int h, int a, int d)
: name(n), health(h), maxHealth(h), attack(a), defense(d), isAlive(true) {}
virtual ~Character() = default;
const string& getName() const { return name; }
int getHealth() const { return health; }
int getMaxHealth() const { return maxHealth; }
int getAttack() const { return attack; }
int getDefense() const { return defense; }
bool isAlive() const { return isAlive; }
void setHealth(int h) {
health = max(0, min(h, maxHealth));
if (health == 0) isAlive = false;
}
void setAttack(int a) { attack = max(1, a); }
void setDefense(int d) { defense = max(0, d); }
virtual int takeDamage(int damage);
virtual void heal(int amount);
virtual void displayStats() const;
};
// 玩家类
class Player : public Character {
private:
int level;
int experience;
int nextLevelExp;
int gold;
vector<unique_ptr<Item>> inventory;
Weapon* equippedWeapon;
Armor* equippedArmor;
map<string, int> questProgress;
vector<string> completedQuests;
string morality; // "good", "neutral", "evil"
public:
Player(const string& n)
: Character(n, 100, 10, 5), level(1), experience(0), nextLevelExp(100), gold(50),
equippedWeapon(nullptr), equippedArmor(nullptr), morality("neutral") {}
int getLevel() const { return level; }
int getExperience() const { return experience; }
int getNextLevelExp() const { return nextLevelExp; }
int getGold() const { return gold; }
const vector<unique_ptr<Item>>& getInventory() const { return inventory; }
Weapon* getEquippedWeapon() const { return equippedWeapon; }
Armor* getEquippedArmor() const { return equippedArmor; }
const string& getMorality() const { return morality; }
void addGold(int amount) { gold += amount; }
bool spendGold(int amount);
void addExperience(int amount);
void levelUp();
void addItem(unique_ptr<Item> item);
bool hasItem(const string& name) const;
unique_ptr<Item> removeItem(const string& name);
void useItem(const string& name);
void displayInventory() const;
void equipWeapon(Weapon* weapon);
void equipArmor(Armor* armor);
int getTotalAttack() const;
int getTotalDefense() const;
void setQuestProgress(const string& quest, int progress);
int getQuestProgress(const string& quest) const;
void completeQuest(const string& quest);
bool hasCompletedQuest(const string& quest) const;
void changeMorality(const string& action);
void displayStats() const override;
};
// 敌人类
class Enemy : public Character {
private:
int experienceReward;
int goldReward;
vector<unique_ptr<Item>> possibleLoot;
string behavior; // "aggressive", "cautious", "fleeing"
bool isBoss;
public:
Enemy(const string& n, int h, int a, int d, int exp, int gold,
const vector<unique_ptr<Item>>& loot, const string& b, bool boss = false)
: Character(n, h, a, d), experienceReward(exp), goldReward(gold), behavior(b), isBoss(boss) {
for (const auto& item : loot) {
possibleLoot.push_back(item->clone());
}
}
int getExperienceReward() const { return experienceReward; }
int getGoldReward() const { return goldReward; }
const string& getBehavior() const { return behavior; }
bool getIsBoss() const { return isBoss; }
vector<unique_ptr<Item>> generateLoot();
void displayStats() const override;
};
// NPC类
class NPC : public Character {
private:
string dialogue;
vector<string> questGivers; // 该NPC能给予的任务
vector<string> shopItems; // 该NPC出售的物品
bool isFriendly;
string requirement; // 与该NPC互动的要求(如特定物品或任务进度)
public:
NPC(const string& n, const string& dlg, const vector<string>& quests,
const vector<string>& items, bool friendly, const string& req = "")
: Character(n, 100, 0, 0), dialogue(dlg), questGivers(quests),
shopItems(items), isFriendly(friendly), requirement(req) {}
const string& getDialogue() const { return dialogue; }
const vector<string>& getQuestGivers() const { return questGivers; }
const vector<string>& getShopItems() const { return shopItems; }
bool getIsFriendly() const { return isFriendly; }
const string& getRequirement() const { return requirement; }
void talkTo(Player* player);
void showShop(Player* player, Game* game);
};
// 位置类
class Location {
private:
string name;
string description;
map<string, string> connections; // 方向到地点名称的映射
vector<unique_ptr<Enemy>> enemies;
vector<unique_ptr<NPC>> npcs;
vector<unique_ptr<Item>> items;
string specialAction; // 该地点的特殊行动
bool visited;
string requirement; // 进入该地点的要求
public:
Location(const string& n, const string& d, const string& specAct = "", const string& req = "")
: name(n), description(d), specialAction(specAct), visited(false), requirement(req) {}
const string& getName() const { return name; }
const string& getDescription() const { return description; }
const map<string, string>& getConnections() const { return connections; }
const vector<unique_ptr<Enemy>>& getEnemies() const { return enemies; }
const vector<unique_ptr<NPC>>& getNPCs() const { return npcs; }
const vector<unique_ptr<Item>>& getItems() const { return items; }
const string& getSpecialAction() const { return specialAction; }
bool isVisited() const { return visited; }
const string& getRequirement() const { return requirement; }
void addConnection(const string& direction, const string& location) {
connections[direction] = location;
}
void addEnemy(unique_ptr<Enemy> enemy) {
enemies.push_back(move(enemy));
}
void addNPC(unique_ptr<NPC> npc) {
npcs.push_back(move(npc));
}
void addItem(unique_ptr<Item> item) {
items.push_back(move(item));
}
void removeEnemy(const string& name) {
auto it = find_if(enemies.begin(), enemies.end(),
[&](const unique_ptr<Enemy>& e) { return e->getName() == name; });
if (it != enemies.end()) {
enemies.erase(it);
}
}
void removeItem(const string& name) {
auto it = find_if(items.begin(), items.end(),
[&](const unique_ptr<Item>& i) { return i->getName() == name; });
if (it != items.end()) {
items.erase(it);
}
}
void setVisited(bool v) { visited = v; }
void display() const;
};
// 任务类
class Quest {
private:
string name;
string description;
string objective;
int requiredProgress;
int rewardExperience;
int rewardGold;
vector<unique_ptr<Item>> rewardItems;
bool completed;
public:
Quest(const string& n, const string& d, const string& obj, int req,
int exp, int gold, const vector<unique_ptr<Item>>& items)
: name(n), description(d), objective(obj), requiredProgress(req),
rewardExperience(exp), rewardGold(gold), completed(false) {
for (const auto& item : items) {
rewardItems.push_back(item->clone());
}
}
const string& getName() const { return name; }
const string& getDescription() const { return description; }
const string& getObjective() const { return objective; }
int getRequiredProgress() const { return requiredProgress; }
int getRewardExperience() const { return rewardExperience; }
int getRewardGold() const { return rewardGold; }
const vector<unique_ptr<Item>>& getRewardItems() const { return rewardItems; }
bool isCompleted() const { return completed; }
void complete() { completed = true; }
void display() const;
};
// 游戏类
class Game {
private:
Player player;
map<string, unique_ptr<Location>> locations;
map<string, unique_ptr<Quest>> quests;
string currentLocation;
bool gameOver;
string gameEnding;
// 随机数生成器
mt19937 rng;
public:
Game(const string& playerName) : player(playerName), gameOver(false), gameEnding("") {
// 初始化随机数生成器
rng.seed(time(nullptr));
// 初始化游戏世界
initializeWorld();
currentLocation = "village_square";
}
void initializeWorld();
void run();
void displayStatus() const;
void processCommand(const string& command);
void move(const string& direction);
void look() const;
void inventory() const;
void stats() const;
void talk(const string& npcName);
void take(const string& itemName);
void drop(const string& itemName);
void use(const string& itemName);
void equip(const string& itemName);
void attack(const string& enemyName);
bool combat(Player* player, Enemy* enemy);
void checkQuests();
void shop();
void specialAction();
void endGame(const string& ending);
void displayEnding() const;
// 物品创建辅助函数
unique_ptr<Weapon> createWeapon(const string& name);
unique_ptr<Armor> createArmor(const string& name);
unique_ptr<Consumable> createConsumable(const string& name);
unique_ptr<KeyItem> createKeyItem(const string& name);
};
// 物品方法实现
void Weapon::use(Player* player) {
player->equipWeapon(this);
cout << player->getName() << "装备了" << name << endl;
}
void Armor::use(Player* player) {
player->equipArmor(this);
cout << player->getName() << "装备了" << name << endl;
}
void Consumable::use(Player* player) {
switch (effectType) {
case HEAL:
player->heal(effectValue);
cout << player->getName() << "使用了" << name << ",恢复了" << effectValue << "点生命值!" << endl;
break;
case BUFF_ATTACK:
player->setAttack(player->getAttack() + effectValue);
cout << player->getName() << "使用了" << name << ",攻击力提升了" << effectValue << "点!" << endl;
break;
case BUFF_DEFENSE:
player->setDefense(player->getDefense() + effectValue);
cout << player->getName() << "使用了" << name << ",防御力提升了" << effectValue << "点!" << endl;
break;
case POISON:
player->takeDamage(effectValue);
cout << player->getName() << "不慎使用了" << name << ",受到了" << effectValue << "点毒素伤害!" << endl;
break;
case STRENGTHEN:
player->setHealth(player->getHealth() + effectValue);
player->setHealth(player->getMaxHealth() + effectValue);
cout << player->getName() << "使用了" << name << ",永久提升了" << effectValue << "点最大生命值!" << endl;
break;
}
}
void KeyItem::use(Player* player) {
cout << name << "不能这样使用。它可能在特定场合有用。" << endl;
}
// 角色方法实现
int Character::takeDamage(int damage) {
int actualDamage = max(1, damage - defense);
setHealth(health - actualDamage);
return actualDamage;
}
void Character::heal(int amount) {
setHealth(health + amount);
}
void Character::displayStats() const {
cout << name << "的状态:" << endl;
cout << "生命值: " << health << "/" << maxHealth << endl;
cout << "攻击力: " << attack << endl;
cout << "防御力: " << defense << endl;
}
// 玩家方法实现
bool Player::spendGold(int amount) {
if (gold >= amount) {
gold -= amount;
return true;
}
return false;
}
void Player::addExperience(int amount) {
experience += amount;
cout << "获得了" << amount << "点经验值!" << endl;
while (experience >= nextLevelExp) {
levelUp();
}
}
void Player::levelUp() {
level++;
experience -= nextLevelExp;
nextLevelExp = static_cast<int>(nextLevelExp * 1.5);
maxHealth += 20;
health = maxHealth;
attack += 3;
defense += 2;
cout << "恭喜!你升级到了" << level << "级!" << endl;
cout << "属性提升:生命值+" << 20 << ", 攻击力+" << 3 << ", 防御力+" << 2 << endl;
}
void Player::addItem(unique_ptr<Item> item) {
if (item->isStackable()) {
// 检查是否已有相同物品
for (const auto& i : inventory) {
if (i->getName() == item->getName()) {
// 这里简化处理,实际应增加数量
cout << "你现在有多个" << item->getName() << endl;
return;
}
}
}
inventory.push_back(move(item));
cout << "获得了" << inventory.back()->getName() << endl;
}
bool Player::hasItem(const string& name) const {
for (const auto& item : inventory) {
if (item->getName() == name) {
return true;
}
}
return false;
}
unique_ptr<Item> Player::removeItem(const string& name) {
for (auto it = inventory.begin(); it != inventory.end(); ++it) {
if ((*it)->getName() == name) {
unique_ptr<Item> item = move(*it);
inventory.erase(it);
return item;
}
}
return nullptr;
}
void Player::useItem(const string& name) {
unique_ptr<Item> item = removeItem(name);
if (item) {
item->use(this);
// 消耗品使用后消失,装备则保留
if (dynamic_cast<Consumable*>(item.get()) == nullptr) {
addItem(move(item));
}
} else {
cout << "你没有这个物品:" << name << endl;
}
}
void Player::displayInventory() const {
if (inventory.empty()) {
cout << "你的背包是空的。" << endl;
return;
}
cout << "背包 (" << inventory.size() << " 件物品):" << endl;
for (const auto& item : inventory) {
cout << "- " << item->getName() << ": " << item->getDescription() << endl;
}
cout << "金币: " << gold << endl;
}
void Player::equipWeapon(Weapon* weapon) {
if (weapon) {
equippedWeapon = weapon;
}
}
void Player::equipArmor(Armor* armor) {
if (armor) {
equippedArmor = armor;
}
}
int Player::getTotalAttack() const {
int total = attack;
if (equippedWeapon) {
total += equippedWeapon->getDamage();
}
return total;
}
int Player::getTotalDefense() const {
int total = defense;
if (equippedArmor) {
total += equippedArmor->getDefense();
}
return total;
}
void Player::setQuestProgress(const string& quest, int progress) {
questProgress[quest] = progress;
}
int Player::getQuestProgress(const string& quest) const {
auto it = questProgress.find(quest);
if (it != questProgress.end()) {
return it->second;
}
return 0;
}
void Player::completeQuest(const string& quest) {
completedQuests.push_back(quest);
}
bool Player::hasCompletedQuest(const string& quest) const {
return find(completedQuests.begin(), completedQuests.end(), quest) != completedQuests.end();
}
void Player::changeMorality(const string& action) {
if (action == "good") {
if (morality == "evil") morality = "neutral";
else if (morality == "neutral") morality = "good";
} else if (action == "evil") {
if (morality == "good") morality = "neutral";
else if (morality == "neutral") morality = "evil";
}
}
void Player::displayStats() const {
cout << "=== " << name << " 的状态 ===" << endl;
cout << "等级: " << level << endl;
cout << "经验值: " << experience << "/" << nextLevelExp << endl;
cout << "生命值: " << health << "/" << maxHealth << endl;
cout << "基础攻击力: " << attack;
if (equippedWeapon) {
cout << " (+ " << equippedWeapon->getDamage() << " 来自 " << equippedWeapon->getName() << ")";
}
cout << " (总计: " << getTotalAttack() << ")" << endl;
cout << "基础防御力: " << defense;
if (equippedArmor) {
cout << " (+ " << equippedArmor->getDefense() << " 来自 " << equippedArmor->getName() << ")";
}
cout << " (总计: " << getTotalDefense() << ")" << endl;
cout << "金币: " << gold << endl;
cout << "道德倾向: " << (morality == "good" ? "善良" : morality == "evil" ? "邪恶" : "中立") << endl;
cout << "=========================" << endl;
}
// 敌人方法实现
vector<unique_ptr<Item>> Enemy::generateLoot() {
vector<unique_ptr<Item>> loot;
uniform_real_distribution<double> dist(0.0, 1.0);
for (const auto& item : possibleLoot) {
// 50% 几率获得每件可能的战利品
if (dist(rng) < 0.5) {
loot.push_back(item->clone());
}
}
return loot;
}
void Enemy::displayStats() const {
cout << "=== " << name << " 的状态 ===" << endl;
cout << "生命值: " << health << "/" << maxHealth << endl;
cout << "攻击力: " << attack << endl;
cout << "防御力: " << defense << endl;
if (isBoss) cout << "这是一个强大的首领敌人!" << endl;
cout << "=========================" << endl;
}
// NPC方法实现
void NPC::talkTo(Player* player) {
// 检查互动要求
if (!requirement.empty() && !player->hasItem(requirement) &&
!player->hasCompletedQuest(requirement)) {
cout << name << "说:\"在满足我的要求之前,我不会理你。\"" << endl;
return;
}
cout << name << "说:\"" << dialogue << "\"" << endl;
// 如果NPC有任务可以给予
for (const auto& questName : questGivers) {
// 这里简化处理,实际应检查玩家是否已接受/完成该任务
cout << name << "说:\"我有一个任务要交给你:" << questName << "。你愿意接受吗?(是/否)\"" << endl;
string response;
cin >> response;
if (response == "是" || response == "y" || response == "yes") {
cout << name << "说:\"太好了!我相信你能完成这个任务。\"" << endl;
// 实际游戏中这里应该将任务添加到玩家的任务列表
player->setQuestProgress(questName, 0);
break;
}
}
// 如果NPC有商店
if (!shopItems.empty()) {
cout << name << "说:\"我这里有一些东西出售,你有兴趣看看吗?(是/否)\"" << endl;
string response;
cin >> response;
if (response == "是" || response == "y" || response == "yes") {
// 实际游戏中这里应该打开商店界面
cout << name << "打开了商店。" << endl;
}
}
}
void NPC::showShop(Player* player, Game* game) {
cout << name << "的商店:" << endl;
for (const auto& itemName : shopItems) {
// 这里应该根据物品名称获取物品并显示价格
unique_ptr<Item> tempItem;
if (itemName.find("剑") != string::npos || itemName.find("刀") != string::npos) {
tempItem = game->createWeapon(itemName);
} else if (itemName.find("甲") != string::npos || itemName.find("盾") != string::npos) {
tempItem = game->createArmor(itemName);
} else {
tempItem = game->createConsumable(itemName);
}
if (tempItem) {
cout << "- " << tempItem->getName() << ":" << tempItem->getValue() << "金币 - " << tempItem->getDescription() << endl;
}
}
cout << "你有" << player->getGold() << "金币。想买什么?(输入物品名称,或输入'退出'离开商店)" << endl;
string choice;
cin.ignore();
getline(cin, choice);
if (choice == "退出") {
cout << "你离开了商店。" << endl;
return;
}
// 检查玩家是否有足够的钱购买所选物品
unique_ptr<Item> item;
if (choice.find("剑") != string::npos || choice.find("刀") != string::npos) {
item = game->createWeapon(choice);
} else if (choice.find("甲") != string::npos || choice.find("盾") != string::npos) {
item = game->createArmor(choice);
} else {
item = game->createConsumable(choice);
}
if (item && player->spendGold(item->getValue())) {
player->addItem(move(item));
cout << "你购买了" << choice << endl;
} else {
cout << "无法购买" << choice << endl;
}
}
// 位置方法实现
void Location::display() const {
cout << "=== " << name << " ===" << endl;
cout << description << endl;
if (!enemies.empty()) {
cout << "这里有敌人:";
for (const auto& enemy : enemies) {
cout << enemy->getName() << " ";
}
cout << endl;
}
if (!npcs.empty()) {
cout << "这里有可以交谈的人:";
for (const auto& npc : npcs) {
cout << npc->getName() << " ";
}
cout << endl;
}
if (!items.empty()) {
cout << "地上有:";
for (const auto& item : items) {
cout << item->getName() << " ";
}
cout << endl;
}
cout << "可以前往的方向:";
for (const auto& conn : connections) {
cout << conn.first << "(" << conn.second << ") ";
}
cout << endl;
if (!specialAction.empty()) {
cout << "特殊行动:" << specialAction << endl;
}
}
// 任务方法实现
void Quest::display() const {
cout << "=== " << name << " ===" << endl;
cout << description << endl;
cout << "目标:" << objective << endl;
cout << "奖励:" << rewardExperience << "经验值," << rewardGold << "金币";
if (!rewardItems.empty()) {
cout << ",以及物品:";
for (const auto& item : rewardItems) {
cout << item->getName() << " ";
}
}
cout << endl;
cout << (completed ? "状态:已完成" : "状态:进行中") << endl;
}
// 游戏方法实现
void Game::initializeWorld() {
// 创建地点
auto villageSquare = make_unique<Location>(
"village_square",
"这是一个宁静的村庄广场,几条小路从这里通向村子的不同地方。广场中央有一口古井。",
"检查古井"
);
villageSquare->addConnection("北", "blacksmith");
villageSquare->addConnection("南", "inn");
villageSquare->addConnection("东", "farm");
villageSquare->addConnection("西", "forest_edge");
auto blacksmith = make_unique<Location>(
"blacksmith",
"铁匠铺里充满了金属和煤炭的气味。墙上挂着各种武器和盔甲。"
);
blacksmith->addConnection("南", "village_square");
blacksmith->addItem(createWeapon("铁剑"));
auto inn = make_unique<Location>(
"inn",
"这是村里的小酒馆,里面有些客人在喝酒聊天。吧台后面站着酒馆老板。"
);
inn->addConnection("北", "village_square");
auto farm = make_unique<Location>(
"farm",
"这是一个小型农场,有几间农舍和一片田地。一个农夫正在田地里劳作。"
);
farm->addConnection("西", "village_square");
farm->addEnemy(make_unique<Enemy>(
"野狼", 40, 8, 2, 30, 15,
vector<unique_ptr<Item>>{createConsumable("疗伤草药")},
"aggressive"
));
auto forestEdge = make_unique<Location>(
"forest_edge",
"村庄西边的森林边缘。高大的树木遮天蔽日,林中传来奇怪的声音。"
);
forestEdge->addConnection("东", "village_square");
forestEdge->addConnection("西", "dark_forest");
forestEdge->addItem(createConsumable("疗伤草药"));
auto darkForest = make_unique<Location>(
"dark_forest",
"黑暗的森林深处。光线昏暗,四周充满了危险的气息。",
"调查洞穴",
"火把" // 需要火把才能进入
);
darkForest->addConnection("东", "forest_edge");
darkForest->addEnemy(make_unique<Enemy>(
"森林巨魔", 100, 15, 5, 80, 30,
vector<unique_ptr<Item>>{createWeapon("巨木棒"), createConsumable("强效疗伤药")},
"aggressive"
));
darkForest->addItem(createKeyItem("神秘护身符"));
// 添加首领级敌人的地点
auto cave = make_unique<Location>(
"cave",
"一个阴暗潮湿的洞穴。深处似乎有什么东西在移动。",
"",
"神秘护身符" // 需要神秘护身符才能进入
);
cave->addConnection("外", "dark_forest");
cave->addEnemy(make_unique<Enemy>(
"洞穴巨龙", 300, 25, 10, 300, 150,
vector<unique_ptr<Item>>{createWeapon("龙爪剑"), createArmor("龙鳞甲"), createKeyItem("龙之心")},
"aggressive", true
));
// 创建NPC
blacksmith->addNPC(make_unique<NPC>(
"铁匠汤姆",
"欢迎来到我的铁匠铺!我能为你打造最好的武器和盔甲。",
vector<string>{"收集铁矿"},
vector<string>{"铁剑", "钢盾", "皮甲", "疗伤草药"},
true
));
inn->addNPC(make_unique<NPC>(
"酒馆老板玛莎",
"欢迎光临!想喝点什么吗?还是来打听点消息?",
vector<string>{"寻找失踪的信使"},
vector<string>{"麦酒", "疗伤草药", "火把"},
true
));
farm->addNPC(make_unique<NPC>(
"农夫约翰",
"最近田里总被野兽骚扰,我的庄稼都快被吃光了!",
vector<string>{"消灭农场的野狼"},
vector<string>{"面包", "胡萝卜"},
true
));
// 添加地点到游戏世界
locations["village_square"] = move(villageSquare);
locations["blacksmith"] = move(blacksmith);
locations["inn"] = move(inn);
locations["farm"] = move(farm);
locations["forest_edge"] = move(forestEdge);
locations["dark_forest"] = move(darkForest);
locations["cave"] = move(cave);
// 创建任务
quests["消灭农场的野狼"] = make_unique<Quest>(
"消灭农场的野狼",
"农夫约翰的农场受到野狼的侵扰,帮助他清除这些威胁。",
"杀死农场里的3只野狼",
3,
100, 50,
vector<unique_ptr<Item>>{createConsumable("强效疗伤药")}
);
quests["收集铁矿"] = make_unique<Quest>(
"收集铁矿",
"铁匠汤姆需要一些铁矿来制作武器和盔甲。",
"收集5块铁矿",
5,
150, 75,
vector<unique_ptr<Item>>{createWeapon("钢剑")}
);
quests["寻找失踪的信使"] = make_unique<Quest>(
"寻找失踪的信使",
"酒馆老板玛莎说有一个携带重要信件的信使失踪了,可能在森林里。",
"找到失踪的信使或他的遗物",
1,
200, 100,
vector<unique_ptr<Item>>{createArmor("皮甲"), createKeyItem("国王的信件")}
);
}
void Game::run() {
cout << "欢迎来到黑暗森林冒险!" << endl;
cout << "你叫" << player.getName() << ",一个勇敢的冒险者,来到了这个宁静的村庄。" << endl;
cout << "但平静之下似乎隐藏着什么秘密..." << endl;
cout << "输入'帮助'查看可用命令。" << endl;
look();
while (!gameOver) {
cout << endl << "请输入命令: ";
string command;
getline(cin, command);
processCommand(command);
if (!player.isAlive()) {
endGame("死亡结局:你在冒险中不幸丧生。也许下次会更幸运?");
}
checkQuests();
}
displayEnding();
}
void Game::displayStatus() const {
cout << "你现在在" << currentLocation << endl;
player.displayStats();
}
void Game::processCommand(const string& command) {
if (command == "向北" || command == "北") {
move("北");
} else if (command == "向南" || command == "南") {
move("南");
} else if (command == "向东" || command == "东") {
move("东");
} else if (command == "向西" || command == "西") {
move("西");
} else if (command == "向外" || command == "外") {
move("外");
} else if (command == "看" || command == "查看") {
look();
} else if (command == "背包" || command == "物品") {
inventory();
} else if (command == "状态") {
stats();
} else if (command.substr(0, 3) == "交谈 " || command.substr(0, 2) == "说 ") {
string npcName = command.substr(command.find(" ") + 1);
talk(npcName);
} else if (command.substr(0, 3) == "拿起 " || command.substr(0, 2) == "取 ") {
string itemName = command.substr(command.find(" ") + 1);
take(itemName);
} else if (command.substr(0, 3) == "放下 ") {
string itemName = command.substr(command.find(" ") + 1);
drop(itemName);
} else if (command.substr(0, 3) == "使用 ") {
string itemName = command.substr(command.find(" ") + 1);
use(itemName);
} else if (command.substr(0, 3) == "装备 ") {
string itemName = command.substr(command.find(" ") + 1);
equip(itemName);
} else if (command.substr(0, 3) == "攻击 ") {
string enemyName = command.substr(command.find(" ") + 1);
attack(enemyName);
} else if (command == "商店" || command == "购物") {
shop();
} else if (command == "特殊" || command == "行动") {
specialAction();
} else if (command == "帮助") {
cout << "可用命令:" << endl;
cout << "移动:向北、向南、向东、向西、向外" << endl;
cout << "查看:看、查看" << endl;
cout << "物品:背包、物品" << endl;
cout << "状态:状态" << endl;
cout << "交谈:交谈 [NPC名字]" << endl;
cout << "拿起:拿起 [物品名字]" << endl;
cout << "放下:放下 [物品名字]" << endl;
cout << "使用:使用 [物品名字]" << endl;
cout << "装备:装备 [物品名字]" << endl;
cout << "攻击:攻击 [敌人名字]" << endl;
cout << "商店:商店、购物" << endl;
cout << "特殊行动:特殊、行动" << endl;
cout << "退出游戏:退出" << endl;
} else if (command == "退出") {
gameOver = true;
gameEnding = "你中途放弃了冒险。也许有一天你会再次回来?";
} else {
cout << "未知命令。输入'帮助'查看可用命令。" << endl;
}
}
void Game::move(const string& direction) {
auto it = locations.find(currentLocation);
if (it == locations.end()) return;
const auto& connections = it->second->getConnections();
auto connIt = connections.find(direction);
if (connIt == connections.end()) {
cout << "不能往那个方向走!" << endl;
return;
}
string newLocation = connIt->second;
auto locIt = locations.find(newLocation);
if (locIt == locations.end()) return;
// 检查进入新地点的要求
const string& requirement = locIt->second->getRequirement();
if (!requirement.empty() && !player.hasItem(requirement)) {
cout << "你需要" << requirement << "才能进入" << newLocation << "!" << endl;
return;
}
currentLocation = newLocation;
locIt->second->setVisited(true);
cout << "你向" << direction << "走去,来到了" << currentLocation << endl;
look();
// 随机遇敌
uniform_real_distribution<double> dist(0.0, 1.0);
if (!locIt->second->getEnemies().empty() && dist(rng) < 0.7) {
uniform_int_distribution<int> enemyDist(0, locIt->second->getEnemies().size() - 1);
int enemyIndex = enemyDist(rng);
const auto& enemy = locIt->second->getEnemies()[enemyIndex];
cout << "突然,一只" << enemy->getName() << "出现在你面前,准备攻击!" << endl;
combat(&player, enemy.get());
}
}
void Game::look() const {
auto it = locations.find(currentLocation);
if (it != locations.end()) {
it->second->display();
}
}
void Game::inventory() const {
player.displayInventory();
}
void Game::stats() const {
player.displayStats();
}
void Game::talk(const string& npcName) {
auto it = locations.find(currentLocation);
if (it == locations.end()) return;
for (const auto& npc : it->second->getNPCs()) {
if (npc->getName() == npcName) {
npc->talkTo(&player);
return;
}
}
cout << "这里没有叫" << npcName << "的人。" << endl;
}
void Game::take(const string& itemName) {
auto it = locations.find(currentLocation);
if (it == locations.end()) return;
for (const auto& item : it->second->getItems()) {
if (item->getName() == itemName) {
unique_ptr<Item> newItem = item->clone();
player.addItem(move(newItem));
it->second->removeItem(itemName);
return;
}
}
cout << "这里没有" << itemName << "可以拿。" << endl;
}
void Game::drop(const string& itemName) {
unique_ptr<Item> item = player.removeItem(itemName);
if (item) {
auto it = locations.find(currentLocation);
if (it != locations.end()) {
it->second->addItem(move(item));
cout << "你放下了" << itemName << endl;
} else {
player.addItem(move(item)); // 放回物品
cout << "无法放下物品。" << endl;
}
} else {
cout << "你没有" << itemName << "可以放下。" << endl;
}
}
void Game::use(const string& itemName) {
player.useItem(itemName);
}
void Game::equip(const string& itemName) {
player.useItem(itemName); // 使用装备就是装备它
}
void Game::attack(const string& enemyName) {
auto it = locations.find(currentLocation);
if (it == locations.end()) return;
for (const auto& enemy : it->second->getEnemies()) {
if (enemy->getName() == enemyName) {
if (combat(&player, enemy.get())) {
// 战斗胜利,移除敌人
it->second->removeEnemy(enemyName);
// 给予奖励
player.addExperience(enemy->getExperienceReward());
player.addGold(enemy->getGoldReward());
// 生成并给予战利品
vector<unique_ptr<Item>> loot = enemy->generateLoot();
for (auto& item : loot) {
player.addItem(move(item));
}
// 更新任务进度(例如杀死特定敌人的任务)
if (enemyName == "野狼") {
player.setQuestProgress("消灭农场的野狼", player.getQuestProgress("消灭农场的野狼") + 1);
}
cout << "你成功击败了" << enemyName << "!" << endl;
// 如果是首领敌人,可能触发结局
if (enemy->getIsBoss()) {
player.changeMorality("good");
endGame("英雄结局:你击败了洞穴巨龙,村庄恢复了和平。你成为了村民们眼中的英雄!");
}
}
return;
}
}
cout << "这里没有" << enemyName << "可以攻击。" << endl;
}
bool Game::combat(Player* player, Enemy* enemy) {
cout << "=== 战斗开始:" << player->getName() << " vs " << enemy->getName() << " ===" << endl;
while (player->isAlive() && enemy->isAlive()) {
// 玩家回合
cout << endl << "你的回合:" << endl;
cout << "1. 攻击" << endl;
cout << "2. 使用物品" << endl;
cout << "3. 逃跑" << endl;
cout << "选择行动:";
int choice;
cin >> choice;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if (choice == 1) {
// 攻击
int damage = player->getTotalAttack() - enemy->getDefense() / 2;
damage = max(1, damage);
enemy->takeDamage(damage);
cout << "你对" << enemy->getName() << "造成了" << damage << "点伤害!" << endl;
// 检查武器耐久度
if (player->getEquippedWeapon()) {
player->getEquippedWeapon()->reduceDurability();
if (player->getEquippedWeapon()->getDurability() == 0) {
cout << "你的" << player->getEquippedWeapon()->getName() << "损坏了!" << endl;
}
}
} else if (choice == 2) {
// 使用物品
player->displayInventory();
cout << "使用哪个物品?";
string itemName;
getline(cin, itemName);
player->useItem(itemName);
} else if (choice == 3) {
// 逃跑
uniform_real_distribution<double> dist(0.0, 1.0);
if (dist(rng) < 0.5) { // 50% 几率成功逃跑
cout << "你成功逃脱了!" << endl;
return false;
} else {
cout << "逃跑失败!" << endl;
}
} else {
cout << "无效的选择,你犹豫了一下。" << endl;
}
// 检查敌人是否已被击败
if (!enemy->isAlive()) {
break;
}
// 敌人回合
cout << endl << enemy->getName() << "的回合:" << endl;
// 根据敌人行为决定行动
if (enemy->getBehavior() == "fleeing" && enemy->getHealth() < enemy->getMaxHealth() / 3) {
uniform_real_distribution<double> dist(0.0, 1.0);
if (dist(rng) < 0.7) { // 70% 几率逃跑
cout << enemy->getName() << "逃跑了!" << endl;
return false;
}
}
// 敌人攻击
int damage = enemy->getAttack() - player->getTotalDefense() / 2;
damage = max(1, damage);
player->takeDamage(damage);
cout << enemy->getName() << "对你造成了" << damage << "点伤害!" << endl;
// 检查盔甲耐久度
if (player->getEquippedArmor()) {
player->getEquippedArmor()->reduceDurability();
if (player->getEquippedArmor()->getDurability() == 0) {
cout << "你的" << player->getEquippedArmor()->getName() << "损坏了!" << endl;
}
}
}
cout << "=== 战斗结束 ===" << endl;
return player->isAlive();
}
void Game::checkQuests() {
for (const auto& questPair : quests) {
const string& questName = questPair.first;
const Quest* quest = questPair.second.get();
if (!player.hasCompletedQuest(questName) &&
player.getQuestProgress(questName) >= quest->getRequiredProgress()) {
// 完成任务
cout << endl << "恭喜!你完成了任务:" << questName << endl;
player.completeQuest(questName);
player.addExperience(quest->getRewardExperience());
player.addGold(quest->getRewardGold());
for (const auto& item : quest->getRewardItems()) {
player.addItem(item->clone());
}
// 根据任务调整道德值
player.changeMorality("good");
// 检查是否完成了所有任务
if (player.getCompletedQuests().size() == quests.size()) {
endGame("任务大师结局:你完成了所有任务,成为了村庄最受尊敬的人。");
}
}
}
// 检查是否获得了邪恶结局条件
if (player.getMorality() == "evil" && player.hasItem("国王的信件")) {
endGame("背叛结局:你选择了将国王的信件交给了黑暗势力,获得了巨大的力量,但也成为了王国的敌人。");
}
// 检查是否获得了秘密结局条件
if (player.hasItem("龙之心") && player.getMorality() == "good") {
endGame("传奇结局:你不仅击败了巨龙,还净化了龙之心,获得了神秘的力量,成为了传说中的英雄。");
}
}
void Game::shop() {
auto it = locations.find(currentLocation);
if (it == locations.end()) return;
for (const auto& npc : it->second->getNPCs()) {
if (!npc->getShopItems().empty()) {
npc->showShop(&player, this);
return;
}
}
cout << "这里没有商店。" << endl;
}
void Game::specialAction() {
auto it = locations.find(currentLocation);
if (it == locations.end() || it->second->getSpecialAction().empty()) {
cout << "这里没有特殊行动可以执行。" << endl;
return;
}
cout << "你决定" << it->second->getSpecialAction() << endl;
if (currentLocation == "village_square" && it->second->getSpecialAction() == "检查古井") {
uniform_real_distribution<double> dist(0.0, 1.0);
if (dist(rng) < 0.3) {
cout << "你在古井里发现了一把生锈的钥匙!" << endl;
player.addItem(createKeyItem("生锈的钥匙"));
} else {
cout << "古井里除了水什么也没有。" << endl;
}
} else if (currentLocation == "dark_forest" && it->second->getSpecialAction() == "调查洞穴") {
cout << "你发现了一个隐藏的洞穴入口。" << endl;
locations[currentLocation]->addConnection("内", "cave");
cout << "现在你可以向内走进入洞穴了。" << endl;
}
}
void Game::endGame(const string& ending) {
gameOver = true;
gameEnding = ending;
}
void Game::displayEnding() const {
cout << endl << "=== 游戏结束 ===" << endl;
cout << gameEnding << endl;
cout << "你的最终等级:" << player.getLevel() << endl;
cout << "感谢游玩!" << endl;
}
// 物品创建辅助函数实现
unique_ptr<Weapon> Game::createWeapon(const string& name) {
if (name == "铁剑") {
return make_unique<Weapon>(
"铁剑", "一把坚固的铁剑,适合初学者使用。",
50, 8, 20
);
} else if (name == "钢剑") {
return make_unique<Weapon>(
"钢剑", "一把锋利的钢剑,比铁剑更强大。",
100, 12, 30
);
} else if (name == "巨木棒") {
return make_unique<Weapon>(
"巨木棒", "一根粗大的木棒,威力惊人但不够锋利。",
75, 15, 15
);
} else if (name == "龙爪剑") {
return make_unique<Weapon>(
"龙爪剑", "用巨龙的爪子打造的剑,蕴含着神秘的力量。",
500, 25, 50
);
}
return nullptr;
}
unique_ptr<Armor> Game::createArmor(const string& name) {
if (name == "皮甲") {
return make_unique<Armor>(
"皮甲", "由坚韧的皮革制成的盔甲,轻便但防护有限。",
40, 5, 15
);
} else if (name == "钢盾") {
return make_unique<Armor>(
"钢盾", "坚固的钢盾,能有效减少受到的伤害。",
60, 8, 20
);
} else if (name == "龙鳞甲") {
return make_unique<Armor>(
"龙鳞甲", "用巨龙的鳞片制成的盔甲,几乎刀枪不入。",
600, 20, 40
);
}
return nullptr;
}
unique_ptr<Consumable> Game::createConsumable(const string& name) {
if (name == "疗伤草药") {
return make_unique<Consumable>(
"疗伤草药", "能恢复少量生命值的草药。",
true, 15, 20, Consumable::HEAL
);
} else if (name == "强效疗伤药") {
return make_unique<Consumable>(
"强效疗伤药", "能恢复大量生命值的药剂。",
true, 50, 50, Consumable::HEAL
);
} else if (name == "力量药剂") {
return make_unique<Consumable>(
"力量药剂", "能暂时提升攻击力的药剂。",
true, 40, 10, Consumable::BUFF_ATTACK
);
} else if (name == "防御药剂") {
return make_unique<Consumable>(
"防御药剂", "能暂时提升防御力的药剂。",
true, 40, 10, Consumable::BUFF_DEFENSE
);
} else if (name == "毒素瓶") {
return make_unique<Consumable>(
"毒素瓶", "含有剧烈毒素的瓶子,小心使用!",
true, 30, 15, Consumable::POISON
);
} else if (name == "生命精华") {
return make_unique<Consumable>(
"生命精华", "能永久提升最大生命值的神秘液体。",
false, 100, 30, Consumable::STRENGTHEN
);
} else if (name == "麦酒") {
return make_unique<Consumable>(
"麦酒", "口感醇厚的麦酒,能稍微恢复一些体力。",
true, 5, 10, Consumable::HEAL
);
} else if (name == "面包") {
return make_unique<Consumable>(
"面包", "普通的面包,能缓解饥饿。",
true, 3, 5, Consumable::HEAL
);
} else if (name == "胡萝卜") {
return make_unique<Consumable>(
"胡萝卜", "新鲜的胡萝卜,对健康有益。",
true, 2, 3, Consumable::HEAL
);
}
return nullptr;
}
unique_ptr<KeyItem> Game::createKeyItem(const string& name) {
if (name == "神秘护身符") {
return make_unique<KeyItem>(
"神秘护身符", "一个散发着微光的护身符,似乎能打开某种封印。",
"cave"
);
} else if (name == "生锈的钥匙") {
return make_unique<KeyItem>(
"生锈的钥匙", "一把生锈的旧钥匙,不知道能打开什么。",
"old_chest"
);
} else if (name == "国王的信件") {
return make_unique<KeyItem>(
"国王的信件", "一封盖有国王印章的机密信件。",
"treason"
);
} else if (name == "龙之心") {
return make_unique<KeyItem>(
"龙之心", "巨龙的心脏,蕴含着巨大的能量。",
"legendary_end"
);
} else if (name == "火把") {
return make_unique<KeyItem>(
"火把", "燃烧的火把,能照亮黑暗的地方。",
"dark_forest"
);
}
return nullptr;
}
int main() {
cout << "请输入你的名字:";
string playerName;
getline(cin, playerName);
if (playerName.empty()) {
playerName = "冒险者";
}
Game game(playerName);
game.run();
return 0;
}