#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>

using namespace std;

// 定义地图大小
const int MAP_WIDTH = 20;
const int MAP_HEIGHT = 20;

// 玩家类
class Player {
public:
    int x, y;
    int health;
    int bullets;

    Player(int _x, int _y) : x(_x), y(_y), health(100), bullets(10) {}

    void takeDamage(int damage) {
        health -= damage;
        if (health < 0) health = 0;
    }

    bool isAlive() const {
        return health > 0;
    }

    void reload() {
        bullets = 10;
    }
};

// 敌人类
class Enemy {
public:
    int x, y;
    int health;

    Enemy(int _x, int _y) : x(_x), y(_y), health(50) {}

    void takeDamage(int damage) {
        health -= damage;
        if (health < 0) health = 0;
    }

    bool isAlive() const {
        return health > 0;
    }
};

// 游戏地图类
class GameMap {
public:
    vector<vector<char>> map;

    GameMap() {
        map.resize(MAP_HEIGHT, vector<char>(MAP_WIDTH, '.'));
        // 随机生成障碍物
        for (int i = 0; i < MAP_WIDTH * MAP_HEIGHT / 10; ++i) {
            int x = rand() % MAP_WIDTH;
            int y = rand() % MAP_HEIGHT;
            if (map[y][x] == '.') {
                map[y][x] = '#'; // 障碍物用 '#' 表示
            }
        }
    }

    void placePlayer(const Player& player) {
        map[player.y][player.x] = 'P';
    }

    void placeEnemy(const Enemy& enemy) {
        map[enemy.y][enemy.x] = 'E';
    }

    void placeTeammate(const Player& teammate) {
        map[teammate.y][teammate.x] = 'T';
    }

    void clearMap() {
        for (int y = 0; y < MAP_HEIGHT; ++y) {
            for (int x = 0; x < MAP_WIDTH; ++x) {
                if (map[y][x] != '#') {
                    map[y][x] = '.';
                }
            }
        }
    }

    void drawMap() {
        for (const auto& row : map) {
            for (char cell : row) {
                cout << cell << " ";
            }
            cout << endl;
        }
    }

    bool isObstacle(int x, int y) const {
        return map[y][x] == '#';
    }

    bool isOccupied(int x, int y) const {
        return map[y][x] != '.' && map[y][x] != '#';
    }
};

// 队友类
class Teammate : public Player {
public:
    Teammate(int _x, int _y) : Player(_x, _y) {}

    // 队友自动移动
    void moveTowardsEnemy(const Enemy& enemy, GameMap& gameMap) {
        int dx = enemy.x - x;
        int dy = enemy.y - y;

        // 优先水平移动
        if (abs(dx) > abs(dy)) {
            if (dx > 0 && x < MAP_WIDTH - 1 && !gameMap.isObstacle(x + 1, y) && !gameMap.isOccupied(x + 1, y)) {
                x++;
            } else if (dx < 0 && x > 0 && !gameMap.isObstacle(x - 1, y) && !gameMap.isOccupied(x - 1, y)) {
                x--;
            }
        } else {
            if (dy > 0 && y < MAP_HEIGHT - 1 && !gameMap.isObstacle(x, y + 1) && !gameMap.isOccupied(x, y + 1)) {
                y++;
            } else if (dy < 0 && y > 0 && !gameMap.isObstacle(x, y - 1) && !gameMap.isOccupied(x, y - 1)) {
                y--;
            }
        }
    }

    // 队友自动射击
    void shootEnemy(Enemy& enemy) {
        if (bullets > 0) {
            int damage = rand() % 15 + 1; // 队友的伤害稍低
            enemy.takeDamage(damage);
            bullets--;
            cout << "Teammate shot the enemy for " << damage << " damage!" << endl;
        }
    }
};

// 游戏逻辑
void playGame() {
    srand(time(0)); // 初始化随机数种子

    Player player(0, 0);
    Teammate teammate(MAP_WIDTH - 1, 0); // 队友初始位置
    Enemy enemy(MAP_WIDTH - 1, MAP_HEIGHT - 1);
    GameMap gameMap;

    cout << "Welcome to the Gunfight Game!" << endl;

    while (player.isAlive() && enemy.isAlive()) {
        gameMap.clearMap();
        gameMap.placePlayer(player);
        gameMap.placeTeammate(teammate);
        gameMap.placeEnemy(enemy);
        gameMap.drawMap();

        cout << "\nYour Health: " << player.health << ", Bullets: " << player.bullets << endl;
        cout << "Teammate Health: " << teammate.health << ", Bullets: " << teammate.bullets << endl;
        cout << "Enemy Health: " << enemy.health << endl;

        cout << "Choose an action: " << endl;
        cout << "1. Shoot" << endl;
        cout << "2. Move" << endl;
        cout << "3. Reload" << endl;
        cout << "4. Run" << endl;

        string action;
        getline(cin, action);

        if (action == "1") {
            if (player.bullets > 0) {
                int damage = rand() % 20 + 1; // 随机伤害
                enemy.takeDamage(damage);
                player.bullets--;
                cout << "You shot the enemy for " << damage << " damage!" << endl;
            } else {
                cout << "You have no bullets left! Reload or run!" << endl;
            }
        } else if (action == "2") {
            cout << "Enter direction (w/a/s/d): ";
            char direction;
            cin >> direction;
            cin.ignore(); // 清除缓冲区
            int newX = player.x, newY = player.y;
            switch (direction) {
                case 'w': if (player.y > 0) newY--; break;
                case 's': if (player.y < MAP_HEIGHT - 1) newY++; break;
                case 'a': if (player.x > 0) newX--; break;
                case 'd': if (player.x < MAP_WIDTH - 1) newX++; break;
                default: cout << "Invalid direction." << endl; break;
            }
            if (!gameMap.isObstacle(newX, newY) && !gameMap.isOccupied(newX, newY)) {
                player.x = newX;
                player.y = newY;
            } else {
                cout << "You can't move there!" << endl;
            }
        } else if (action == "3") {
            player.reload();
            cout << "You reloaded your gun." << endl;
        } else if (action == "4") {
            cout << "You ran away!" << endl;
            break;
        } else {
            cout << "Invalid action. Try again." << endl;
        }

        // 队友自动移动和射击
        teammate.moveTowardsEnemy(enemy, gameMap);
        if (teammate.bullets > 0 && abs(teammate.x - enemy.x) <= 1 && abs(teammate.y - enemy.y) <= 1) {
            teammate.shootEnemy(enemy);
        }

        if (enemy.isAlive()) {
            int enemyDamage = rand() % 10 + 1; // 敌人随机伤害
            player.takeDamage(enemyDamage);
            cout << "The enemy shot you for " << enemyDamage << " damage!" << endl;
        }
    }

    if (player.isAlive()) {
        cout << "Congratulations! You and your teammate defeated the enemy!" << endl;
    } else {
        cout << "Game Over. You were killed by the enemy." << endl;
    }
}

int main() {
    playGame();
    return 0;
}