#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <iomanip>
#include <algorithm>

using namespace std; // 修复:缺少命名空间

// 随机数生成器
random_device rd;
mt19937 rng(rd());

// 成就结构体
struct Achievement {
    string id;
    string name;
    string description;
    bool unlocked;
    int progress;
    int target;

    Achievement(string i, string n, string d, int t = 0)
        : id(i), name(n), description(d), unlocked(false), progress(0), target(t) {}
};

// 士兵类型枚举
enum class SoldierType {
    INFANTRY,
    ARCHER,
    CAVALRY
};

// 士兵单位结构体
struct SoldierUnit {
    SoldierType type;
    int count;
    int attack;
    int defense;
    int cost;

    SoldierUnit(SoldierType t, int c = 0) : type(t), count(c) {
        switch (t) {
            case SoldierType::INFANTRY:
                attack = 10; defense = 10; cost = 5;
                break;
            case SoldierType::ARCHER:
                attack = 15; defense = 5; cost = 8;
                break;
            case SoldierType::CAVALRY:
                attack = 20; defense = 15; cost = 15;
                break;
        }
    }

    string getTypeName() const {
        switch (type) {
            case SoldierType::INFANTRY: return "步兵";
            case SoldierType::ARCHER:   return "弓箭手";
            case SoldierType::CAVALRY:  return "骑兵";
            default: return "未知";
        }
    }

    int getTotalPower() const {
        return (attack + defense) * count;
    }
};

// 王国类
class Kingdom {
private:
    string name;
    int gold;
    int food;
    int territory;
    vector<SoldierUnit> army;
    vector<Achievement> achievements;
    int battleWins;

    void checkAchievements() {
        for (auto& ach : achievements) {
            if (ach.unlocked) continue;

            if (ach.target > 0) {
                if (ach.progress >= ach.target) {
                    ach.unlocked = true;
                    cout << "\n【成就解锁!】" << ach.name << " - " << ach.description << endl;
                }
                continue;
            }

            if (ach.id == "found_kingdom" && territory >= 1) {
                ach.unlocked = true;
                cout << "\n【成就解锁!】" << ach.name << " - " << ach.description << endl;
            }
            if (ach.id == "first_victory" && battleWins >= 1) {
                ach.unlocked = true;
                cout << "\n【成就解锁!】" << ach.name << " - " << ach.description << endl;
            }
            if (ach.id == "gold_1000" && gold >= 1000) {
                ach.unlocked = true;
                cout << "\n【成就解锁!】" << ach.name << " - " << ach.description << endl;
            }
            if (ach.id == "large_army" && getTotalArmyCount() >= 500) {
                ach.unlocked = true;
                cout << "\n【成就解锁!】" << ach.name << " - " << ach.description << endl;
            }
        }
    }

    int getTotalArmyCount() const {
        int total = 0;
        for (const auto& unit : army) total += unit.count;
        return total;
    }

    int getTotalArmyPower() const {
        int total = 0;
        for (const auto& unit : army) total += unit.getTotalPower();
        return total;
    }

public:
    Kingdom(string n) : name(n), gold(500), food(1000), territory(1), battleWins(0) {
        achievements.emplace_back("found_kingdom", "建国立业", "成功建立你的第一个王国");
        achievements.emplace_back("first_victory", "初战告捷", "赢得第一场战斗的胜利");
        achievements.emplace_back("gold_1000", "富甲一方", "拥有1000枚金币");
        achievements.emplace_back("large_army", "百万雄师", "招募士兵总数达到500人", 500);
        achievements.emplace_back("5_wins", "百战百胜", "累计赢得5场战斗", 5);
    }

    void showStatus() const {
        cout << "\n====================【" << name << "王国状态】====================" << endl;
        cout << "金币:" << gold << " | 粮食:" << food << " | 领土:" << territory << " 平方公里" << endl;
        cout << "当前军队总人数:" << getTotalArmyCount() << " | 总战力:" << getTotalArmyPower() << endl;
        cout << "战斗胜利次数:" << battleWins << endl;
        cout << "------------------------------------------------------------" << endl;
        cout << "【军队编制】" << endl;
        bool hasSoldier = false;
        for (const auto& unit : army) {
            if (unit.count > 0) {
                hasSoldier = true;
                cout << unit.getTypeName() << ":" << unit.count << "人 | 单战力:"
                     << (unit.attack + unit.defense) << " | 总成本:" << unit.cost * unit.count << endl;
            }
        }
        if (!hasSoldier) cout << "暂无士兵,快去招募吧!" << endl;
        cout << "============================================================" << endl;
    }

    void recruitSoldiers() {
        cout << "\n====================【招募士兵】====================" << endl;
        cout << "当前金币:" << gold << " | 粮食:" << food << endl;
        cout << "1. 步兵(5金币/人):均衡型单位" << endl;
        cout << "2. 弓箭手(8金币/人):远程攻击加成" << endl;
        cout << "3. 骑兵(15金币/人):冲锋战力加成" << endl;
        cout << "0. 返回主菜单" << endl;
        cout << "请选择士兵类型:";

        int choice;
        cin >> choice;
        if (choice < 0 || choice > 3) {
            cout << "无效选择!" << endl;
            return;
        }
        if (choice == 0) return;

        SoldierType type = static_cast<SoldierType>(choice - 1);
        SoldierUnit tempUnit(type);

        cout << "请输入招募数量:";
        int num;
        cin >> num;
        if (num <= 0) {
            cout << "数量必须为正数!" << endl;
            return;
        }

        int totalCost = tempUnit.cost * num;
        if (totalCost > gold) {
            cout << "金币不足!需要" << totalCost << ",当前只有" << gold << endl;
            return;
        }

        if (num > food) {
            cout << "粮食不足!无法养活这么多士兵!" << endl;
            return;
        }

        bool found = false;
        for (auto& unit : army) {
            if (unit.type == type) {
                unit.count += num;
                found = true;
                break;
            }
        }
        if (!found) {
            army.emplace_back(type, num);
        }

        gold -= totalCost;
        food -= num;

        for (auto& ach : achievements) {
            if (ach.id == "large_army") {
                ach.progress += num;
                break;
            }
        }

        cout << "招募成功!获得" << num << "名" << tempUnit.getTypeName() << endl;
        checkAchievements();
    }

    void startBattle() {
        if (getTotalArmyCount() == 0) {
            cout << "\n没有士兵,无法发起战斗!" << endl;
            return;
        }

        cout << "\n====================【出征作战】====================" << endl;
        cout << "你率领军队出征,遭遇了一支随机敌军!" << endl;

        uniform_int_distribution<int> enemyPowerDist(100, 500);
        uniform_int_distribution<int> enemyCountDist(50, 200);
        int enemyPower = enemyPowerDist(rng);
        int enemyCount = enemyCountDist(rng);

        cout << "敌军情况:" << endl;
        cout << "人数:" << enemyCount << " | 总战力:" << enemyPower << endl;
        cout << "1. 发起进攻" << endl;
        cout << "2. 撤退" << endl;
        cout << "请选择:";

        int choice;
        cin >> choice;
        if (choice != 1) {
            cout << "你选择撤退,军队安全返回。" << endl;
            return;
        }

        uniform_real_distribution<double> bonusDist(0.8, 1.2);
        double myBonus = bonusDist(rng);
        int myFinalPower = static_cast<int>(getTotalArmyPower() * myBonus);

        cout << "\n战斗开始!我方战力波动系数:" << fixed << setprecision(2) << myBonus << endl;
        cout << "我方最终战力:" << myFinalPower << " | 敌军战力:" << enemyPower << endl;

        if (myFinalPower > enemyPower) {
            cout << "\n【胜利!】你击败了敌军,获得奖励!" << endl;
            battleWins++;
            gold += 200;
            food += 500;
            territory += 5;

            for (auto& ach : achievements) {
                if (ach.id == "5_wins") {
                    ach.progress++;
                    break;
                }
            }

            cout << "获得:200金币 + 500粮食 + 5平方公里领土" << endl;
        } else {
            cout << "\n【失败!】你被敌军击败,损失惨重!" << endl;
            for (auto& unit : army) {
                int loss = static_cast<int>(unit.count * 0.3);
                unit.count -= loss;
                if (unit.count < 0) unit.count = 0;
            }
            gold -= 100;
            if (gold < 0) gold = 0;
        }

        checkAchievements();
    }

    void showAchievements() const {
        cout << "\n====================【成就系统】====================" << endl;
        int unlockedCount = 0;
        for (const auto& ach : achievements) {
            cout << "[" << (ach.unlocked ? "√" : "□") << "] " << ach.name << endl;
            cout << "  描述:" << ach.description << endl;
            if (ach.target > 0) {
                cout << "  进度:" << ach.progress << "/" << ach.target << endl;
            }
            cout << endl;
            if (ach.unlocked) unlockedCount++;
        }
        cout << "已解锁:" << unlockedCount << "/" << achievements.size() << " 个成就" << endl;
        cout << "====================================================" << endl;
    }

    void produceResources() {
        int goldGain = territory * 10;
        int foodGain = territory * 20;
        gold += goldGain;
        food += foodGain;
        cout << "\n【回合结束】领土生产:" << goldGain << "金币 + " << foodGain << "粮食" << endl;
    }
};

void showMainMenu() {
    cout << "\n====================【王国冒险主菜单】====================" << endl;
    cout << "1. 查看王国状态" << endl;
    cout << "2. 招募士兵" << endl;
    cout << "3. 发起战斗" << endl;
    cout << "4. 查看成就" << endl;
    cout << "5. 结束回合(资源生产)" << endl;
    cout << "0. 退出游戏" << endl;
    cout << "==========================================================" << endl;
    cout << "请输入你的选择:";
}

int main() {
    cout << "欢迎来到《王国霸业》文字冒险游戏!" << endl;
    cout << "请输入你的王国名称:";
    string kingdomName;
    cin >> kingdomName;
    Kingdom playerKingdom(kingdomName);

    int choice;
    while (true) {
        showMainMenu();
        cin >> choice;
        switch (choice) {
            case 0:
                cout << "感谢游玩,再见!" << endl;
                return 0;
            case 1:
                playerKingdom.showStatus();
                break;
            case 2:
                playerKingdom.recruitSoldiers();
                break;
            case 3:
                playerKingdom.startBattle();
                break;
            case 4:
                playerKingdom.showAchievements();
                break;
            case 5:
                playerKingdom.produceResources();
                break;
            default:
                cout << "无效选择,请重新输入!" << endl;
                break;
        }
    }
    return 0;
}