#include #include #include #include #include #include #include #include #include #include #include using namespace std;

// 游戏常量 const int MAX_HEALTH = 100; const int MAX_LEVEL = 20; const int BASE_DAMAGE = 10; const int BASE_DEFENSE = 5; const int MAP_SIZE = 10;

// 方向枚举 enum Direction { NORTH, EAST, SOUTH, WEST, DIRECTION_COUNT };

// 位置结构 struct Position { int x; int y;

Position(int x = 0, int y = 0) : x(x), y(y) {}

bool operator==(const Position& other) const {
    return x == other.x && y == other.y;
}

Position getAdjacent(Direction dir) const {
    switch(dir) {
        case NORTH: return Position(x, y-1);
        case EAST: return Position(x+1, y);
        case SOUTH: return Position(x, y+1);
        case WEST: return Position(x-1, y);
        default: return *this;
    }
}

string toString() const {
    return "(" + to_string(x) + ", " + to_string(y) + ")";
}

};

// 前向声明 class Character; class Enemy;

// 物品基类 class Item { public: string name; string description; int value; int type; // 0:武器, 1:防具, 2:消耗品, 3:任务物品

Item(string n, string d, int v, int t) : name(n), description(d), value(v), type(t) {}

virtual void use() = 0;
virtual string getDetails() = 0;
virtual unique_ptr<Item> clone() const = 0;
virtual ~Item() = default;

};

// 武器类 class Weapon : public Item { public: int damage;

Weapon(string n, string d, int v, int dmg) : Item(n, d, v, 0), damage(dmg) {}

void use() override {
    cout << "你装备了 " << name << endl;
}

string getDetails() override {
    return name + " (伤害: " + to_string(damage) + ") - " + description;
}

unique_ptr<Item> clone() const override {
    return make_unique<Weapon>(*this);
}

};

// 防具类 class Armor : public Item { public: int defense;

Armor(string n, string d, int v, int def) : Item(n, d, v, 1), defense(def) {}

void use() override {
    cout << "你装备了 " << name << endl;
}

string getDetails() override {
    return name + " (防御: " + to_string(defense) + ") - " + description;
}

unique_ptr<Item> clone() const override {
    return make_unique<Armor>(*this);
}

};

// 消耗品类 class Consumable : public Item { public: int healthRestore;

Consumable(string n, string d, int v, int hr) : Item(n, d, v, 2), healthRestore(hr) {}

void use() override {
    cout << "你使用了 " << name << ", 恢复了 " << healthRestore << " 点生命值" << endl;
}

string getDetails() override {
    return name + " (恢复: " + to_string(healthRestore) + ") - " + description;
}

unique_ptr<Item> clone() const override {
    return make_unique<Consumable>(*this);
}

};

// 任务物品类 class QuestItem : public Item { public: QuestItem(string n, string d, int v) : Item(n, d, v, 3) {}

void use() override {
    cout << "这是任务物品: " << name << ",无法使用" << endl;
}

string getDetails() override {
    return name + " (任务物品) - " + description;
}

unique_ptr<Item> clone() const override {
    return make_unique<QuestItem>(*this);
}

};

// 技能基类 class Skill { public: string name; string description; int manaCost; int cooldown; int currentCooldown;

Skill(string n, string d, int mc, int cd) :
    name(n), description(d), manaCost(mc), cooldown(cd), currentCooldown(0) {}

virtual void use(Character* user, Enemy* target) = 0;
virtual string getDetails() const {
    return name + " (消耗魔法: " + to_string(manaCost) + ", 冷却: " + to_string(cooldown) + ") - " + description;
}

void updateCooldown() {
    if (currentCooldown > 0) {
        currentCooldown--;
    }
}

virtual ~Skill() = default;

};

// 敌人类 class Enemy { public: string name; int health; int maxHealth; int attack; int defense; int expReward; vector<unique_ptr> loot; vector<unique_ptr> skills;

Enemy(string n, int h, int a, int d, int exp) :
    name(n), health(h), maxHealth(h), attack(a), defense(d), expReward(exp) {}

bool isAlive() {
    return health > 0;
}

void takeDamage(int damage) {
    int actualDamage = max(1, damage - defense);
    health -= actualDamage;
    cout << name << " 受到了 " << actualDamage << " 点伤害!" << endl;
}

int calculateDamage() {
    return attack;
}

unique_ptr<Item> getRandomLoot() {
    if (loot.empty() || rand() % 100 < 70) { // 30%几率掉落物品
        return nullptr;
    }
    return loot[rand() % loot.size()]->clone();
}

void performAction(Character* target);

};

// 角色类 class Character { public: string name; int level; int health; int maxHealth; int mana; int maxMana; int attack; int defense; int experience; int expToNextLevel; Position position; vector<unique_ptr> inventory; Weapon* equippedWeapon; Armor* equippedArmor; vector<unique_ptr> skills; map<string, bool> quests;

Character(string n) : name(n), level(1), health(MAX_HEALTH), maxHealth(MAX_HEALTH),
                     mana(50), maxMana(50), attack(BASE_DAMAGE), defense(BASE_DEFENSE),
                     experience(0), expToNextLevel(100), equippedWeapon(nullptr),
                     equippedArmor(nullptr), position(MAP_SIZE/2, MAP_SIZE/2) {
    // 初始化技能
    // 注意:这里需要先声明AttackSkill和HealSkill类
}

void displayStats() {
    cout << "========== " << name << " ==========" << endl;
    cout << "等级: " << level << endl;
    cout << "生命值: " << health << "/" << maxHealth << endl;
    cout << "魔法值: " << mana << "/" << maxMana << endl;
    cout << "攻击力: " << attack + (equippedWeapon ? equippedWeapon->damage : 0) << endl;
    cout << "防御力: " << defense + (equippedArmor ? equippedArmor->defense : 0) << endl;
    cout << "经验值: " << experience << "/" << expToNextLevel << endl;
    cout << "位置: " << position.toString() << endl;
    cout << "==============================" << endl;
}

void addItem(unique_ptr<Item> item) {
    inventory.push_back(move(item));
    cout << "获得了: " << inventory.back()->name << endl;
}

void showInventory() {
    if (inventory.empty()) {
        cout << "背包空空如也..." << endl;
        return;
    }
    
    cout << "========== 背包 ==========" << endl;
    for (int i = 0; i < inventory.size(); i++) {
        cout << i+1 << ". " << inventory[i]->getDetails() << endl;
    }
    cout << "==========================" << endl;
}

void useItem(int index) {
    if (index < 0 || index >= inventory.size()) {
        cout << "无效的选择!" << endl;
        return;
    }
    
    Item* item = inventory[index].get();
    if (item->type == 0) { // 武器
        equippedWeapon = dynamic_cast<Weapon*>(item);
        item->use();
    } else if (item->type == 1) { // 防具
        equippedArmor = dynamic_cast<Armor*>(item);
        item->use();
    } else if (item->type == 2) { // 消耗品
        Consumable* cons = dynamic_cast<Consumable*>(item);
        health = min(maxHealth, health + cons->healthRestore);
        item->use();
        inventory.erase(inventory.begin() + index);
    } else {
        item->use();
    }
}

void gainExp(int exp) {
    experience += exp;
    cout << "获得了 " << exp << " 点经验值!" << endl;
    
    if (experience >= expToNextLevel) {
        levelUp();
    }
}

void levelUp() {
    while (experience >= expToNextLevel && level < MAX_LEVEL) {
        level++;
        experience -= expToNextLevel;
        expToNextLevel = static_cast<int>(expToNextLevel * 1.5);
        
        maxHealth += 20;
        health = maxHealth;
        maxMana += 10;
        mana = maxMana;
        attack += 5;
        defense += 3;
        
        cout << "恭喜! " << name << " 升级到 " << level << " 级!" << endl;
        cout << "最大生命值提升到 " << maxHealth << endl;
        cout << "最大魔法值提升到 " << maxMana << endl;
        cout << "攻击力提升到 " << attack << endl;
        cout << "防御力提升到 " << defense << endl;
        
        // 每5级学习一个新技能
        if (level % 5 == 0) {
            learnNewSkill();
        }
    }
}

void learnNewSkill() {
    cout << "你学会了一个新技能!" << endl;
    
    if (level == 5) {
        // skills.push_back(make_unique<AttackSkill>("旋风斩", "对敌人造成2倍伤害", 20, 3, 20));
        cout << "学会了: 旋风斩" << endl;
    } else if (level == 10) {
        // skills.push_back(make_unique<HealSkill>("高级治疗", "恢复50点生命值", 30, 4, 50));
        cout << "学会了: 高级治疗" << endl;
    } else if (level == 15) {
        // skills.push_back(make_unique<AttackSkill>("致命一击", "造成3倍伤害,但有30%几率失败", 40, 5, 30));
        cout << "学会了: 致命一击" << endl;
    } else if (level == 20) {
        // skills.push_back(make_unique<HealSkill>("神圣之光", "完全恢复生命值", 100, 10, 100));
        cout << "学会了: 神圣之光" << endl;
    }
}

void showSkills() {
    cout << "========== 技能 ==========" << endl;
    for (int i = 0; i < skills.size(); i++) {
        string cooldownInfo = skills[i]->currentCooldown > 0 ?
            " (冷却中: " + to_string(skills[i]->currentCooldown) + "回合)" : " (可用)";
        cout << i+1 << ". " << skills[i]->getDetails() << cooldownInfo << endl;
    }
    cout << "==========================" << endl;
}

void updateSkillCooldowns() {
    for (auto& skill : skills) {
        skill->updateCooldown();
    }
}

bool isAlive() {
    return health > 0;
}

void takeDamage(int damage) {
    int actualDamage = max(1, damage - (defense + (equippedArmor ? equippedArmor->defense : 0)));
    health -= actualDamage;
    cout << name << " 受到了 " << actualDamage << " 点伤害!" << endl;
}

int calculateDamage() {
    return attack + (equippedWeapon ? equippedWeapon->damage : 0);
}

bool hasQuestItem(const string& itemName) {
    for (const auto& item : inventory) {
        if (item->name == itemName && item->type == 3) {
            return true;
        }
    }
    return false;
}

void removeQuestItem(const string& itemName) {
    for (auto it = inventory.begin(); it != inventory.end(); ++it) {
        if ((*it)->name == itemName && (*it)->type == 3) {
            inventory.erase(it);
            cout << "交出了: " << itemName << endl;
            return;
        }
    }
}

void startQuest(const string& questName) {
    quests[questName] = false; // 任务进行中
    cout << "接受了任务: " << questName << endl;
}

void completeQuest(const string& questName) {
    quests[questName] = true; // 任务完成
    cout << "完成了任务: " << questName << endl;
}

bool hasCompletedQuest(const string& questName) {
    auto it = quests.find(questName);
    return it != quests.end() && it->second;
}

bool hasActiveQuest(const string& questName) {
    auto it = quests.find(questName);
    return it != quests.end() && !it->second;
}

};

// 攻击技能 class AttackSkill : public Skill { public: int damageMultiplier;

AttackSkill(string n, string d, int mc, int cd, int dm) :
    Skill(n, d, mc, cd), damageMultiplier(dm) {}

void use(Character* user, Enemy* target) override;

string getDetails() const override {
    return name + " (伤害倍数: " + to_string(damageMultiplier) +
           ", 消耗魔法: " + to_string(manaCost) +
           ", 冷却: " + to_string(cooldown) + ") - " + description;
}

};

// 治疗技能 class HealSkill : public Skill { public: int healAmount;

HealSkill(string n, string d, int mc, int cd, int ha) :
    Skill(n, d, mc, cd), healAmount(ha) {}

void use(Character* user, Enemy* target) override;

string getDetails() const override {
    return name + " (治疗量: " + to_string(healAmount) +
           ", 消耗魔法: " + to_string(manaCost) +
           ", 冷却: " + to_string(cooldown) + ") - " + description;
}

};

// 实现技能使用 void AttackSkill::use(Character* user, Enemy* target) { if (user->mana < manaCost) { cout << "魔法值不足,无法使用 " << name << "!" << endl; return; }

if (currentCooldown > 0) {
    cout << name << " 还在冷却中!" << endl;
    return;
}

user->mana -= manaCost;
currentCooldown = cooldown;

int damage = user->calculateDamage() * damageMultiplier / 10;
cout << user->name << " 使用了 " << name << "!" << endl;
target->takeDamage(damage);

}

void HealSkill::use(Character* user, Enemy* target) { if (user->mana < manaCost) { cout << "魔法值不足,无法使用 " << name << "!" << endl; return; }

if (currentCooldown > 0) {
    cout << name << " 还在冷却中!" << endl;
    return;
}

user->mana -= manaCost;
currentCooldown = cooldown;

user->health = min(user->maxHealth, user->health + healAmount);
cout << user->name << " 使用了 " << name << ", 恢复了 " << healAmount << " 点生命值!" << endl;

}

// 实现Enemy的performAction方法 void Enemy::performAction(Character* target) { // 简单AI:30%几率使用技能(如果有的话),否则普通攻击 if (!skills.empty() && rand() % 100 < 30) { // 使用第一个可用技能 for (auto& skill : skills) { if (skill->currentCooldown == 0) { skill->use(nullptr, this); // 这里需要修复参数 return; } } // 如果没有可用技能,则普通攻击 int damage = calculateDamage(); cout << name << " 攻击了 " << target->name << "!" << endl; target->takeDamage(damage); } else { int damage = calculateDamage(); cout << name << " 攻击了 " << target->name << "!" << endl; target->takeDamage(damage); } }

// 地图格子类型 enum TileType { EMPTY, FOREST, MOUNTAIN, WATER, TOWN, DUNGEON, BOSS };

// NPC类 class NPC { public: string name; string dialogue; vector quests; vector<unique_ptr> items; Position position;

NPC(string n, string d, Position pos) : name(n), dialogue(d), position(pos) {}

void talk() {
    cout << name << ": \"" << dialogue << "\"" << endl;
}

void giveQuest(Character* player, const string& questName) {
    if (find(quests.begin(), quests.end(), questName) != quests.end()) {
        player->startQuest(questName);
    }
}

void completeQuest(Character* player, const string& questName) {
    if (find(quests.begin(), quests.end(), questName) != quests.end()) {
        if (player->hasQuestItem("完成" + questName)) {
            player->completeQuest(questName);
            player->removeQuestItem("完成" + questName);
            
            // 给予奖励
            if (!items.empty()) {
                player->addItem(items[0]->clone());
                cout << name << " 给了你奖励: " << items[0]->name << endl;
            }
            
            player->gainExp(100 * player->level); // 经验奖励基于玩家等级
        } else {
            cout << "你还没有完成这个任务的要求。" << endl;
        }
    }
}

};

// 游戏世界类 class GameWorld { public: vector<vector> map; vector<unique_ptr> enemies; vector<unique_ptr> allItems; vector<unique_ptr> npcs; vector specialLocations;

GameWorld() {
    initializeMap();
    initializeItems();
    initializeEnemies();
    initializeNPCs();
}

void initializeMap() {
    map.resize(MAP_SIZE, vector<TileType>(MAP_SIZE, EMPTY));
    
    // 创建一些地形
    for (int i = 0; i < MAP_SIZE; i++) {
        for (int j = 0; j < MAP_SIZE; j++) {
            if (rand() % 100 < 20) map[i][j] = FOREST;
            if (rand() % 100 < 10) map[i][j] = MOUNTAIN;
            if (rand() % 100 < 5) map[i][j] = WATER;
        }
    }
    
    // 设置特殊地点
    map[0][0] = TOWN;
    map[MAP_SIZE-1][MAP_SIZE-1] = DUNGEON;
    map[MAP_SIZE/2][MAP_SIZE/2] = BOSS;
    
    // 记录特殊位置
    specialLocations.push_back(Position(0, 0));
    specialLocations.push_back(Position(MAP_SIZE-1, MAP_SIZE-1));
    specialLocations.push_back(Position(MAP_SIZE/2, MAP_SIZE/2));
}

void initializeItems() {
    // 创建武器
    allItems.push_back(make_unique<Weapon>("木剑", "一把简单的木制剑", 10, 5));
    allItems.push_back(make_unique<Weapon>("铁剑", "一把标准的铁剑", 30, 10));
    allItems.push_back(make_unique<Weapon>("钢剑", "一把坚固的钢剑", 60, 15));
    allItems.push_back(make_unique<Weapon>("苹果剑", "一把由神秘苹果制成的剑", 100, 25));
    allItems.push_back(make_unique<Weapon>("王者之剑", "传说中的神剑", 200, 35));
    allItems.push_back(make_unique<Weapon>("火焰剑", "蕴含火焰力量的剑", 150, 30));
    allItems.push_back(make_unique<Weapon>("冰霜剑", "蕴含冰霜力量的剑", 150, 30));
    allItems.push_back(make_unique<Weapon>("雷电剑", "蕴含雷电力量的剑", 150, 30));
    
    // 创建防具
    allItems.push_back(make_unique<Armor>("布甲", "简单的布制护甲", 15, 3));
    allItems.push_back(make_unique<Armor>("皮甲", "皮革制成的护甲", 40, 7));
    allItems.push_back(make_unique<Armor>("铁甲", "铁制的护甲", 80, 12));
    allItems.push_back(make_unique<Armor>("苹果护甲", "由神秘苹果制成的护甲", 150, 20));
    allItems.push_back(make_unique<Armor>("王者护甲", "传说中的神甲", 250, 30));
    allItems.push_back(make_unique<Armor>("火焰护甲", "蕴含火焰力量的护甲", 180, 25));
    allItems.push_back(make_unique<Armor>("冰霜护甲", "蕴含冰霜力量的护甲", 180, 25));
    allItems.push_back(make_unique<Armor>("雷电护甲", "蕴含雷电力量的护甲", 180, 25));
    
    // 创建消耗品
    allItems.push_back(make_unique<Consumable>("小苹果", "恢复少量生命值", 5, 20));
    allItems.push_back(make_unique<Consumable>("苹果", "恢复中等生命值", 10, 40));
    allItems.push_back(make_unique<Consumable>("金苹果", "恢复大量生命值", 20, 80));
    allItems.push_back(make_unique<Consumable>("神秘苹果", "完全恢复生命值", 50, 100));
    allItems.push_back(make_unique<Consumable>("魔法药水", "恢复50点魔法值", 15, 0));
    allItems.push_back(make_unique<Consumable>("强力魔法药水", "完全恢复魔法值", 30, 0));
    
    // 创建任务物品
    allItems.push_back(make_unique<QuestItem>("哥布林首领的头颅", "哥布林首领的头颅,证明你击败了它", 1));
    allItems.push_back(make_unique<QuestItem>("龙之鳞片", "从巨龙身上取得的鳞片", 1));
    allItems.push_back(make_unique<QuestItem>("神秘信件", "一封神秘的信件,内容不明", 1));
    allItems.push_back(make_unique<QuestItem>("古老地图", "标记着宝藏位置的地图", 1));
}

void initializeEnemies() {
    // 创建敌人
    auto goblin = make_unique<Enemy>("哥布林", 30, 8, 2, 20);
    goblin->loot.push_back(allItems[0]->clone()); // 木剑
    goblin->loot.push_back(allItems[8]->clone()); // 布甲
    goblin->loot.push_back(allItems[16]->clone()); // 小苹果
    enemies.push_back(move(goblin));
    
    auto orc = make_unique<Enemy>("兽人", 50, 12, 5, 40);
    orc->loot.push_back(allItems[1]->clone()); // 铁剑
    orc->loot.push_back(allItems[9]->clone()); // 皮甲
    orc->loot.push_back(allItems[17]->clone()); // 苹果
    enemies.push_back(move(orc));
    
    auto troll = make_unique<Enemy>("巨魔", 80, 15, 8, 70);
    troll->loot.push_back(allItems[2]->clone()); // 钢剑
    troll->loot.push_back(allItems[10]->clone()); // 铁甲
    troll->loot.push_back(allItems[18]->clone()); // 金苹果
    enemies.push_back(move(troll));
    
    auto darkKnight = make_unique<Enemy>("黑暗骑士", 120, 20, 12, 120);
    darkKnight->loot.push_back(allItems[3]->clone()); // 苹果剑
    darkKnight->loot.push_back(allItems[11]->clone()); // 苹果护甲
    darkKnight->loot.push_back(allItems[19]->clone()); // 神秘苹果
    enemies.push_back(move(darkKnight));
    
    auto dragon = make_unique<Enemy>("巨龙", 200, 30, 15, 250);
    dragon->loot.push_back(allItems[4]->clone()); // 王者之剑
    dragon->loot.push_back(allItems[12]->clone()); // 王者护甲
    dragon->loot.push_back(allItems[20]->clone()); // 魔法药水
    enemies.push_back(move(dragon));
    
    // 添加更多敌人变种
    auto fireDragon = make_unique<Enemy>("火焰巨龙", 220, 35, 18, 300);
    fireDragon->loot.push_back(allItems[5]->clone()); // 火焰剑
    fireDragon->loot.push_back(allItems[13]->clone()); // 火焰护甲
    fireDragon->loot.push_back(allItems[21]->clone()); // 强力魔法药水
    enemies.push_back(move(fireDragon));
    
    auto iceDragon = make_unique<Enemy>("冰霜巨龙", 220, 35, 18, 300);
    iceDragon->loot.push_back(allItems[6]->clone()); // 冰霜剑
    iceDragon->loot.push_back(allItems[14]->clone()); // 冰霜护甲
    iceDragon->loot.push_back(allItems[21]->clone()); // 强力魔法药水
    enemies.push_back(move(iceDragon));
    
    auto thunderDragon = make_unique<Enemy>("雷电巨龙", 220, 35, 18, 300);
    thunderDragon->loot.push_back(allItems[7]->clone()); // 雷电剑
    thunderDragon->loot.push_back(allItems[15]->clone()); // 雷电护甲
    thunderDragon->loot.push_back(allItems[21]->clone()); // 强力魔法药水
    enemies.push_back(move(thunderDragon));
    
    auto goblinChief = make_unique<Enemy>("哥布林首领", 100, 18, 10, 150);
    goblinChief->loot.push_back(allItems[22]->clone()); // 哥布林首领的头颅
    goblinChief->loot.push_back(allItems[3]->clone()); // 苹果剑
    enemies.push_back(move(goblinChief));
}

void initializeNPCs() {
    // 创建NPC
    auto blacksmith = make_unique<NPC>("铁匠约翰", "欢迎来到我的铁匠铺!如果你需要装备,我可以帮你修理或升级。", Position(0, 1));
    blacksmith->quests.push_back("收集材料");
    blacksmith->items.push_back(allItems[1]->clone()); // 铁剑作为奖励
    npcs.push_back(move(blacksmith));
    
    auto mayor = make_unique<NPC>("村长", "我们的村庄正受到哥布林的威胁。你能帮我们消灭哥布林首领吗?", Position(1, 0));
    mayor->quests.push_back("消灭哥布林首领");
    mayor->items.push_back(allItems[9]->clone()); // 皮甲作为奖励
    npcs.push_back(move(mayor));
    
    auto wizard = make_unique<NPC>("巫师梅林", "我正在研究一种强大的魔法,但我需要龙之鳞片来完成我的研究。", Position(MAP_SIZE-2, MAP_SIZE-2));
    wizard->quests.push_back("收集龙之鳞片");
    wizard->items.push_back(allItems[20]->clone()); // 魔法药水作为奖励
    npcs.push_back(move(wizard));
    
    auto merchant = make_unique<NPC>("旅行商人", "我有各种稀有商品,只要你有足够的金币!", Position(3, 3));
    merchant->items.push_back(allItems[19]->clone()); // 神秘苹果
    merchant->items.push_back(allItems[21]->clone()); // 强力魔法药水
    npcs.push_back(move(merchant));
}

string getTileDescription(TileType tile) {
    switch(tile) {
        case EMPTY: return "空地";
        case FOREST: return "森林";
        case MOUNTAIN: return "山脉";
        case WATER: return "水域";
        case TOWN: return "城镇";
        case DUNGEON: return "地下城";
        case BOSS: return "BOSS区域";
        default: return "未知";
    }
}

void displayMap(const Position& playerPos) {
    cout << "========== 地图 ==========" << endl;
    for (int y = 0; y < MAP_SIZE; y++) {
        for (int x = 0; x < MAP_SIZE; x++) {
            if (x == playerPos.x && y == playerPos.y) {
                cout << "P ";
            } else {
                switch(map[y][x]) {
                    case EMPTY: cout << ". "; break;
                    case FOREST: cout << "F "; break;
                    case MOUNTAIN: cout << "M "; break;
                    case WATER: cout << "W "; break;
                    case TOWN: cout << "T "; break;
                    case DUNGEON: cout << "D "; break;
                    case BOSS: cout << "B "; break;
                    default: cout << "? "; break;
                }
            }
        }
        cout << endl;
    }
    cout << "图例: P=玩家, .=空地, F=森林, M=山脉, W=水域, T=城镇, D=地下城, B=BOSS" << endl;
    cout << "==========================" << endl;
}

bool isValidPosition(const Position& pos) {
    return pos.x >= 0 && pos.x < MAP_SIZE && pos.y >= 0 && pos.y < MAP_SIZE;
}

bool canMoveTo(const Position& pos) {
    if (!isValidPosition(pos)) return false;
    TileType tile = map[pos.y][pos.x];
    return tile != WATER && tile != MOUNTAIN;
}

NPC* getNPCAt(const Position& pos) {
    for (const auto& npc : npcs) {
        if (npc->position == pos) {
            return npc.get();
        }
    }
    return nullptr;
}

bool isSpecialLocation(const Position& pos) {
    for (const auto& loc : specialLocations) {
        if (loc == pos) {
            return true;
        }
    }
    return false;
}

string getLocationName(const Position& pos) {
    if (pos == Position(0, 0)) return "起始村庄";
    if (pos == Position(MAP_SIZE-1, MAP_SIZE-1)) return "龙之巢穴";
    if (pos == Position(MAP_SIZE/2, MAP_SIZE/2)) return "最终BOSS领域";
    return getTileDescription(map[pos.y][pos.x]);
}

};

// 游戏类 class AppleKnightGame { private: unique_ptr player; GameWorld world; bool gameRunning; int gameEnding; // 0: 未结束, 1: 胜利, 2: 失败

public: AppleKnightGame() : gameRunning(false), gameEnding(0) { srand(time(0)); }

void startGame() {
    cout << "欢迎来到苹果骑士!" << endl;
    cout << "这是一个关于勇敢骑士寻找神秘苹果的冒险故事。" << endl;
    cout << "请创建你的角色..." << endl;
    
    string playerName;
    cout << "输入你的角色名: ";
    getline(cin, playerName);
    
    player = make_unique<Character>(playerName);
    gameRunning = true;
    gameEnding = 0;
    
    // 给玩家初始物品
    player->addItem(world.allItems[0]->clone()); // 木剑
    player->addItem(world.allItems[8]->clone()); // 布甲
    player->addItem(world.allItems[16]->clone()); // 小苹果
    player->addItem(world.allItems[16]->clone()); // 小苹果
    
    // 初始化技能
    player->skills.push_back(make_unique<AttackSkill>("强力打击", "造成1.5倍伤害", 10, 2, 15));
    player->skills.push_back(make_unique<HealSkill>("治疗术", "恢复20点生命值", 15, 3, 20));
    
    cout << "游戏开始! 你获得了初始装备。" << endl;
    player->displayStats();
    
    mainGameLoop();
}

void mainGameLoop() {
    while (gameRunning && player->isAlive() && gameEnding == 0) {
        displayLocationInfo();
        displayMainMenu();
        int choice;
        cin >> choice;
        
        switch (choice) {
            case 1:
                moveMenu();
                break;
            case 2:
                explore();
                break;
            case 3:
                player->displayStats();
                break;
            case 4:
                player->showInventory();
                useItemMenu();
                break;
            case 5:
                player->showSkills();
                break;
            case 6:
                checkForNPC();
                break;
            case 7:
                world.displayMap(player->position);
                break;
            case 8:
                saveGame();
                break;
            case 9:
                loadGame();
                break;
            case 10:
                cout << "感谢游玩苹果骑士!" << endl;
                gameRunning = false;
                break;
            default:
                cout << "无效的选择,请重试。" << endl;
        }
        
        // 检查玩家是否达到最高等级
        if (player->level >= MAX_LEVEL) {
            cout << "恭喜! 你已经成为最高等级的苹果骑士!" << endl;
            cout << "游戏胜利!" << endl;
            gameEnding = 1;
        }
        
        // 检查玩家是否在BOSS区域并击败了所有BOSS
        if (world.getTileDescription(world.map[player->position.y][player->position.x]) == "BOSS区域" &&
            player->hasCompletedQuest("消灭哥布林首领") &&
            player->hasCompletedQuest("收集龙之鳞片") &&
            player->hasCompletedQuest("击败最终BOSS")) {
            cout << "恭喜! 你完成了所有任务,拯救了世界!" << endl;
            cout << "真正的结局: 和平时代来临!" << endl;
            gameEnding = 1;
        }
    }
    
    if (!player->isAlive()) {
        cout << "游戏结束! 你被击败了。" << endl;
        gameEnding = 2;
    }
    
    displayEnding();
}

void displayLocationInfo() {
    cout << "\n========== 位置信息 ==========" << endl;
    cout << "当前位置: " << world.getLocationName(player->position) << endl;
    cout << "地形: " << world.getTileDescription(world.map[player->position.y][player->position.x]) << endl;
    
    NPC* npc = world.getNPCAt(player->position);
    if (npc) {
        cout << "你看到了: " << npc->name << endl;
    }
    
    cout << "==============================" << endl;
}

void displayMainMenu() {
    cout << "\n========== 主菜单 ==========" << endl;
    cout << "1. 移动" << endl;
    cout << "2. 探索" << endl;
    cout << "3. 查看状态" << endl;
    cout << "4. 背包" << endl;
    cout << "5. 技能" << endl;
    cout << "6. 与NPC交谈" << endl;
    cout << "7. 查看地图" << endl;
    cout << "8. 保存游戏" << endl;
    cout << "9. 读取游戏" << endl;
    cout << "10. 退出游戏" << endl;
    cout << "请选择: ";
}

void moveMenu() {
    cout << "\n========== 移动 ==========" << endl;
    cout << "1. 向北移动" << endl;
    cout << "2. 向东移动" << endl;
    cout << "3. 向南移动" << endl;
    cout << "4. 向西移动" << endl;
    cout << "5. 取消" << endl;
    cout << "请选择方向: ";
    
    int choice;
    cin >> choice;
    
    if (choice < 1 || choice > 4) {
        cout << "移动取消。" << endl;
        return;
    }
    
    Direction dir = static_cast<Direction>(choice - 1);
    Position newPos = player->position.getAdjacent(dir);
    
    if (world.canMoveTo(newPos)) {
        player->position = newPos;
        cout << "你移动到了 " << world.getLocationName(player->position) << endl;
        
        // 特殊地点事件
        if (world.isSpecialLocation(player->position)) {
            handleSpecialLocation();
        }
    } else {
        cout << "无法移动到那个位置。" << endl;
    }
}

void handleSpecialLocation() {
    if (player->position == Position(0, 0)) { // 起始村庄
        cout << "欢迎来到起始村庄! 这里是安全的避风港。" << endl;
        // 自动恢复生命和魔法
        player->health = player->maxHealth;
        player->mana = player->maxMana;
        cout << "在村庄中,你的生命值和魔法值完全恢复了!" << endl;
    } else if (player->position == Position(MAP_SIZE-1, MAP_SIZE-1)) { // 龙之巢穴
        cout << "你来到了龙之巢穴! 这里充满了危险的气息。" << endl;
        if (!player->hasCompletedQuest("收集龙之鳞片") && !player->hasActiveQuest("收集龙之鳞片")) {
            cout << "你发现了一些龙之鳞片,但没有龙在这里。" << endl;
            player->addItem(world.allItems[23]->clone()); // 龙之鳞片
        }
    } else if (player->position == Position(MAP_SIZE/2, MAP_SIZE/2)) { // BOSS区域
        cout << "你进入了最终BOSS的领域! 准备战斗!" << endl;
        if (!player->hasCompletedQuest("击败最终BOSS")) {
            battle(world.enemies[7].get()); // 火焰巨龙
            if (player->isAlive()) {
                player->completeQuest("击败最终BOSS");
            }
        }
    }
}

void explore() {
    cout << "\n你开始探索..." << endl;
    
    TileType currentTile = world.map[player->position.y][player->position.x];
    int encounterChance = 0;
    
    // 根据地形决定遭遇几率
    switch(currentTile) {
        case FOREST: encounterChance = 40; break;
        case DUNGEON: encounterChance = 70; break;
        case BOSS: encounterChance = 90; break;
        default: encounterChance = 20; break;
    }
    
    // 30%几率遇到敌人,30%几率找到物品,40%几率无事发生
    int encounter = rand() % 100;
    
    if (encounter < encounterChance) {
        // 遇到敌人
        int enemyIndex = rand() % world.enemies.size();
        
        // 根据玩家等级调整敌人强度
        if (player->level < 5) enemyIndex = min(enemyIndex, 2);
        else if (player->level < 10) enemyIndex = min(enemyIndex, 4);
        else if (player->level < 15) enemyIndex = min(enemyIndex, 6);
        
        Enemy* enemy = world.enemies[enemyIndex].get();
        cout << "你遇到了一个 " << enemy->name << "!" << endl;
        battle(enemy);
    } else if (encounter < encounterChance + 20) {
        // 找到物品
        int itemIndex = rand() % world.allItems.size();
        Item* foundItem = world.allItems[itemIndex].get();
        cout << "你发现了一个宝箱! 里面是: " << foundItem->name << endl;
        player->addItem(foundItem->clone());
    } else {
        cout << "你探索了一段时间,但没有发现什么特别的东西。" << endl;
    }
}

void battle(Enemy* enemy) {
    cout << "\n========== 战斗开始! ==========" << endl;
    cout << player->name << " vs " << enemy->name << endl;
    
    // 重置技能冷却
    player->updateSkillCooldowns();
    
    while (player->isAlive() && enemy->isAlive()) {
        // 玩家回合
        cout << "\n你的回合:" << endl;
        cout << "1. 攻击" << endl;
        cout << "2. 使用技能" << endl;
        cout << "3. 使用物品" << endl;
        cout << "4. 逃跑" << endl;
        cout << "请选择: ";
        
        int choice;
        cin >> choice;
        
        if (choice == 1) {
            // 攻击
            int damage = player->calculateDamage();
            cout << player->name << " 攻击了 " << enemy->name << "!" << endl;
            enemy->takeDamage(damage);
        } else if (choice == 2) {
            // 使用技能
            useSkillMenu(enemy);
            continue; // 使用技能后不结束回合
        } else if (choice == 3) {
            // 使用物品
            useItemMenu();
            continue; // 使用物品后不结束回合
        } else if (choice == 4) {
            // 逃跑
            if (rand() % 100 < 50) { // 50%几率逃跑成功
                cout << "你成功逃脱了!" << endl;
                return;
            } else {
                cout << "逃跑失败!" << endl;
            }
        } else {
            cout << "无效的选择,自动攻击!" << endl;
            int damage = player->calculateDamage();
            cout << player->name << " 攻击了 " << enemy->name << "!" << endl;
            enemy->takeDamage(damage);
        }
        
        // 检查敌人是否被击败
        if (!enemy->isAlive()) {
            cout << "你击败了 " << enemy->name << "!" << endl;
            player->gainExp(enemy->expReward);
            
            // 掉落物品
            unique_ptr<Item> loot = enemy->getRandomLoot();
            if (loot) {
                cout << enemy->name << " 掉落了: " << loot->name << endl;
                player->addItem(move(loot));
            }
            
            // 检查是否完成相关任务
            if (enemy->name == "哥布林首领" && player->hasActiveQuest("消灭哥布林首领")) {
                player->addItem(world.allItems[22]->clone()); // 哥布林首领的头颅
            } else if ((enemy->name == "巨龙" || enemy->name == "火焰巨龙" ||
                       enemy->name == "冰霜巨龙" || enemy->name == "雷电巨龙") &&
                       player->hasActiveQuest("收集龙之鳞片")) {
                player->addItem(world.allItems[23]->clone()); // 龙之鳞片
            }
            
            break;
        }
        
        // 敌人回合
        cout << "\n" << enemy->name << "的回合:" << endl;
        enemy->performAction(player.get());
        
        // 检查玩家是否被击败
        if (!player->isAlive()) {
            cout << "你被 " << enemy->name << " 击败了!" << endl;
            break;
        }
    }
    
    cout << "========== 战斗结束! ==========" << endl;
}

void useSkillMenu(Enemy* enemy) {
    if (player->skills.empty()) {
        cout << "你没有技能!" << endl;
        return;
    }
    
    player->showSkills();
    cout << "选择要使用的技能 (0取消): ";
    int choice;
    cin >> choice;
    
    if (choice == 0) return;
    if (choice < 1 || choice > player->skills.size()) {
        cout << "无效的选择!" << endl;
        return;
    }
    
    player->skills[choice-1]->use(player.get(), enemy);
}

void useItemMenu() {
    if (player->inventory.empty()) {
        cout << "背包为空!" << endl;
        return;
    }
    
    player->showInventory();
    cout << "选择要使用的物品 (0取消): ";
    int choice;
    cin >> choice;
    
    if (choice == 0) return;
    player->useItem(choice - 1);
}

void checkForNPC() {
    NPC* npc = world.getNPCAt(player->position);
    if (npc) {
        cout << "你遇到了 " << npc->name << endl;
        npc->talk();
        
        // 显示NPC选项
        cout << "\n你要做什么?" << endl;
        cout << "1. 交谈" << endl;
        cout << "2. 接受任务" << endl;
        cout << "3. 交付任务" << endl;
        cout << "4. 离开" << endl;
        cout << "请选择: ";
        
        int choice;
        cin >> choice;
        
        switch(choice) {
            case 1:
                npc->talk();
                break;
            case 2:
                if (!npc->quests.empty()) {
                    for (int i = 0; i < npc->quests.size(); i++) {
                        cout << i+1 << ". " << npc->quests[i] << endl;
                    }
                    cout << "选择要接受的任务 (0取消): ";
                    int questChoice;
                    cin >> questChoice;
                    if (questChoice > 0 && questChoice <= npc->quests.size()) {
                        player->startQuest(npc->quests[questChoice-1]);
                    }
                } else {
                    cout << "这个NPC没有任务可提供。" << endl;
                }
                break;
            case 3:
                if (!npc->quests.empty()) {
                    for (int i = 0; i < npc->quests.size(); i++) {
                        cout << i+1 << ". " << npc->quests[i] << " - ";
                        if (player->hasCompletedQuest(npc->quests[i])) {
                            cout << "已完成" << endl;
                        } else if (player->hasActiveQuest(npc->quests[i])) {
                            cout << "进行中" << endl;
                        } else {
                            cout << "未接受" << endl;
                        }
                    }
                    cout << "选择要交付的任务 (0取消): ";
                    int questChoice;
                    cin >> questChoice;
                    if (questChoice > 0 && questChoice <= npc->quests.size()) {
                        npc->completeQuest(player.get(), npc->quests[questChoice-1]);
                    }
                } else {
                    cout << "这个NPC没有任务可交付。" << endl;
                }
                break;
            case 4:
                cout << "你离开了。" << endl;
                break;
            default:
                cout << "无效的选择。" << endl;
        }
    } else {
        cout << "这里没有NPC。" << endl;
    }
}

void saveGame() {
    ofstream saveFile("apple_knight_save.txt");
    if (!saveFile) {
        cout << "保存游戏失败!" << endl;
        return;
    }
    
    // 保存玩家数据
    saveFile << player->name << endl;
    saveFile << player->level << endl;
    saveFile << player->health << endl;
    saveFile << player->maxHealth << endl;
    saveFile << player->mana << endl;
    saveFile << player->maxMana << endl;
    saveFile << player->attack << endl;
    saveFile << player->defense << endl;
    saveFile << player->experience << endl;
    saveFile << player->expToNextLevel << endl;
    saveFile << player->position.x << endl;
    saveFile << player->position.y << endl;
    
    // 保存装备
    saveFile << (player->equippedWeapon ? player->equippedWeapon->name : "None") << endl;
    saveFile << (player->equippedArmor ? player->equippedArmor->name : "None") << endl;
    
    // 保存背包
    saveFile << player->inventory.size() << endl;
    for (const auto& item : player->inventory) {
        saveFile << item->name << endl;
    }
    
    // 保存任务
    saveFile << player->quests.size() << endl;
    for (const auto& quest : player->quests) {
        saveFile << quest.first << endl;
        saveFile << quest.second << endl;
    }
    
    saveFile.close();
    cout << "游戏已保存!" << endl;
}

void loadGame() {
    ifstream saveFile("apple_knight_save.txt");
    if (!saveFile) {
        cout << "没有找到保存文件!" << endl;
        return;
    }
    
    // 读取玩家数据
    string name;
    int level, health, maxHealth, mana, maxMana, attack, defense, experience, expToNextLevel, x, y;
    
    getline(saveFile, name);
    saveFile >> level >> health >> maxHealth >> mana >> maxMana >> attack >> defense >> experience >> expToNextLevel >> x >> y;
    saveFile.ignore(); // 忽略换行符
    
    // 创建新角色
    player = make_unique<Character>(name);
    player->level = level;
    player->health = health;
    player->maxHealth = maxHealth;
    player->mana = mana;
    player->maxMana = maxMana;
    player->attack = attack;
    player->defense = defense;
    player->experience = experience;
    player->expToNextLevel = expToNextLevel;
    player->position = Position(x, y);
    
    // 读取装备
    string weaponName, armorName;
    getline(saveFile, weaponName);
    getline(saveFile, armorName);
    
    // 读取背包
    int inventorySize;
    saveFile >> inventorySize;
    saveFile.ignore(); // 忽略换行符
    
    player->inventory.clear();
    for (int i = 0; i < inventorySize; i++) {
        string itemName;
        getline(saveFile, itemName);
        
        // 查找物品
        for (const auto& item : world.allItems) {
            if (item->name == itemName) {
                player->inventory.push_back(item->clone());
                break;
            }
        }
    }
    
    // 装备武器和防具
    if (weaponName != "None") {
        for (const auto& item : player->inventory) {
            if (item->name == weaponName && item->type == 0) {
                player->equippedWeapon = dynamic_cast<Weapon*>(item.get());
                break;
            }
        }
    }
    
    if (armorName != "None") {
        for (const auto& item : player->inventory) {
            if (item->name == armorName && item->type == 1) {
                player->equippedArmor = dynamic_cast<Armor*>(item.get());
                break;
            }
        }
    }
    
    // 读取任务
    int questsSize;
    saveFile >> questsSize;
    saveFile.ignore(); // 忽略换行符
    
    player->quests.clear();
    for (int i = 0; i < questsSize; i++) {
        string questName;
        bool completed;
        getline(saveFile, questName);
        saveFile >> completed;
        saveFile.ignore(); // 忽略换行符
        player->quests[questName] = completed;
    }
    
    saveFile.close();
    cout << "游戏已加载!" << endl;
    player->displayStats();
}

void displayEnding() {
    cout << "\n========== 游戏结束 ==========" << endl;
    if (gameEnding == 1) {
        cout << "恭喜你完成了苹果骑士的冒险!" << endl;
        cout << "你的最终等级: " << player->level << endl;
        cout << "你完成的任务数量: " << count_if(player->quests.begin(), player->quests.end(),
            [](const pair<string, bool>& p) { return p.second; }) << "/" << player->quests.size() << endl;
        
        if (player->hasCompletedQuest("击败最终BOSS")) {
            cout << "结局: 英雄 - 你击败了最终BOSS,成为了传奇!" << endl;
        } else if (player->level >= MAX_LEVEL) {
            cout << "结局: 大师 - 你通过修炼达到了最高境界!" << endl;
        } else {
            cout << "结局: 冒险者 - 你的冒险告一段落,但还有更多故事等待发现。" << endl;
        }
    } else {
        cout << "很遗憾,你的冒险结束了。" << endl;
        cout << "你的最终等级: " << player->level << endl;
        cout << "你完成的任务数量: " << count_if(player->quests.begin(), player->quests.end(),
            [](const pair<string, bool>& p) { return p.second; }) << "/" << player->quests.size() << endl;
        cout << "结局: 失败 - 但每次失败都是新开始的契机。" << endl;
    }
    cout << "==============================" << endl;
}

};

// 主函数 int main() { AppleKnightGame game; game.startGame(); return 0; }

6 条评论

  • 1