代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <string>
#include <iomanip>
#include <unordered_map>
using namespace std;

// ============ 兵种分类 ============
enum UnitCategory {
    INFANTRY,    // 步兵
    TANK,        // 坦克
    ARTILLERY,   // 炮兵
    FIGHTER,     // 战斗机
    BOMBER       // 轰炸机
};

enum CardType {
    UNIT,
    ORDER
};

// 战线
enum BattleZone {
    SUPPORT_LINE,
    FRONT_LINE
};

// 稀有等级
enum Rarity {
    IRON,    // 铁卡:单张卡牌本局最多抽4张
    COPPER,  // 铜卡:单张卡牌本局最多抽3张
    SILVER,  // 银卡:单张卡牌本局最多抽2张
    ELITE    // 精英:单张卡牌本局最多抽1张
};

string getRarityName(Rarity r)
{
    if(r == IRON)   return "【铁卡】";
    if(r == COPPER) return "【铜卡】";
    if(r == SILVER) return "【银卡】";
    if(r == ELITE)  return "【精英】";
    return "【未知】";
}

int getMaxDrawNum(Rarity r)
{
    if(r == IRON) return 4;
    if(r == COPPER) return 3;
    if(r == SILVER) return 2;
    if(r == ELITE) return 1;
    return 0;
}

struct Card {
    string name;
    string nation;
    CardType type;
    UnitCategory category;
    BattleZone zone;
    Rarity rarity;
    int deployCost;
    int opCost;
    int attack;
    int health;
    int maxHealth;
    string keyword;

    bool hasMoved;
    bool hasAttacked;
    bool shockUsed;
    bool hasSmoke;
    bool suppressed;
    bool inhibited;

    Card(string n, string nat, UnitCategory cat, Rarity rar, int dc, int oc, int a, int h, string kw)
        : name(n), nation(nat), type(UNIT), category(cat), zone(SUPPORT_LINE), rarity(rar),
          deployCost(dc), opCost(oc), attack(a), health(h), maxHealth(h), keyword(kw),
          hasMoved(false), hasAttacked(false), shockUsed(false), hasSmoke(false), suppressed(false), inhibited(false) {}

    Card(string n, string nat, Rarity rar, int dc, string kw)
        : name(n), nation(nat), type(ORDER), category(INFANTRY), zone(SUPPORT_LINE), rarity(rar),
          deployCost(dc), opCost(0), attack(0), health(0), maxHealth(0), keyword(kw),
          hasMoved(false), hasAttacked(false), shockUsed(false), hasSmoke(false), suppressed(false), inhibited(false) {}
};

class Player {
public:
    string name;
    int hqHP;
    int credit;
    int maxCreditSlot;

    vector<Card> deck;
    vector<Card> hand;
    vector<Card> supportLine;
    vector<Card> frontLine;

    mt19937 rng;
    unordered_map<string,int> cardDrawCount;

    Player(string n) : name(n), hqHP(20), credit(0), maxCreditSlot(0)
    {
        random_device rd;
        rng.seed(rd());
    }

    void shuffleDeck() {
        shuffle(deck.begin(), deck.end(), rng);
    }

    bool reachCardLimit(const string& cardName, Rarity rar)
    {
        int already = 0;
        if(cardDrawCount.find(cardName) != cardDrawCount.end())
            already = cardDrawCount[cardName];
        return already >= getMaxDrawNum(rar);
    }

    void addCardCount(const string& cardName)
    {
        cardDrawCount[cardName]++;
    }

    void drawCard() {
        if (deck.empty())
        {
            cout << "\n>>> " << name << "牌库已经耗尽,无法继续抽牌!\n";
            return;
        }

        if (hand.size() >= 9)
        {
            Card c = deck.back();
            deck.pop_back();
            cout << ">>> " << name << "手牌已满9张,抽到【" << c.name << "】直接销毁\n";
            return;
        }

        Card drawn = deck.back();
        deck.pop_back();

        if(drawn.type == UNIT && reachCardLimit(drawn.name, drawn.rarity))
        {
            cout << ">>> " << name << "抽到【" << drawn.name << "】" << getRarityName(drawn.rarity)
                 << ",本局该卡牌已达抽取上限,卡牌直接销毁!\n";
            return;
        }
        //指令卡同样遵守抽取上限规则
        if(drawn.type == ORDER && reachCardLimit(drawn.name, drawn.rarity))
        {
            cout << ">>> " << name << "抽到【" << drawn.name << "】" << getRarityName(drawn.rarity)
                 << ",本局该卡牌已达抽取上限,卡牌直接销毁!\n";
            return;
        }

        if(drawn.type == UNIT || drawn.type == ORDER)
            addCardCount(drawn.name);

        hand.push_back(drawn);
        cout << ">>> " << name << "抽到卡牌:【" << drawn.name << "】" << getRarityName(drawn.rarity) << "\n";
    }

    void turnStart() {
        if (maxCreditSlot < 12) maxCreditSlot++;
        credit = maxCreditSlot;
        drawCard();

        for (auto& c : supportLine) {
            if (c.keyword.find("补给") != string::npos)
                c.health = min(c.health + 1, c.maxHealth);
            c.hasMoved = false;
            c.hasAttacked = false;
            c.hasSmoke = false;
            c.suppressed = false;
            c.inhibited = false;
        }
        for (auto& c : frontLine) {
            if (c.keyword.find("补给") != string::npos)
                c.health = min(c.health + 1, c.maxHealth);
            c.hasMoved = false;
            c.hasAttacked = false;
            c.hasSmoke = false;
            c.suppressed = false;
            c.inhibited = false;
        }
    }

    bool playUnit(int idx, Player& enemy) {
        if (idx < 0 || idx >= (int)hand.size()) {
            cout << ">>> 错误:无效手牌序号!\n";
            return false;
        }
        Card c = hand[idx];
        if (c.type != UNIT) {
            cout << ">>> 错误:该卡牌是指令卡!\n";
            return false;
        }
        if (credit < c.deployCost) {
            cout << ">>> 错误:指挥点不足!\n";
            return false;
        }
        if (supportLine.size() >= 4) {
            cout << ">>> 错误:支援阵线已满4单位!\n";
            return false;
        }

        credit -= c.deployCost;
        c.zone = SUPPORT_LINE;
        if (c.keyword.find("闪击") == string::npos)
        {
            c.hasMoved = true;
            c.hasAttacked = false;
        }
        else
        {
            c.hasMoved = false;
            c.hasAttacked = false;
        }
        string deployName = c.name;
        supportLine.push_back(c);
        hand.erase(hand.begin() + idx);

        // ====== 鼠式登场特效 ======
        if(deployName == "鼠式")
        {
            cout << "\n===== 鼠式登场能力发动!=====\n";
            vector<Card> allEnemyUnits;
            for(auto &u : enemy.supportLine) allEnemyUnits.push_back(u);
            for(auto &u : enemy.frontLine) allEnemyUnits.push_back(u);

            int hitCount = allEnemyUnits.size();
            for(auto &victim : allEnemyUnits)
            {
                cout << ">>> 鼠式消灭敌方单位【" << victim.name << "】\n";
            }
            enemy.hqHP -= hitCount * 2;
            cout << ">>> 敌方总部受到 " << hitCount * 2 << " 点伤害!\n";
            enemy.supportLine.clear();
            enemy.frontLine.clear();
        }

        if(c.keyword.find("侦察") != string::npos && !deck.empty())
            drawCard();
        cout << ">>> " << name << "部署【" << deployName << "】 " << c.attack << "/" << c.health << " | " << c.keyword << "\n";
        return true;
    }

    bool castOrder(int idx, Player& self, Player& enemy) {
        if (idx < 0 || idx >= (int)hand.size()) {
            cout << ">>> 错误:无效手牌序号!\n";
            return false;
        }
        Card order = hand[idx];
        if (order.type != ORDER) {
            cout << ">>> 错误:这是作战单位!\n";
            return false;
        }
        if (credit < order.deployCost) {
            cout << ">>> 错误:指挥点不足!\n";
            return false;
        }

        credit -= order.deployCost;
        cout << ">>> " << name << "发动指令【" << order.name << "】\n";

        if (order.name == "地毯式轰炸") {
            auto dmgAll = [](vector<Card>& group) {
                for(auto& u : group)
                    u.health -= 3;
            };
            dmgAll(self.supportLine);
            dmgAll(self.frontLine);
            dmgAll(enemy.supportLine);
            dmgAll(enemy.frontLine);
            cout << ">>> 地毯式轰炸!场上所有单位受到3点伤害!\n";
            auto clear = [](vector<Card>& vec){
                vector<Card> alive;
                for(auto& c : vec) if(c.health > 0) alive.push_back(c);
                vec.swap(alive);
            };
            clear(self.supportLine);
            clear(self.frontLine);
            clear(enemy.supportLine);
            clear(enemy.frontLine);
        }
        else if (order.name == "反坦克炮击") {
            bool killed = false;
            if (!enemy.frontLine.empty()) { enemy.frontLine.erase(enemy.frontLine.begin()); killed = true; }
            else if (!enemy.supportLine.empty()) { enemy.supportLine.erase(enemy.supportLine.begin()); killed = true; }
            if (!killed) {
                cout << ">>> 敌方无单位,指令失效,返还指挥点\n";
                credit += order.deployCost;
                return false;
            }
            cout << ">>> 摧毁敌方一名作战单位。\n";
        }
        else if (order.name == "装甲补给") {
            if (self.supportLine.empty() && self.frontLine.empty()) {
                cout << ">>> 我方无单位,指令失效,返还指挥点\n";
                credit += order.deployCost;
                return false;
            }
            Card& target = (!self.frontLine.empty()) ? self.frontLine[0] : self.supportLine[0];
            target.attack += 2;
            target.health += 2;
            target.maxHealth += 2;
            cout << ">>> 目标单位+2攻击/+2生命\n";
        }
        else if (order.name == "紧急动员") {
            self.drawCard();
            self.drawCard();
        }
        else if (order.name == "空中封锁") {
            for (auto& u : enemy.supportLine) { u.hasMoved = true; u.hasAttacked = true; }
            for (auto& u : enemy.frontLine) { u.hasMoved = true; u.hasAttacked = true; }
            cout << ">>> 所有敌方本回合无法行动。\n";
        }
        else if (order.name == "战地急救") {
            self.hqHP = min(self.hqHP + 5, 30);
            cout << ">>> 总部恢复5生命。\n";
        }
        else if (order.name == "医疗纵队") {
            self.hqHP = min(self.hqHP + 4, 30);
            vector<Card*> allUnits;
            for (auto& u : self.supportLine) allUnits.push_back(&u);
            for (auto& u : self.frontLine) allUnits.push_back(&u);
            if (!allUnits.empty()) {
                uniform_int_distribution<int> dist(0, (int)allUnits.size() - 1);
                int r = dist(rng);
                allUnits[r]->health = allUnits[r]->maxHealth;
                cout << ">>> 总部+4生命,修复一名友方至满血\n";
            }
        }
        else if (order.name == "休整待命") {
            self.hqHP = min(self.hqHP + 7, 30);
            cout << ">>> 总部恢复7生命。\n";
        }
        else if (order.name == "战时生产") {
            if (self.maxCreditSlot >= 12) {
                cout << ">>> 槽位已满,指令失效,返还指挥点\n";
                credit += order.deployCost;
                return false;
            }
            self.maxCreditSlot += 1;
            self.credit += 2;
            cout << ">>> 上限+1,获得2指挥点\n";
        }
        else if (order.name == "北方的铁矿") {
            if (self.frontLine.empty())
            {
                cout << ">>> 前线无单位,指令失效,返还指挥点\n";
                credit += order.deployCost;
                return false;
            }
            self.credit += 3;
            cout << ">>> 前线存在单位,获得3指挥点\n";
        }
        //=====新增美国经济指令=====
        else if(order.name == "战争机器")
        {
            self.maxCreditSlot += 1;
            cout << ">>> 指挥点槽位+1(无视12上限)\n";
        }
        else if(order.name == "战争需要")
        {
            self.maxCreditSlot += 2;
            cout << ">>> 指挥点槽位+2(无视12上限)\n";
        }
        else if(order.name == "战争债券")
        {
            self.maxCreditSlot += 2;
            if(!self.deck.empty()) self.drawCard();
            cout << ">>> 指挥点槽位+2(无视12上限),抽取一张卡牌\n";
        }
        else if (order.name == "军备研发") {
            cout << "\n【军备研发 · 三选一】\n1.德军步兵  2.美军步枪兵  3.轻型轰炸机\n选择:";
            int sel; cin >> sel;
            if (sel == 1)
                self.hand.emplace_back("德军步兵","德国", INFANTRY, IRON, 1, 1, 1, 2, "无词条");
            else if (sel == 2)
                self.hand.emplace_back("美军步枪兵","美国", INFANTRY, COPPER, 1, 1, 1, 3, "补给");
            else
                self.hand.emplace_back("轻型轰炸机","美国", BOMBER, COPPER, 3, 1, 2, 2, "远程");
            cout << ">>> 研发完成加入手牌(研发单位不计入本局抽取上限)\n";
        }
        else if (order.name == "重型装备开发") {
            cout << "\n【重型装备开发 · 三选一】\n1.四号坦克  2.T-34坦克  3.喷火战斗机\n选择:";
            int sel; cin >> sel;
            if (sel == 1)
                self.hand.emplace_back("四号坦克","德国", TANK, SILVER, 4, 1, 4, 4, "重甲");
            else if (sel == 2)
                self.hand.emplace_back("T-34坦克","苏联", TANK, SILVER, 4, 1, 3, 5, "闪击");
            else
                self.hand.emplace_back("喷火战斗机","英国", FIGHTER, SILVER, 4, 1, 4, 2, "远程,制空");
            cout << ">>> 研发完成加入手牌(研发单位不计入本局抽取上限)\n";
        }

        hand.erase(hand.begin() + idx);
        return true;
    }

    bool advanceToFront(int unitIdx, Player& enemy) {
        if (unitIdx < 0 || unitIdx >= (int)supportLine.size()) {
            cout << ">>> 错误:单位序号无效\n";
            return false;
        }
        Card& u = supportLine[unitIdx];
        if (u.hasMoved) {
            cout << ">>> 该单位本回合已移动!\n";
            return false;
        }
        if(u.suppressed)
        {
            cout << ">>> 单位受到【压制】效果,本回合无法移动!\n";
            return false;
        }
        if (credit < u.opCost) {
            cout << ">>> 指挥点不足\n";
            return false;
        }
        if (frontLine.size() >= 5) {
            cout << ">>> 前线已满\n";
            return false;
        }
        if (!enemy.frontLine.empty()) {
            cout << ">>> 敌方占据前线,无法推进!\n";
            return false;
        }

        credit -= u.opCost;
        u.hasMoved = true;
        u.zone = FRONT_LINE;
        frontLine.push_back(u);
        supportLine.erase(supportLine.begin() + unitIdx);
        cout << ">>> " << u.name << "推进占领前线\n";
        return true;
    }

    bool attackHQ(int zoneSel, int unitIdx, Player& enemy) {
        Card* attacker = nullptr;
        if (zoneSel == 1) {
            if (unitIdx < 0 || unitIdx >= (int)supportLine.size()) return false;
            attacker = &supportLine[unitIdx];
        } else {
            if (unitIdx < 0 || unitIdx >= (int)frontLine.size()) return false;
            attacker = &frontLine[unitIdx];
        }
        Card& atk = *attacker;

        if (atk.hasAttacked) { cout << ">>> 单位本回合已进攻!\n"; return false; }
        if (atk.category == INFANTRY && atk.hasMoved) { cout << ">>> 步兵移动后无法进攻!\n"; return false; }
        if(atk.suppressed)
        {
            cout << ">>> 单位受到【压制】,无法发起进攻!\n";
            return false;
        }
        if (credit < atk.opCost) { cout << ">>> 指挥点不足\n"; return false; }
        if(atk.hasSmoke)
        {
            cout << ">>> 目标带有【烟幕】,无法选中!\n";
            return false;
        }

        bool canReachHQ = (atk.category == ARTILLERY || atk.category == BOMBER || atk.category == FIGHTER)
            || (atk.zone == FRONT_LINE);
        if (!canReachHQ) {
            cout << ">>> 步兵/坦克必须在前线才能攻击总部!\n";
            return false;
        }

        if(atk.category == BOMBER)
        {
            bool enemyHasFighter = false;
            for(auto &u : enemy.supportLine)
                if(u.category == FIGHTER) { enemyHasFighter = true; break; }
            if(enemyHasFighter)
            {
                cout << ">>> 敌方支援阵线存在战斗机,轰炸机禁止直接轰炸总部!\n";
                return false;
            }
        }

        credit -= atk.opCost;
        atk.hasAttacked = true;
        int damage = atk.attack;
        if(atk.inhibited) damage = max(0, damage - 2);
        enemy.hqHP -= damage;
        cout << ">>> " << atk.name << "攻击敌方总部,造成" << damage << "伤害!敌方剩余HP:" << enemy.hqHP << "\n";
        return true;
    }

    bool engageUnit(int myZone, int myIdx, int enemyZone, int enemyIdx, Player& enemy) {
        Card* attacker = nullptr;
        if (myZone == 1) {
            if (myIdx < 0 || myIdx >= (int)supportLine.size()) return false;
            attacker = &supportLine[myIdx];
        } else {
            if (myIdx < 0 || myIdx >= (int)frontLine.size()) return false;
            attacker = &frontLine[myIdx];
        }
        Card& atk = *attacker;

        Card* defender = nullptr;
        if (enemyZone == 1) {
            if (enemyIdx < 0 || enemyIdx >= (int)enemy.supportLine.size()) return false;
            defender = &enemy.supportLine[enemyIdx];
        } else {
            if (enemyIdx < 0 || enemyIdx >= (int)enemy.frontLine.size()) return false;
            defender = &enemy.frontLine[enemyIdx];
        }
        Card& def = *defender;

        if (atk.hasAttacked) { cout << ">>> 单位本回合已进攻!\n"; return false; }
        if (atk.category == INFANTRY && atk.hasMoved) { cout << ">>> 步兵移动后不能进攻!\n"; return false; }
        if(atk.suppressed)
        {
            cout << ">>> 单位受到【压制】,无法发起进攻!\n";
            return false;
        }
        if(def.hasSmoke)
        {
            cout << ">>> 目标带有【烟幕】,无法选中!\n";
            return false;
        }
        if (credit < atk.opCost) { cout << ">>> 指挥点不足\n"; return false; }

        if(atk.category == BOMBER)
        {
            bool enemyHasSupportFighter = false;
            for(auto &u : enemy.supportLine)
                if(u.category == FIGHTER) { enemyHasSupportFighter = true; break; }
            if(enemyHasSupportFighter && !(enemyZone == 1 && def.category == FIGHTER))
            {
                cout << ">>> 敌方支援有战斗机,轰炸机只能攻击敌方支援阵线战斗机!\n";
                return false;
            }
        }

        credit -= atk.opCost;
        atk.hasAttacked = true;
        cout << ">>> " << atk.name << " 交战 " << def.name << "\n";

        int dmg = atk.attack;
        if(atk.inhibited) dmg = max(0, dmg - 2);
        if(atk.keyword.find("冲击") != string::npos && !atk.shockUsed)
        {
            dmg += 2;
            atk.shockUsed = true;
        }
        if ((atk.keyword.find("穿甲") != string::npos) && def.category == TANK)
            dmg *= 2;
        if(atk.keyword.find("制空") != string::npos && (def.category == BOMBER || def.category == FIGHTER))
            dmg += 3;
        if (def.keyword.find("重甲") != string::npos)
            dmg = max(1, dmg - 1);

        def.health -= dmg;

        int counterDmg = 0;
        if (!(atk.category == ARTILLERY || atk.category == BOMBER))
        {
            if(def.keyword.find("伏击") != string::npos)
            {
                counterDmg = def.attack;
                if (atk.keyword.find("重甲") != string::npos)
                    counterDmg = max(1, counterDmg - 1);
                atk.health -= counterDmg;
                counterDmg = 0;
            }
            else
            {
                counterDmg = def.attack;
                if (atk.keyword.find("重甲") != string::npos)
                    counterDmg = max(1, counterDmg - 1);
            }
        }
        atk.health -= counterDmg;

        if (def.health <= 0 && def.keyword.find("坚守") != string::npos) def.health = 1;
        if (atk.health <= 0 && atk.keyword.find("坚守") != string::npos) atk.health = 1;

        auto clearDead = [](vector<Card>& zone) {
            vector<Card> alive;
            for (auto& c : zone) if (c.health > 0) alive.push_back(c);
            zone.swap(alive);
        };
        clearDead(supportLine);
        clearDead(frontLine);
        clearDead(enemy.supportLine);
        clearDead(enemy.frontLine);
        return true;
    }

    void showStatusHeader()
    {
        cout << "\n============================================================\n";
        cout << "                    【" << name << " 回合信息】\n";
        cout << " 指挥点:" << credit << "/" << maxCreditSlot << " | 总部生命值:" << hqHP << "\n";
        cout << " 规则:同名称单位/指令卡本局抽取有上限;战时生产最高12槽,部分美国指令可突破上限\n";
        cout << "============================================================\n";
    }

    void showSupportLine() {
        cout << "\n【支援阵线】(上限4单位)\n";
        if (supportLine.empty()) {
            cout << "   暂无单位\n";
            return;
        }
        for (int i = 0; i < (int)supportLine.size(); i++) {
            auto& u = supportLine[i];
            cout << "  " << i+1 << ". " << u.name << getRarityName(u.rarity) << "[" << u.nation << "]"
                 << " 攻:" << u.attack << " 血:" << u.health << "/" << u.maxHealth << " 行动消耗:" << u.opCost;
            vector<string> tag;
            if(u.hasMoved) tag.push_back("已移动");
            if(u.hasAttacked) tag.push_back("已进攻");
            if(u.suppressed) tag.push_back("压制");
            if(u.inhibited) tag.push_back("抑制");
            if(u.hasSmoke) tag.push_back("烟幕");
            if(!tag.empty()){
                cout << " 【";
                for(size_t t=0;t<tag.size();t++){
                    if(t>0) cout << ",";
                    cout << tag[t];
                }
                cout << "】";
            }
            cout << " | 词条:" << u.keyword << "\n";
        }
    }
    void showFrontLine() {
        cout << "\n【前线阵地】(上限5单位)\n";
        if (frontLine.empty()) {
            cout << "   暂无单位\n";
            return;
        }
        for (int i = 0; i < (int)frontLine.size(); i++) {
            auto& u = frontLine[i];
            cout << "  " << i+1 << ". " << u.name << getRarityName(u.rarity) << "[" << u.nation << "]"
                 << " 攻:" << u.attack << " 血:" << u.health << "/" << u.maxHealth << " 行动消耗:" << u.opCost;
            vector<string> tag;
            if(u.hasMoved) tag.push_back("已移动");
            if(u.hasAttacked) tag.push_back("已进攻");
            if(u.suppressed) tag.push_back("压制");
            if(u.inhibited) tag.push_back("抑制");
            if(u.hasSmoke) tag.push_back("烟幕");
            if(!tag.empty()){
                cout << " 【";
                for(size_t t=0;t<tag.size();t++){
                    if(t>0) cout << ",";
                    cout << tag[t];
                }
                cout << "】";
            }
            cout << " | 词条:" << u.keyword << "\n";
        }
    }
    void showHand() {
        cout << "\n【手牌】上限9张\n";
        if (hand.empty()) {
            cout << "   暂无手牌\n";
            return;
        }
        for (int i = 0; i < (int)hand.size(); i++) {
            auto& c = hand[i];
            cout << "  " << i+1 << ". " << c.name << getRarityName(c.rarity) << "[" << c.nation << "]"
                 << " 部署费用:" << c.deployCost;
            if(c.type == UNIT)
                cout << " 攻:" << c.attack << " 血:" << c.health;
            else
                cout << " 【指令卡】";
            cout << " | " << c.keyword << "\n";
        }
    }
};

bool findMaxThreatTarget(Player& enemy, int &zoneOut, int &idxOut)
{
    int scoreMax = -1;
    zoneOut = 1; idxOut = 0;
    for(int i=0; i<(int)enemy.supportLine.size();i++)
    {
        auto &u = enemy.supportLine[i];
        int s = u.attack;
        if(u.category == ARTILLERY || u.category == BOMBER || u.category == FIGHTER) s += 6;
        if(s > scoreMax) { scoreMax = s; zoneOut = 1; idxOut = i; }
    }
    for(int i=0; i<(int)enemy.frontLine.size();i++)
    {
        auto &u = enemy.frontLine[i];
        int s = u.attack;
        if(u.category == ARTILLERY || u.category == BOMBER || u.category == FIGHTER) s += 6;
        if(s > scoreMax) { scoreMax = s; zoneOut = 2; idxOut = i; }
    }
    return scoreMax != -1;
}

bool findEnemySupportFighter(Player& enemy, int &idxOut)
{
    for(int i=0; i<(int)enemy.supportLine.size();i++)
    {
        if(enemy.supportLine[i].category == FIGHTER)
        {
            idxOut = i;
            return true;
        }
    }
    return false;
}

void aiTurnAction(Player &ai, Player &player)
{
    const int RESERVE_POINT = 2;
    vector<int> orderList;
    for(int i=0;i<(int)ai.hand.size();i++)
    {
        auto &c = ai.hand[i];
        if(c.type == ORDER && ai.credit >= c.deployCost + RESERVE_POINT)
            orderList.push_back(i);
    }

    // 指令优先级,新增三张经济指令加入序列
    vector<string> priorityOrder = {
        "空中封锁",
        "反坦克炮击",
        "地毯式轰炸",
        "紧急动员",
        "战争债券",
        "战争需要",
        "战时生产",
        "战争机器",
        "装甲补给",
        "休整待命",
        "医疗纵队",
        "战地急救",
        "北方的铁矿"
    };

    bool usedOrder = false;
    for(auto &want : priorityOrder)
    {
        for(int idx : orderList)
        {
            if(ai.hand[idx].name == want)
            {
                if(want == "北方的铁矿")
                {
                    bool frontHasUnit = !ai.frontLine.empty();
                    if(!frontHasUnit || ai.credit > 3)
                        continue;
                }
                if((want == "战地急救" || want == "休整待命" || want == "医疗纵队") && ai.hqHP > 12)
                    continue;
                if(want == "装甲补给" && ai.supportLine.empty() && ai.frontLine.empty())
                    continue;

                ai.castOrder(idx, ai, player);
                usedOrder = true;
                break;
            }
        }
        if(usedOrder) break;
    }

    bool deployed;
    do{
        deployed = false;
        int pick = -1;
        int minCost = 99;
        for(int i=0;i<(int)ai.hand.size();i++)
        {
            auto &c = ai.hand[i];
            if(c.type == UNIT && ai.supportLine.size() < 4 && ai.credit >= c.deployCost + RESERVE_POINT)
            {
                if(c.deployCost < minCost)
                {
                    minCost = c.deployCost;
                    pick = i;
                }
            }
        }
        if(pick != -1)
        {
            ai.playUnit(pick, player);
            deployed = true;
        }
    }while(deployed);

    for(int i=0;i<(int)ai.supportLine.size();i++)
    {
        auto &u = ai.supportLine[i];
        if(!u.hasMoved && !u.suppressed && ai.credit >= u.opCost + RESERVE_POINT
            && ai.frontLine.empty() && player.frontLine.empty())
        {
            ai.advanceToFront(i, player);
            break;
        }
    }

    for(int zoneType : {1,2})
    {
        vector<Card> &group = (zoneType == 1) ? ai.supportLine : ai.frontLine;
        for(int i=0;i<(int)group.size();i++)
        {
            auto &u = group[i];
            if(u.category == BOMBER && !u.hasAttacked && !u.suppressed && ai.credit >= u.opCost + RESERVE_POINT)
            {
                int fighterIdx;
                if(findEnemySupportFighter(player, fighterIdx))
                {
                    ai.engageUnit(zoneType, i, 1, fighterIdx, player);
                    return;
                }
            }
        }
    }

    int totalFrontDmg = 0;
    for(auto &u : ai.frontLine) totalFrontDmg += u.attack;
    bool canKillEnemyHQ = (totalFrontDmg >= player.hqHP);
    if(canKillEnemyHQ)
    {
        for(int i=0;i<(int)ai.frontLine.size();i++)
        {
            if(!ai.frontLine[i].hasAttacked && !ai.frontLine[i].suppressed && ai.credit >= ai.frontLine[i].opCost)
            {
                ai.attackHQ(2,i,player);
            }
        }
        return;
    }

    int enemyZone, enemyIdx;
    if(findMaxThreatTarget(player, enemyZone, enemyIdx))
    {
        for(int i=0;i<(int)ai.frontLine.size();i++)
        {
            if(!ai.frontLine[i].hasAttacked && !ai.frontLine[i].suppressed && ai.credit >= ai.frontLine[i].opCost + RESERVE_POINT)
            {
                ai.engageUnit(2,i,enemyZone,enemyIdx,player);
                return;
            }
        }
        for(int i=0;i<(int)ai.supportLine.size();i++)
        {
            auto &u = ai.supportLine[i];
            if((u.category == ARTILLERY || u.category == BOMBER || u.category == FIGHTER)
                && !u.hasAttacked && !u.suppressed && ai.credit >= u.opCost + RESERVE_POINT)
            {
                ai.engageUnit(1,i,enemyZone,enemyIdx,player);
                return;
            }
        }
    }

    bool enemyHasUnit = (!player.supportLine.empty() || !player.frontLine.empty());
    if(!enemyHasUnit)
    {
        for(int i=0;i<(int)ai.frontLine.size();i++)
        {
            if(!ai.frontLine[i].hasAttacked && !ai.frontLine[i].suppressed && ai.credit >= ai.frontLine[i].opCost)
            {
                ai.attackHQ(2,i,player);
            }
        }
    }
}

void initFullDeck(Player& p)
{
    // ============ 铁卡 IRON【新增多张1费卡】 ============
    //德国
    p.deck.emplace_back("德军步兵","德国", INFANTRY, IRON, 1, 1, 1, 2, "无词条");
    p.deck.emplace_back("侦察装甲车","德国", TANK, IRON, 2, 1, 2, 2, "侦察");
    p.deck.emplace_back("德军传令兵","德国", INFANTRY, IRON, 1, 1, 1, 1, "侦察");
    //苏联
    p.deck.emplace_back("苏联第1088兵团","苏联", INFANTRY, IRON, 0, 0, 1, 1, "闪击");
    p.deck.emplace_back("红军步兵","苏联", INFANTRY, IRON, 1, 1, 2, 1, "冲击");
    p.deck.emplace_back("民兵游击队","苏联", INFANTRY, IRON, 1, 1, 1, 2, "伏击");
    //美国
    p.deck.emplace_back("国民警卫队","美国", INFANTRY, IRON, 1, 1, 1, 2, "伏击");
    p.deck.emplace_back("美军传令兵","美国", INFANTRY, IRON, 1, 1, 1, 1, "侦察");
    //英国
    p.deck.emplace_back("本土民兵","英国", INFANTRY, IRON, 1, 1, 1, 2, "守护");
    p.deck.emplace_back("皇家斥候","英国", INFANTRY, IRON, 1, 1, 1, 1, "侦察");

    // ============ 铜卡 COPPER ============
    //德国
    p.deck.emplace_back("风暴突击兵","德国", INFANTRY, COPPER, 2, 1, 2, 3, "闪击");
    p.deck.emplace_back("玛蒂尔达坦克","德国", TANK, COPPER, 3, 1, 2, 5, "重甲");
    p.deck.emplace_back("88毫米高炮","德国", ARTILLERY, COPPER, 3, 1, 3, 2, "远程,制空");
    //苏联
    p.deck.emplace_back("工兵小队","苏联", INFANTRY, COPPER, 2, 1, 1, 4, "守护");
    p.deck.emplace_back("反坦克步兵","苏联", INFANTRY, COPPER, 2, 1, 3, 1, "穿甲");
    //美国
    p.deck.emplace_back("美军步枪兵","美国", INFANTRY, COPPER, 1, 1, 1, 3, "补给");
    p.deck.emplace_back("轻型轰炸机","美国", BOMBER, COPPER, 3, 1, 2, 2, "远程");
    //英国
    p.deck.emplace_back("英军步兵","英国", INFANTRY, COPPER, 2, 1, 2, 2, "压制");
    p.deck.emplace_back("25磅野战炮","英国", ARTILLERY, COPPER, 3, 1, 3, 3, "远程");

    // ============ 银卡 SILVER ============
    //德国
    p.deck.emplace_back("四号坦克","德国", TANK, SILVER, 4, 1, 4, 4, "重甲");
    p.deck.emplace_back("斯图卡俯冲轰炸机","德国", BOMBER, SILVER, 5, 1, 4, 3, "远程,冲击");
    //苏联
    p.deck.emplace_back("近卫步兵","苏联", INFANTRY, SILVER, 3, 1, 3, 3, "坚守");
    p.deck.emplace_back("T-34坦克","苏联", TANK, SILVER, 4, 1, 3, 5, "闪击");
    p.deck.emplace_back("伊尔-2攻击机","苏联", BOMBER, SILVER, 4, 1, 3, 4, "远程,穿甲");
    //美国
    p.deck.emplace_back("游骑兵","美国", INFANTRY, SILVER, 3, 1, 4, 2, "伏击");
    p.deck.emplace_back("谢尔曼坦克","美国", TANK, SILVER, 4, 1, 4, 3, "冲击");
    p.deck.emplace_back("105毫米榴弹炮","美国", ARTILLERY, SILVER, 4, 1, 4, 3, "远程,抑制");
    //英国
    p.deck.emplace_back("苏格兰高地兵","英国", INFANTRY, SILVER, 3, 1, 3, 3, "冲击");
    p.deck.emplace_back("喷火战斗机","英国", FIGHTER, SILVER, 4, 1, 4, 2, "远程,制空");
    p.deck.emplace_back("丘吉尔坦克","英国", TANK, SILVER, 5, 2, 3, 7, "重甲,守护");

    // ============ 精英 ELITE ============
    //德国
    p.deck.emplace_back("虎式坦克H1型","德国", TANK, ELITE, 8, 4, 7, 7, "重甲,冲击");
    p.deck.emplace_back("鼠式","德国", TANK, ELITE, 12, 4, 12, 10, "重甲3,守护");
    //苏联
    p.deck.emplace_back("KV-1重型坦克","苏联", TANK, ELITE, 6, 2, 4, 8, "重甲,守护");
    p.deck.emplace_back("喀秋莎火箭炮","苏联", ARTILLERY, ELITE, 5, 2, 5, 2, "远程,压制");
    p.deck.emplace_back("IS-2重型坦克","苏联", TANK, ELITE, 8, 3, 8, 6, "重甲,穿甲");
    //美国
    p.deck.emplace_back("潘兴重型坦克","美国", TANK, ELITE, 6, 2, 5, 6, "重甲,穿甲");
    p.deck.emplace_back("兰卡斯特","美国", FIGHTER, ELITE,8 , 3, 7, 3, "远程,制空,闪击");
    p.deck.emplace_back("B29超级空中堡垒","美国", BOMBER, ELITE,9,4,8,4,"远程");
    //英国
    p.deck.emplace_back("彗星坦克","英国", TANK, ELITE,7,2,6,5,"冲击,重甲");

    //====================指令卡====================
    //铁卡指令
    p.deck.emplace_back("北方的铁矿","苏联", IRON, 1, "若友方前线存在单位,立即获得3点指挥点");
    p.deck.emplace_back("紧急动员","美国", IRON, 2, "抽取两张卡牌");
    p.deck.emplace_back("反坦克炮击","英国", IRON, 2, "消灭一名敌方作战单位");
    //新增美国铁卡指令:战争机器
    p.deck.emplace_back("战争机器","美国", IRON, 2, "增加1个指挥点槽(无视上限)");
    //铜卡指令
    p.deck.emplace_back("战地急救","英国", COPPER, 3, "我方总部恢复5点生命值");
    p.deck.emplace_back("医疗纵队","苏联", COPPER, 3, "总部+4血,修复一名友方至满血");
    p.deck.emplace_back("装甲补给","德国", COPPER, 3, "一个友方单位获得+2攻击/+2生命");
    p.deck.emplace_back("军备研发","美国", COPPER, 3, "三选一研发轻型单位加入手牌");
    //新增美国铜卡指令:战争债券
    p.deck.emplace_back("战争债券","美国", COPPER, 5, "增加两个指挥点槽(无视上限)并抽一张卡");
    //银卡指令
    p.deck.emplace_back("战时生产","德国", SILVER, 4, "指挥槽上限+1,获得2指挥点(最高12槽)");
    p.deck.emplace_back("地毯式轰炸","美国", SILVER, 4, "对场上所有单位造成3点伤害");
    p.deck.emplace_back("空中封锁","英国", SILVER, 4, "所有敌方单位本回合无法行动");
    p.deck.emplace_back("休整待命","苏联", SILVER, 4, "我方总部恢复7点生命值");
    //新增美国银卡指令:战争需要
    p.deck.emplace_back("战争需要","美国", SILVER, 4, "增加2个指挥点槽(无视上限)");
    //精英指令
    p.deck.emplace_back("重型装备开发","德国", ELITE, 5, "三选一研发重型单位加入手牌");

    p.shuffleDeck();
}

int main()
{
    Player player("玩家");
    Player ai("AI对手");
    initFullDeck(player);
    initFullDeck(ai);

    for (int i = 0; i < 3; i++) {
        player.drawCard();
        ai.drawCard();
    }

    bool isPlayerTurn = true;
    while (player.hqHP > 0 && ai.hqHP > 0)
    {
        system("cls");
        if (isPlayerTurn)
        {
            player.turnStart();
            while(true)
            {
                player.showStatusHeader();
                cout << "【?? AI对手阵地信息】\n";
                ai.showSupportLine();
                ai.showFrontLine();
                cout << "\n----------------------------------------\n";
                cout << "【?? 我方阵地信息】\n";
                player.showSupportLine();
                player.showFrontLine();
                player.showHand();
                cout << "\n========== 操作菜单 ==========\n";
                cout << "1 部署单位  |  2 使用指令\n";
                cout << "3 单位推进前线 | 4 攻击敌方总部\n";
                cout << "5 交战敌方单位 | 6 结束回合\n";
                cout << "请输入操作编号:";
                int op;
                cin >> op;
                if(op == 1){
                    int id;cout<<"手牌序号:";cin>>id;player.playUnit(id-1, ai);
                }else if(op == 2){
                    int id;cout<<"手牌序号:";cin>>id;player.castOrder(id-1,player,ai);
                }else if(op == 3){
                    int id;cout<<"支援阵线单位序号:";cin>>id;player.advanceToFront(id-1,ai);
                }else if(op == 4){
                    int z,idx;cout<<"战线(1支援/2前线):";cin>>z;cout<<"单位序号:";cin>>idx;player.attackHQ(z,idx-1,ai);
                }else if(op == 5){
                    int myZ,myI,eZ,eI;
                    cout<<"我方战线(1支援/2前线):";cin>>myZ;
                    cout<<"我方单位序号:";cin>>myI;
                    cout<<"敌方战线(1/2):";cin>>eZ;
                    cout<<"敌方单位序号:";cin>>eI;
                    player.engageUnit(myZ,myI-1,eZ,eI-1,ai);
                }else if(op == 6){
                    cout<<"回合结束\n";break;
                }else{
                    cout<<"无效指令\n";
                }
                cout<<"\n按下回车键继续...";
                cin.ignore();cin.get();
                system("cls");
            }
        }
        else
        {
            ai.turnStart();
            cout << "\n================ ?? AI对手回合 ================\n";
            aiTurnAction(ai, player);
            cout << "\nAI行动完毕,按下回车键切换玩家回合...";
            cin.ignore();cin.get();
        }
        isPlayerTurn = !isPlayerTurn;
    }

    if(player.hqHP <= 0)
        cout << "\n==================== 游戏结束 ====================\n【战败】我方总部被摧毁!\n";
    else
        cout << "\n==================== 游戏结束 ====================\n【胜利】敌方总部被摧毁!\n";
    return 0;
}