#include <iostream>
#include <vector>
#include <conio.h>      // For _getch()
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <string>

// --------------------
// 前置声明
// --------------------
struct Entity;
struct Pickup;
struct Weapon;
struct DestructibleObstacle;
void playCampaign(int campaign);  // 战役 1-4(地图模式)
void playCampaign5();             // 战役 5(Panther 坦克模式)

// --------------------
// 数据结构(公共部分)
// --------------------
struct Entity {
    int x, y;
    int health;
    char symbol;
};

struct Pickup {
    int x, y;
    char symbol;
    int value; // 例如:生命回复
};

struct Weapon {
    std::string name;
    int range;     // 有效射程(以网格为单位)
    int ammo;      // 当前弹夹中的子弹数量
    int clipSize;  // 弹夹容量
};

struct DestructibleObstacle {
    int x, y;
    int health;
    char symbol;
};

int score = 0;

// --------------------
// 工具函数
// --------------------

// A simple round-to-int helper (only for nonnegative numbers)
int roundToInt(float value) {
    return static_cast<int>(value + 0.5f);
}

float degToRad(float deg) {
    return deg * M_PI / 180.0f;
}

float angleDiff(float a, float b) {
    float diff = std::fabs(a - b);
    return diff > 180 ? 360 - diff : diff;
}

void displayHealthBar(const std::string &name, int health, int maxHealth) {
    int barWidth = 20;
    int pos = (health * barWidth) / maxHealth;
    std::cout << name << " 生命: [";
    for (int i = 0; i < barWidth; i++) {
        std::cout << (i < pos ? "#" : "-");
    }
    std::cout << "] " << health << "/" << maxHealth << std::endl;
}

// --------------------
// C++98–compatible search helper functions
// --------------------
int findEntityAt(const std::vector<Entity>& vec, int x, int y) {
    for (size_t i = 0; i < vec.size(); i++) {
        if (vec[i].x == x && vec[i].y == y)
            return static_cast<int>(i);
    }
    return -1;
}

int findPickupAt(const std::vector<Pickup>& vec, int x, int y) {
    for (size_t i = 0; i < vec.size(); i++) {
        if (vec[i].x == x && vec[i].y == y)
            return static_cast<int>(i);
    }
    return -1;
}

int findObstacleAt(const std::vector<DestructibleObstacle>& vec, int x, int y) {
    for (size_t i = 0; i < vec.size(); i++) {
        if (vec[i].x == x && vec[i].y == y)
            return static_cast<int>(i);
    }
    return -1;
}

// --------------------
// 战斗遭遇系统(用于战役 1-3)
// --------------------
bool battleEncounter(const std::string &battleName, int &playerHealth, int maxPlayerHealth, int enemyHealth) {
    std::cout << "\n=== 战斗: " << battleName << " ===\n";
    while (playerHealth > 0 && enemyHealth > 0) {
        displayHealthBar("玩家", playerHealth, maxPlayerHealth);
        std::cout << "敌人生命值: " << enemyHealth << std::endl;
        std::cout << "按 's' 射击: ";
        char action = _getch();
        if (action == 's' || action == 'S') {
            int damage = 10 + rand() % 51;  // 10~60
            std::cout << "\n你射击敌人,造成 " << damage << " 点伤害!\n";
            enemyHealth -= damage;
            if (enemyHealth <= 0) {
                std::cout << "敌人被击败!\n";
                break;
            }
        } else {
            std::cout << "\n输入错误,失去射击机会!\n";
        }
        int enemyDamage = 10 + rand() % 6;  // 10~15
        std::cout << "敌人反击,造成 " << enemyDamage << " 点伤害!\n";
        playerHealth -= enemyDamage;
        if (playerHealth <= 0) {
            std::cout << "在战斗 " << battleName << " 中你被击败了!\n";
            return false;
        }
    }
    return true;
}

bool battleBunker(Entity &bunker, int &playerHealth) {
    int bunkerMaxHealth = bunker.health;
    std::cout << "\n开始进攻掩体 (坐标: " << bunker.x << "," << bunker.y << "),掩体生命值: " << bunker.health << "\n";
    while (bunker.health > 0 && playerHealth > 0) {
        displayHealthBar("玩家", playerHealth, 150);
        displayHealthBar("掩体", bunker.health, bunkerMaxHealth);
        std::cout << "按 's' 射击掩体: ";
        char action = _getch();
        if (action == 's' || action == 'S') {
            int damage = 10 + rand() % 51;
            std::cout << "\n你射击掩体,造成 " << damage << " 点伤害!\n";
            bunker.health -= damage;
            if (bunker.health <= 0) {
                std::cout << "掩体被摧毁并占领!\n";
                return true;
            }
        } else {
            std::cout << "\n输入错误,失去射击机会!\n";
        }
        int turretDamage = 5 + rand() % 6;  // 5~10
        std::cout << "掩体炮塔开火,造成 " << turretDamage << " 点伤害!\n";
        playerHealth -= turretDamage;
        if (playerHealth <= 0) {
            std::cout << "你被掩体防御击杀了!\n";
            return false;
        }
    }
    return true;
}

// --------------------
// 地图显示(战役 1-4)
// --------------------
void render(const std::vector<std::vector<char>> &baseMap, 
            const Entity &player, 
            const std::vector<Entity> &enemies,
            const std::vector<Pickup> &pickups,
            const std::vector<Entity> &bunkers,
            const Weapon &weapon) {
    system("cls");
    std::vector<std::vector<char>> displayMap = baseMap;
    for (size_t i = 0; i < pickups.size(); i++) {
        displayMap[pickups[i].y][pickups[i].x] = pickups[i].symbol;
    }
    for (size_t i = 0; i < bunkers.size(); i++) {
        displayMap[bunkers[i].y][bunkers[i].x] = bunkers[i].symbol;
    }
    for (size_t i = 0; i < enemies.size(); i++) {
        displayMap[enemies[i].y][enemies[i].x] = enemies[i].symbol;
    }
    displayMap[player.y][player.x] = player.symbol;
    for (size_t i = 0; i < displayMap.size(); i++) {
        for (size_t j = 0; j < displayMap[i].size(); j++) {
            std::cout << displayMap[i][j] << ' ';
        }
        std::cout << std::endl;
    }
    std::cout << "玩家生命值: " << player.health;
    if (player.health < 30)
        std::cout << "  [警告: 生命值过低]";
    std::cout << "\n得分: " << score;
    std::cout << "\n武器: " << weapon.name << " | 子弹: " << weapon.ammo << "/" << weapon.clipSize << std::endl;
    std::cout << "\n操作提示:\n  移动: w/a/s/d 及对角 (q, e, z, c)\n  射击: i/j/k/l (上/左/下/右)\n  手雷: g   装弹: r" << std::endl;
}

void addObstacles(std::vector<std::vector<char>> &baseMap, int count) {
    int height = baseMap.size();
    int width = baseMap[0].size();
    int placed = 0;
    while (placed < count) {
        int x = rand() % width;
        int y = rand() % height;
        if (baseMap[y][x] == '.') {
            baseMap[y][x] = '#';
            placed++;
        }
    }
}

// --------------------
// 辅助函数:根据坦克角度返回显示字符
// --------------------
char getTankSymbol(float angle) {
    angle = fmod(angle, 360.0f);
    if (angle < 0)
        angle += 360.0f;
    if (angle < 45 || angle >= 315)
        return '>';
    else if (angle < 135)
        return '^';
    else if (angle < 225)
        return '<';
    else
        return 'v';
}

// --------------------
// 战役 5:德国亚丁攻势(Panther 坦克突击)
// --------------------
struct Tank {
    float x, y;
    float angle;  // 0 表示向右,逆时针增加
    float speed;
    int health;
};

void addObstaclesDestructible(std::vector<std::vector<char>> &grid, std::vector<DestructibleObstacle> &obs, int count) {
    int height = grid.size();
    int width = grid[0].size();
    int placed = 0;
    while (placed < count) {
        int x = rand() % width;
        int y = rand() % height;
        if (grid[y][x] == '.') {
            grid[y][x] = '#';
            obs.push_back(DestructibleObstacle());
            obs.back().x = x;
            obs.back().y = y;
            obs.back().health = 100;
            obs.back().symbol = '#';
            placed++;
        }
    }
}

void renderCampaign5Grid(const int MAP_WIDTH, const int MAP_HEIGHT,
                         const Tank &playerTank, const std::vector<DestructibleObstacle> &obs,
                         const std::vector<Entity> &enemies, const std::vector<Entity> &crew) {
    std::vector<std::vector<char>> grid(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
    for (size_t i = 0; i < obs.size(); i++) {
        grid[obs[i].y][obs[i].x] = obs[i].symbol;
    }
    for (size_t i = 0; i < enemies.size(); i++) {
        grid[enemies[i].y][enemies[i].x] = enemies[i].symbol;
    }
    for (size_t i = 0; i < crew.size(); i++) {
        grid[crew[i].y][crew[i].x] = crew[i].symbol;
    }
    int tx = roundToInt(playerTank.x);
    int ty = roundToInt(playerTank.y);
    grid[ty][tx] = getTankSymbol(playerTank.angle);
    system("cls");
    for (size_t i = 0; i < grid.size(); i++) {
        for (size_t j = 0; j < grid[i].size(); j++) {
            std::cout << grid[i][j] << ' ';
        }
        std::cout << std::endl;
    }
}

// --------------------
// 战役 1-4 主函数(地图模式)
// --------------------
void playCampaign(int campaign) {
    const int MAP_WIDTH = 10, MAP_HEIGHT = 10;
    std::vector<std::vector<char> > baseMap(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
    addObstacles(baseMap, 10);
    
    Entity player = {5, 9, 150, 'P'};
    Weapon weapon = {"步枪", 6, 6, 6}; // 伤害 10~60
    std::vector<Entity> enemies;
    std::vector<Pickup> pickups;
    std::vector<Entity> bunkers;
    
    if (campaign == 1) {
        std::cout << "任务简报: 诺曼底登陆 - 占领海岸的敌掩体。\n";
        bunkers.push_back({3, 0, 50, 'B'});
        bunkers.push_back({7, 0, 50, 'B'});
        baseMap[0][3] = 'B';
        baseMap[0][7] = 'B';
        enemies.push_back({3, 3, 50, 'E'});
        enemies.push_back({7, 3, 50, 'E'});
        enemies.push_back({5, 5, 50, 'E'});
        pickups.push_back({2, 6, 'M', 20});
    }
    else if (campaign == 2) {
        std::cout << "任务简报: 亚丁攻势 - 顽抗敌军!\n";
        enemies.push_back({2, 2, 50, 'E'});
        enemies.push_back({4, 3, 50, 'E'});
        enemies.push_back({6, 2, 50, 'E'});
        enemies.push_back({3, 4, 50, 'E'});
        enemies.push_back({7, 4, 50, 'E'});
        pickups.push_back({1, 8, 'M', 20});
    }
    else if (campaign == 3) {
        std::cout << "任务简报: 柏林进攻 - 深入敌后,占领旗帜!\n";
        baseMap[0][5] = 'F';
        enemies.push_back({4, 2, 50, 'E'});
        enemies.push_back({6, 2, 50, 'E'});
        enemies.push_back({5, 4, 50, 'E'});
        enemies.push_back({3, 3, 50, 'E'});
        pickups.push_back({8, 7, 'M', 20});
    }
    else if (campaign == 4) {
        std::cout << "德国诺曼底任务:在战壕中使用机枪防御10波盟军进攻,与你的NPC战友协同作战。\n";
        player.health = 150;
        std::vector<Entity> teammates;
        teammates.push_back({4, 9, 120, 'T'});
        teammates.push_back({6, 9, 120, 'T'});
        
        int totalWaves = 10;
        int baseEnemyCount = 3;
        int waveNumber = 1;
        while (waveNumber <= totalWaves) {
            std::cout << "\n--- 第 " << waveNumber << " 波 ---\n";
            int enemyCount = baseEnemyCount + ((waveNumber - 1) / 3) * 2;
            std::vector<Entity> waveEnemies;
            for (int i = 0; i < enemyCount; i++) {
                waveEnemies.push_back({rand() % MAP_WIDTH, 0, 40 + waveNumber * 5, 'A'});
            }
            while (!waveEnemies.empty() && player.health > 0) {
                system("cls");
                std::cout << "德国诺曼底 - 第 " << waveNumber << " 波 / 共 " << totalWaves << " 波\n";
                displayHealthBar("玩家", player.health, 150);
                for (size_t i = 0; i < teammates.size(); i++) {
                    std::cout << "战友" << i + 1 << " 生命值: " << teammates[i].health << "\n";
                }
                std::cout << "剩余攻击者: " << waveEnemies.size() << "\n";
                
                std::cout << "请按方向键 (i/j/k/l) 选择机枪射击方向:";
                char action = _getch();
                int mdx = 0, mdy = 0;
                if (action == 'i') mdy = -1;
                else if (action == 'k') mdy = 1;
                else if (action == 'j') mdx = -1;
                else if (action == 'l') mdx = 1;
                else std::cout << "\n输入错误,本回合跳过。\n";
                
                int shotX = player.x + mdx;
                int shotY = player.y + mdy;
                bool hit = false;
                for (int r = 0; r < 6 && !hit; r++) {
                    if (shotX < 0 || shotX >= MAP_WIDTH || shotY < 0 || shotY >= MAP_HEIGHT)
                        break;
                    int idx = findEntityAt(waveEnemies, shotX, shotY);
                    if (idx != -1) {
                        int damage = 25 + rand() % 26; // 25-50
                        waveEnemies[idx].health -= damage;
                        std::cout << "\n你使用机枪射击攻击者 (" << shotX << "," << shotY << "),造成 " << damage << " 点伤害。\n";
                        if (waveEnemies[idx].health <= 0) {
                            waveEnemies.erase(waveEnemies.begin() + idx);
                            score += 100;
                            std::cout << "攻击者被消灭!(+100分)\n";
                        }
                        hit = true;
                        break;
                    }
                    shotX += mdx;
                    shotY += mdy;
                }
                // 战友自动射击
                for (size_t i = 0; i < teammates.size(); i++) {
                    if (!waveEnemies.empty()) {
                        int targetIndex = rand() % waveEnemies.size();
                        int damage = 25 + rand() % 26;
                        waveEnemies[targetIndex].health -= damage;
                        std::cout << "战友射击,造成 " << damage << " 点伤害。\n";
                        if (waveEnemies[targetIndex].health <= 0) {
                            waveEnemies.erase(waveEnemies.begin() + targetIndex);
                            score += 100;
                            std::cout << "攻击者被战友击毙!(+100分)\n";
                        }
                    }
                }
                // 敌人反击
                for (size_t i = 0; i < waveEnemies.size(); i++) {
                    int dmg = 10 + rand() % 6;
                    if (!teammates.empty() && (rand() % 2 == 0)) {
                        int tIndex = rand() % teammates.size();
                        teammates[tIndex].health -= dmg;
                        std::cout << "攻击者射击战友" << tIndex + 1 << ",造成 " << dmg << " 点伤害。\n";
                        if (teammates[tIndex].health <= 0) {
                            std::cout << "战友" << tIndex + 1 << "阵亡!\n";
                            teammates.erase(teammates.begin() + tIndex);
                        }
                    } else {
                        player.health -= dmg;
                        std::cout << "攻击者射击你,造成 " << dmg << " 点伤害。\n";
                    }
                }
                
                std::cout << "\n按任意键进入本波下一回合...";
                _getch();
                if (player.health <= 0)
                    break;
            }
            if (player.health <= 0)
                break;
            if (waveNumber % 3 == 0) {
                int repair = 15;
                player.health += repair;
                if (player.health > 150)
                    player.health = 150;
                std::cout << "  你获得了坦克维修 (+15 生命)!\n";
            }
            std::cout << "\n第 " << waveNumber << " 波清除!按任意键进入下一波...";
            _getch();
            waveNumber++;
        }
        if (player.health > 0)
            std::cout << "\n所有波次已击退!德国诺曼底任务完成。\n";
        else
            std::cout << "\n你在战壕中被击溃。任务失败。\n";
        return;
    }
    
    // 若为战役 1-3,以下为常规地图模式循环(保持原有逻辑)
    while (true) {
        render(baseMap, player, enemies, pickups, bunkers, weapon);
        char input = _getch();
        int dx = 0, dy = 0;
        bool isMove = false, isShoot = false, isGrenade = false, isReload = false;
        
        if (input == 'w') { dy = -1; isMove = true; }
        else if (input == 's') { dy = 1; isMove = true; }
        else if (input == 'a') { dx = -1; isMove = true; }
        else if (input == 'd') { dx = 1; isMove = true; }
        else if (input == 'q') { dx = -1; dy = -1; isMove = true; }
        else if (input == 'e') { dx = 1; dy = -1; isMove = true; }
        else if (input == 'z') { dx = -1; dy = 1; isMove = true; }
        else if (input == 'c') { dx = 1; dy = 1; isMove = true; }
        else if (input == 'i') { dy = -1; isShoot = true; }
        else if (input == 'k') { dy = 1; isShoot = true; }
        else if (input == 'j') { dx = -1; isShoot = true; }
        else if (input == 'l') { dx = 1; isShoot = true; }
        else if (input == 'g') { isGrenade = true; }
        else if (input == 'r') { isReload = true; }
        
        if (isMove) {
            int newX = player.x + dx;
            int newY = player.y + dy;
            if (newX >= 0 && newX < MAP_WIDTH && newY >= 0 && newY < MAP_HEIGHT &&
                (baseMap[newY][newX] == '.' || baseMap[newY][newX] == 'B' || baseMap[newY][newX] == 'F')) {
                player.x = newX;
                player.y = newY;
                if (campaign == 1 && baseMap[newY][newX] == 'B') {
                    int idx = findEntityAt(bunkers, newX, newY);
                    if (idx != -1) {
                        bool survived = battleBunker(bunkers[idx], player.health);
                        if (survived) {
                            score += 100;
                            baseMap[newY][newX] = '.';
                            bunkers.erase(bunkers.begin() + idx);
                        } else {
                            render(baseMap, player, enemies, pickups, bunkers, weapon);
                            std::cout << "游戏结束!被掩体防御击杀。\n";
                            return;
                        }
                    }
                }
                if (campaign == 3 && baseMap[newY][newX] == 'F') {
                    baseMap[newY][newX] = '.';
                    score += 100;
                    std::cout << "旗帜占领成功!(+100分)\n";
                }
            }
            for (size_t i = 0; i < pickups.size(); ) {
                if (pickups[i].x == player.x && pickups[i].y == player.y) {
                    player.health += pickups[i].value;
                    if (player.health > 150)
                        player.health = 150;
                    std::cout << "捡到急救包(回复 " << pickups[i].value << " 生命)\n";
                    score += 50;
                    pickups.erase(pickups.begin() + i);
                } else {
                    i++;
                }
            }
        }
        else if (isShoot) {
            if (weapon.ammo <= 0) {
                std::cout << "弹药不足!按 'r' 装弹!\n";
            } else {
                weapon.ammo--;
                std::cout << "BANG!\n";
                int shotX = player.x + dx;
                int shotY = player.y + dy;
                for (int r = 0; r < weapon.range; r++) {
                    if (shotX < 0 || shotX >= MAP_WIDTH || shotY < 0 || shotY >= MAP_HEIGHT)
                        break;
                    if (baseMap[shotY][shotX] == '#')
                        break;
                    int idx = findEntityAt(enemies, shotX, shotY);
                    if (idx != -1) {
                        int damage = 10 + rand() % 51; // 10~60
                        enemies[idx].health -= damage;
                        std::cout << "击中敌人 (" << shotX << "," << shotY << "),造成 " << damage << " 点伤害。\n";
                        if (enemies[idx].health <= 0) {
                            enemies.erase(enemies.begin() + idx);
                            score += 100;
                            std::cout << "敌人被消灭!(+100分)\n";
                        }
                        break;
                    }
                    shotX += dx;
                    shotY += dy;
                }
            }
        }
        else if (isGrenade) {
            std::cout << "BOOM! 手雷爆炸。\n请输入手雷投掷方向 (i/j/k/l): ";
            char gDir = _getch();
            int centerX = player.x;
            int centerY = player.y;
            if (gDir == 'i') centerY = player.y - 1;
            else if (gDir == 'k') centerY = player.y + 1;
            else if (gDir == 'j') centerX = player.x - 1;
            else if (gDir == 'l') centerX = player.x + 1;
            for (size_t i = 0; i < enemies.size(); ) {
                if (std::abs(enemies[i].x - centerX) <= 1 && std::abs(enemies[i].y - centerY) <= 1) {
                    enemies[i].health -= 20;
                    std::cout << "手雷击中敌人 (" << enemies[i].x << "," << enemies[i].y << "),造成 20 伤害。\n";
                    if (enemies[i].health <= 0) {
                        enemies.erase(enemies.begin() + i);
                        score += 100;
                        std::cout << "敌人被手雷消灭!(+100分)\n";
                        continue;
                    }
                }
                i++;
            }
        }
        else if (isReload) {
            weapon.ammo = weapon.clipSize;
            std::cout << "装弹中...\n";
        }
        
        // 敌人行动
        for (size_t i = 0; i < enemies.size(); i++) {
            if (enemies[i].x == player.x || enemies[i].y == player.y) {
                int shotDx = (enemies[i].x == player.x) ? 0 : (enemies[i].x < player.x ? 1 : -1);
                int shotDy = (enemies[i].y == player.y) ? 0 : (enemies[i].y < player.y ? 1 : -1);
                int shotX = enemies[i].x + shotDx;
                int shotY = enemies[i].y + shotDy;
                while (shotX >= 0 && shotX < MAP_WIDTH && shotY >= 0 && shotY < MAP_HEIGHT) {
                    if (baseMap[shotY][shotX] == '#')
                        break;
                    if (shotX == player.x && shotY == player.y) {
                        int dmg = 10 + rand() % 6;
                        player.health -= dmg;
                        std::cout << "敌人射击你,造成 " << dmg << " 点伤害!\n";
                        break;
                    }
                    shotX += shotDx;
                    shotY += shotDy;
                }
            }
            else {
                int moveDx = (enemies[i].x < player.x) ? 1 : (enemies[i].x > player.x ? -1 : 0);
                int moveDy = (enemies[i].y < player.y) ? 1 : (enemies[i].y > player.y ? -1 : 0);
                int newX = enemies[i].x + moveDx;
                int newY = enemies[i].y + moveDy;
                if (newX >= 0 && newX < MAP_WIDTH && newY >= 0 && newY < MAP_HEIGHT && baseMap[newY][newX] == '.')
                {
                    enemies[i].x = newX;
                    enemies[i].y = newY;
                }
            }
        }
        
        if (player.health <= 0) {
            render(baseMap, player, enemies, pickups, bunkers, weapon);
            std::cout << "游戏结束!你在任务中阵亡。\n";
            return;
        }
        if (campaign == 1 && bunkers.empty()) {
            render(baseMap, player, enemies, pickups, bunkers, weapon);
            std::cout << "\n所有掩体已占领。进入最终战斗...\n";
            bool result = battleEncounter("最终进攻", player.health, 150, 80);
            std::cout << (result ? "胜利!任务完成。\n" : "失败!最终战斗中失败。\n");
            return;
        }
        else if (campaign == 2 && enemies.empty()) {
            render(baseMap, player, enemies, pickups, bunkers, weapon);
            std::cout << "\n所有敌人已消灭。进入最终战斗...\n";
            bool result = battleEncounter("最终防御", player.health, 150, 90);
            std::cout << (result ? "胜利!任务完成。\n" : "失败!最终战斗中失败。\n");
            return;
        }
        else if (campaign == 3 && baseMap[0][5] != 'F') {
            render(baseMap, player, enemies, pickups, bunkers, weapon);
            std::cout << "\n旗帜已占领。进入最终战斗...\n";
            bool result = battleEncounter("旗帜防御", player.health, 150, 80);
            std::cout << (result ? "胜利!任务完成。\n" : "失败!最终战斗中失败。\n");
            return;
        }
    }
}

// --------------------
// 战役 5 主函数(坦克模式)
// --------------------
void playCampaign5() {
    const int MAP_WIDTH = 20, MAP_HEIGHT = 10;
    std::vector<std::vector<char> > grid(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
    std::vector<DestructibleObstacle> obstacles;
    addObstaclesDestructible(grid, obstacles, 5);  // 放置 5 个可破坏障碍
    
    // 坦克生命值200,固定速度1.0
    Tank playerTank = { MAP_WIDTH / 2.0f, MAP_HEIGHT - 2.0f, 90.0f, 1.0f, 200 };
    int cannonAmmo = 4;
    int machineGunAmmo = 20;
    std::vector<Entity> crew;
    {
        Entity temp;
        temp.x = roundToInt(playerTank.x) - 1;
        temp.y = roundToInt(playerTank.y);
        temp.health = 100;
        temp.symbol = 'C';
        crew.push_back(temp);
    }
    {
        Entity temp;
        temp.x = roundToInt(playerTank.x) + 1;
        temp.y = roundToInt(playerTank.y);
        temp.health = 100;
        temp.symbol = 'C';
        crew.push_back(temp);
    }
    
    int totalWaves = 8;
    int baseInfantry = 3;
    for (int wave = 1; wave <= totalWaves; wave++) {
        std::cout << "\n--- 第 " << wave << " 波 ---\n";
        int numInfantry = baseInfantry + ((wave - 1) / 3) * 2;
        int numEnemyTanks = 1 + ((wave - 1) / 3);
        std::vector<Entity> enemies;
        for (int i = 0; i < numInfantry; i++) {
            Entity temp;
            temp.x = rand() % MAP_WIDTH;
            temp.y = 0;
            temp.health = 40 + wave * 5;
            temp.symbol = 'I';
            enemies.push_back(temp);
        }
        for (int i = 0; i < numEnemyTanks; i++) {
            Entity temp;
            temp.x = rand() % MAP_WIDTH;
            temp.y = 0;
            temp.health = 80 + wave * 5;
            temp.symbol = 'T';
            enemies.push_back(temp);
        }
        
        while (!enemies.empty()) {
            std::vector<std::vector<char> > currentGrid(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
            for (size_t i = 0; i < obstacles.size(); i++) {
                currentGrid[obstacles[i].y][obstacles[i].x] = obstacles[i].symbol;
            }
            for (size_t i = 0; i < enemies.size(); i++) {
                currentGrid[enemies[i].y][enemies[i].x] = enemies[i].symbol;
            }
            for (size_t i = 0; i < crew.size(); i++) {
                currentGrid[crew[i].y][crew[i].x] = crew[i].symbol;
            }
            int tx = roundToInt(playerTank.x);
            int ty = roundToInt(playerTank.y);
            currentGrid[ty][tx] = getTankSymbol(playerTank.angle);
            
            system("cls");
            for (size_t i = 0; i < currentGrid.size(); i++) {
                for (size_t j = 0; j < currentGrid[i].size(); j++) {
                    std::cout << currentGrid[i][j] << ' ';
                }
                std::cout << "\n";
            }
            
            std::cout << "德国亚丁攻势(Panther 坦克突击) - 第 " << wave << " 波 / 共 " << totalWaves << " 波\n";
            std::cout << "坦克生命值: " << playerTank.health << "\n";
            std::cout << "机组成员: ";
            for (size_t i = 0; i < crew.size(); i++) {
                std::cout << "机组" << i + 1 << "(" << crew[i].health << ") ";
            }
            std::cout << "\n主炮弹药: " << cannonAmmo << "   机枪弹药: " << machineGunAmmo << "\n";
            std::cout << "剩余敌人: " << enemies.size() << "\n";
            std::cout << "控制: w(加速), s(刹车), a/d(转向), [空格] 主炮, m 机枪, r 装弹\n";
            std::cout << "请输入指令: ";
            char cmd = _getch();
            
            if (cmd == 'w') {
                playerTank.speed = 1.0f;
            } else if (cmd == 's') {
                playerTank.speed = 0.0f;
            } else if (cmd == 'a') {
                playerTank.angle += 15.0f;
                if (playerTank.angle >= 360.0f) playerTank.angle -= 360.0f;
            } else if (cmd == 'd') {
                playerTank.angle -= 15.0f;
                if (playerTank.angle < 0) playerTank.angle += 360.0f;
            }
            else if (cmd == ' ') {
                if (cannonAmmo <= 0) {
                    std::cout << "\n主炮弹药不足!按 r 装弹。\n";
                } else {
                    cannonAmmo--;
                    std::cout << "\n发射主炮!\n";
                    float rad = degToRad(playerTank.angle);
                    int shotRange = 8;
                    int hitIndex = -1;
                    int bx = roundToInt(playerTank.x);
                    int by = roundToInt(playerTank.y);
                    for (int r = 0; r < shotRange; r++) {
                        bx += (int)std::round(std::cos(rad));
                        by -= (int)std::round(std::sin(rad));
                        // 检查障碍物
                        int obsIndex = findObstacleAt(obstacles, bx, by);
                        if (obsIndex != -1) {
                            int damage = 200;
                            float dx = obstacles[obsIndex].x - playerTank.x;
                            float dy = playerTank.y - obstacles[obsIndex].y;
                            float targetAngle = std::atan2(dy, dx) * 180.0f / M_PI;
                            if (targetAngle < 0)
                                targetAngle += 360.0f;
                            float diff = angleDiff(playerTank.angle, targetAngle);
                            float multiplier = (diff < 45 ? 0.5f : (diff > 135 ? 1.5f : 1.0f));
                            int finalDamage = (int)(damage * multiplier);
                            obstacles[obsIndex].health -= finalDamage;
                            std::cout << "主炮击中障碍物 (" << obstacles[obsIndex].x << "," << obstacles[obsIndex].y << "),造成 " << finalDamage << " 点伤害。\n";
                            if (obstacles[obsIndex].health <= 0) {
                                std::cout << "障碍物被摧毁!\n";
                                obstacles.erase(obstacles.begin() + obsIndex);
                            }
                            break;
                        }
                        int enemyIndex = -1;
                        enemyIndex = findEntityAt(enemies, bx, by);
                        if (enemyIndex != -1) {
                            hitIndex = enemyIndex;
                            break;
                        }
                    }
                    if (hitIndex != -1) {
                        int baseDamage = 200;
                        float dx = enemies[hitIndex].x - playerTank.x;
                        float dy = playerTank.y - enemies[hitIndex].y;
                        float targetAngle = std::atan2(dy, dx) * 180.0f / M_PI;
                        if (targetAngle < 0)
                            targetAngle += 360.0f;
                        float diff = angleDiff(playerTank.angle, targetAngle);
                        float multiplier = (diff < 45 ? 0.5f : (diff > 135 ? 1.5f : 1.0f));
                        int damage = (int)(baseDamage * multiplier);
                        enemies[hitIndex].health -= damage;
                        std::cout << "主炮击中敌人 (" << enemies[hitIndex].x << "," << enemies[hitIndex].y << "),造成 " << damage << " 点伤害。\n";
                        if (enemies[hitIndex].health <= 0) {
                            std::cout << "敌人被摧毁!\n";
                            enemies.erase(enemies.begin() + hitIndex);
                            score += 150;
                        }
                    } else {
                        std::cout << "主炮未命中。\n";
                    }
                }
            }
            else if (cmd == 'm') {
                if (machineGunAmmo <= 0) {
                    std::cout << "\n机枪弹药不足!按 r 装弹。\n";
                } else {
                    machineGunAmmo--;
                    std::cout << "\n发射机枪!\n";
                    float rad = degToRad(playerTank.angle);
                    int shotRange = 6;
                    int hitIndex = -1;
                    int bx = roundToInt(playerTank.x);
                    int by = roundToInt(playerTank.y);
                    for (int r = 0; r < shotRange; r++) {
                        bx += (int)std::round(std::cos(rad));
                        by -= (int)std::round(std::sin(rad));
                        int obsIndex = findObstacleAt(obstacles, bx, by);
                        if (obsIndex != -1) {
                            int damage = 30 + rand() % 11;
                            obstacles[obsIndex].health -= damage;
                            std::cout << "机枪击中障碍物 (" << obstacles[obsIndex].x << "," << obstacles[obsIndex].y << "),造成 " << damage << " 点伤害。\n";
                            if (obstacles[obsIndex].health <= 0) {
                                std::cout << "障碍物被摧毁!\n";
                                obstacles.erase(obstacles.begin() + obsIndex);
                            }
                            break;
                        }
                        int enemyIndex = findEntityAt(enemies, bx, by);
                        if (enemyIndex != -1) {
                            hitIndex = enemyIndex;
                            break;
                        }
                    }
                    if (hitIndex != -1) {
                        int damage = 30 + rand() % 11;
                        enemies[hitIndex].health -= damage;
                        std::cout << "机枪击中敌人 (" << enemies[hitIndex].x << "," << enemies[hitIndex].y << "),造成 " << damage << " 点伤害。\n";
                        if (enemies[hitIndex].health <= 0) {
                            std::cout << "敌人被摧毁!\n";
                            enemies.erase(enemies.begin() + hitIndex);
                            score += 100;
                        }
                    } else {
                        std::cout << "机枪未命中。\n";
                    }
                }
            }
            else if (cmd == 'r') {
                cannonAmmo = 4;
                machineGunAmmo = 20;
                std::cout << "\n正在装弹...\n";
            }
            
            // 更新坦克位置
            float rad = degToRad(playerTank.angle);
            playerTank.x += playerTank.speed * std::cos(rad);
            playerTank.y -= playerTank.speed * std::sin(rad);
            if (playerTank.x < 0) playerTank.x = 0;
            if (playerTank.x >= MAP_WIDTH) playerTank.x = MAP_WIDTH - 1;
            if (playerTank.y < 0) playerTank.y = 0;
            if (playerTank.y >= MAP_HEIGHT) playerTank.y = MAP_HEIGHT - 1;
            
            // 更新机组成员位置
            int tnx = roundToInt(playerTank.x);
            int tny = roundToInt(playerTank.y);
            crew[0].x = tnx - 1;
            crew[0].y = tny;
            crew[1].x = tnx + 1;
            crew[1].y = tny;
            
            // 敌人行动
            for (size_t i = 0; i < enemies.size(); i++) {
                if (enemies[i].x < roundToInt(playerTank.x))
                    enemies[i].x++;
                else if (enemies[i].x > roundToInt(playerTank.x))
                    enemies[i].x--;
                if (enemies[i].y < roundToInt(playerTank.y))
                    enemies[i].y++;
                else if (enemies[i].y > roundToInt(playerTank.y))
                    enemies[i].y--;
                if (rand() % 100 < 30) {
                    int baseDmg = 15 + rand() % 6;
                    float dx = enemies[i].x - playerTank.x;
                    float dy = playerTank.y - enemies[i].y;
                    float enemyAngle = std::atan2(dy, dx) * 180.0f / M_PI;
                    if (enemyAngle < 0) enemyAngle += 360.0f;
                    float diff = angleDiff(playerTank.angle, enemyAngle);
                    float multiplier = (diff < 45 ? 0.5f : (diff > 135 ? 1.5f : 1.0f));
                    int dmg = (int)(baseDmg * multiplier);
                    playerTank.health -= dmg;
                    std::cout << "敌人射击你,造成 " << dmg << " 点伤害。\n";
                }
            }
            
            std::cout << "\n按任意键进入本波下一回合...";
            _getch();
            if (playerTank.health <= 0) {
                std::cout << "\n你的Panther坦克被摧毁. 任务失败.\n";
                return;
            }
        }
        
        std::cout << "\n本波清除!按任意键进入下一波...";
        _getch();
        
        if (wave % 3 == 0) {
            playerTank.health += 15;
            if (playerTank.health > 200) playerTank.health = 200;
            std::cout << "  坦克获得维修 (+15 生命)!\n";
        }
    }
    std::cout << "\n所有敌防被摧毁!德国亚丁攻势任务完成.\n";
}

// --------------------
// Main 函数
// --------------------
int main() {
    srand(static_cast<unsigned int>(time(0)));
    std::cout << "战场 1 - 增强版\n";
    std::cout << "【操作说明】\n";
    std::cout << "(战役1-4) 移动: w/a/s/d 及对角 (q,e,z,c). 射击: i/j/k/l (上/左/下/右). 手雷: g, 装弹: r.\n";
    std::cout << "\n请选择战役:\n";
    std::cout << "1. 诺曼底登陆\n2. 亚丁攻势\n3. 柏林进攻\n4. 德国诺曼底 (机枪防御)\n5. 德国亚丁攻势 (Panther 坦克突击)\n请输入编号 (1-5): ";
    int choice;
    std::cin >> choice;
    if (choice >= 1 && choice <= 5) {
        if (choice == 5) {
            playCampaign5();
        } else {
            playCampaign(choice);
        }
    } else {
        std::cout << "输入无效!\n";
    }
    std::cout << "\n按任意键退出...";
    _getch();
    return 0;
}