#include <iostream>
#include <windows.h>
#include <vector>
#include <conio.h>
#include <cstdlib>
#include <ctime>
#include <algorithm>

using namespace std;

const int WIDTH = 60;
const int HEIGHT = 30;

int playerX;
int playerY;
bool gameOver;
int lives;

struct Bullet {
    int x, y;
};

vector<Bullet> playerBullets;
vector<Bullet> enemyBullets;

struct Enemy {
    int x, y;
    bool alive;
};

vector<Enemy> enemies;

struct Boss {
    int x, y;
    int hp;
    int dir;
    bool alive;
} boss;

int enemyDir;
int enemyMoveSpeed;
int enemyFireRate;
int enemyMoveTimer;
int score;

char screen[HEIGHT][WIDTH + 1];

void setPos(int x, int y) {
    COORD pos = {(SHORT)x, (SHORT)y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void hideCursor() {
    CONSOLE_CURSOR_INFO info;
    info.dwSize = 1;
    info.bVisible = FALSE;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
}

void clearScreen() {
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            screen[y][x] = ' ';
        }
        screen[y][WIDTH] = '\0';
    }
}

void drawBorder() {
    for (int x = 0; x < WIDTH; x++) screen[0][x] = '-';
    for (int y = 1; y < HEIGHT - 1; y++) {
        screen[y][0] = '|';
        screen[y][WIDTH - 1] = '|';
    }
    for (int x = 0; x < WIDTH; x++) screen[HEIGHT - 1][x] = '-';
}

void renderScreen() {
    setPos(0,0);
    for (int y = 0; y < HEIGHT; y++) cout << screen[y] << endl;
}

void initGame() {
    playerX = WIDTH / 2;
    playerY = HEIGHT - 3;
    gameOver = false;
    lives = 3;

    enemyDir = 1;
    enemyMoveSpeed = 8;
    enemyFireRate = 25;
    enemyMoveTimer = 0;
    score = 0;
    boss.alive = false;
}

void initEnemies() {
    for (int i = 0; i < 10; i++) {
        Enemy e;
        e.x = 5 + i * 4;
        e.y = 2;
        e.alive = true;
        enemies.push_back(e);
    }
}

void spawnBoss() {
    if (score >= 300 && !boss.alive) {
        boss.alive = true;
        boss.x = WIDTH / 2;
        boss.y = 4;
        boss.hp = 40;
        boss.dir = 1;
    }
}

void input() {
    if (_kbhit()) {
        char key = _getch();
        if (key == 75 && playerX > 2) playerX--;
        if (key == 77 && playerX < WIDTH - 3) playerX++;
        if (key == 32) {
            Bullet b;
            b.x = playerX;
            b.y = playerY - 1;
            playerBullets.push_back(b);
        }
        if (key == 27) gameOver = true;
    }
}

void logic() {
    // 玩家子弹移动
    for (int i = 0; i < playerBullets.size(); i++) {
        playerBullets[i].y--;
        if (playerBullets[i].y < 1) {
            playerBullets.erase(playerBullets.begin() + i);
            i--;
        }
    }

    // 敌人子弹移动
    for (int i = 0; i < enemyBullets.size(); i++) {
        enemyBullets[i].y++;
        if (enemyBullets[i].y > HEIGHT - 2) {
            enemyBullets.erase(enemyBullets.begin() + i);
            i--;
        }
    }

    // 敌人移动
    enemyMoveTimer++;
    if (enemyMoveTimer >= enemyMoveSpeed) {
        enemyMoveTimer = 0;
        bool drop = false;
        for (int i = 0; i < enemies.size(); i++) {
            if (!enemies[i].alive) continue;
            enemies[i].x += enemyDir;
            if (enemies[i].x <= 1 || enemies[i].x >= WIDTH - 2) drop = true;
        }
        if (drop) {
            enemyDir *= -1;
            for (int i = 0; i < enemies.size(); i++) {
                if (enemies[i].alive) enemies[i].y++;
            }
        }
    }

    // 敌人射击
    if (rand() % enemyFireRate == 0) {
        int r = rand() % enemies.size();
        if (enemies[r].alive) {
            Bullet b;
            b.x = enemies[r].x;
            b.y = enemies[r].y + 1;
            enemyBullets.push_back(b);
        }
    }

    // BOSS 逻辑
    if (boss.alive) {
        boss.x += boss.dir;
        if (boss.x < 5 || boss.x > WIDTH - 5) boss.dir *= -1;
        if (rand() % 8 == 0) {
            Bullet b1, b2, b3;
            b1.x = boss.x; b1.y = boss.y + 1;
            b2.x = boss.x - 1; b2.y = boss.y + 1;
            b3.x = boss.x + 1; b3.y = boss.y + 1;
            enemyBullets.push_back(b1);
            enemyBullets.push_back(b2);
            enemyBullets.push_back(b3);
        }
    }

    // 子弹击中敌人
    for (int i = 0; i < enemies.size(); i++) {
        if (!enemies[i].alive) continue;
        for (int j = 0; j < playerBullets.size(); j++) {
            if (playerBullets[j].x == enemies[i].x && playerBullets[j].y == enemies[i].y) {
                enemies[i].alive = false;
                score += 10;
                playerBullets.erase(playerBullets.begin() + j);
                break;
            }
        }
    }

    // 子弹击中BOSS
    if (boss.alive) {
        for (int j = 0; j < playerBullets.size(); j++) {
            if (playerBullets[j].y == boss.y &&
                playerBullets[j].x >= boss.x - 1 &&
                playerBullets[j].x <= boss.x + 1) {
                boss.hp--;
                score += 10;
                playerBullets.erase(playerBullets.begin() + j);
                if (boss.hp <= 0) {
                    boss.alive = false;
                }
                break;
            }
        }
    }

    // 玩家碰撞
    bool hit = false;
    for (int i = 0; i < enemyBullets.size(); i++) {
        if (enemyBullets[i].x == playerX && enemyBullets[i].y == playerY) {
            hit = true;
        }
    }
    for (int i = 0; i < enemies.size(); i++) {
        if (enemies[i].alive && enemies[i].x == playerX && enemies[i].y == playerY) {
            hit = true;
        }
    }
    if (boss.alive && playerY == boss.y && playerX >= boss.x - 1 && playerX <= boss.x + 1) {
        hit = true;
    }

    if (hit) {
        lives--;
        playerX = WIDTH / 2;
        enemyBullets.clear();
        if (lives <= 0) gameOver = true;
    }
}

void drawGame() {
    clearScreen();
    drawBorder();

    // 玩家
    screen[playerY][playerX] = '^';

    // 敌人
    for (int i = 0; i < enemies.size(); i++) {
        if (enemies[i].alive) {
            screen[enemies[i].y][enemies[i].x] = '*';
        }
    }

    // BOSS
    if (boss.alive) {
        screen[boss.y][boss.x - 1] = '#';
        screen[boss.y][boss.x] = '#';
        screen[boss.y][boss.x + 1] = '#';
    }

    // 子弹
    for (int i = 0; i < playerBullets.size(); i++) {
        screen[playerBullets[i].y][playerBullets[i].x] = '|';
    }
    for (int i = 0; i < enemyBullets.size(); i++) {
        screen[enemyBullets[i].y][enemyBullets[i].x] = '.';
    }

    // 信息
    char info[60];
    sprintf(info, "Score:%-4d HP:%d", score, lives);
    for (int i = 0; info[i]; i++) {
        screen[HEIGHT-1][2+i] = info[i];
    }

    if (boss.alive) {
        sprintf(info, "BOSS HP:%d", boss.hp);
        for (int i = 0; info[i]; i++) {
            screen[HEIGHT-1][25+i] = info[i];
        }
    }

    renderScreen();
    Sleep(30);
}

int main() {
    srand((unsigned)time(NULL));
    system("mode con cols=60 lines=31");
    hideCursor();
    initGame();
    initEnemies();

    while (!gameOver) {
        input();
        spawnBoss();
        logic();
        drawGame();
    }

    setPos(0, HEIGHT-1);
    cout << "  GAME OVER! Score: " << score << endl;
    return 0;
}