15 条题解

  • 0
    @ 2026-6-11 16:09:30

    Don't play it

    #include<bits/stdc++.h>
    #include <iostream>
    #include <conio.h>
    #include <windows.h>
    #include <vector>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <algorithm>
    #include <string>
    
    using namespace std;
    
    // ---------- 控制台辅助 ----------
    void gotoxy(int x, int y) {
        COORD coord;
        coord.X = x;
        coord.Y = y;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }
    
    void hideCursor() {
        CONSOLE_CURSOR_INFO cursorInfo;
        GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
        cursorInfo.bVisible = false;
        SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
    }
    
    // ---------- 火柴人 ----------
    const char* stickman[3] = {
        " O ",
        "/|\\",
        "/ \\"
    };
    
    // ---------- 数据结构 ----------
    struct Point {
        int x, y;
        Point(int x = 0, int y = 0) : x(x), y(y) {}
    };
    
    struct Enemy {
        Point pos;
        bool alive;
        Enemy(int x, int y) : pos(x, y), alive(true) {}
    };
    
    struct Bullet {
        Point pos;
        float dx, dy;
        int speed;
        bool active;
        Bullet(Point start, Point target, int spd = 8) {
            pos = start;
            float len = sqrt((target.x - start.x)*(target.x - start.x) + (target.y - start.y)*(target.y - start.y));
            if (len < 0.01f) len = 1.0f;
            dx = (target.x - start.x) / len;
            dy = (target.y - start.y) / len;
            speed = spd;
            active = true;
        }
        void update() {
            pos.x += (int)(dx * speed);
            pos.y += (int)(dy * speed);
        }
    };
    
    struct ExtractionPoint {
        Point pos;
        ExtractionPoint(int x, int y) : pos(x, y) {}
    };
    // ---------- 收集品 ----------
    class Collectible {
    public:
        string name;
        double price;   // 改用 double,避免 long long 兼容问题
        Collectible(string n, double p) : name(n), price(p) {}
        virtual ~Collectible() {}
    };
    
    // 具体收集品(价格用浮点数,显示时会取整)
    class AfricanHeart : public Collectible {
    public:
        AfricanHeart() : Collectible("非洲之心", 13000000.0) {}
    };
    class Resuscitator : public Collectible {
    public:
        Resuscitator() : Collectible("复苏呼吸机", 6000000.0) {}
    };
    class MilitaryRadar : public Collectible {
    public:
        MilitaryRadar() : Collectible("便携军用雷达", 2100000.0) {}
    };
    class QuantumStorage : public Collectible {
    public:
        QuantumStorage() : Collectible("量子存储", 270000.0) {}
    };
    class ExperimentalData : public Collectible {
    public:
        ExperimentalData() : Collectible("实验数据", 240000.0) {}
    };
    class MechanicalWatch : public Collectible {
    public:
        MechanicalWatch() : Collectible("名贵机械表", 210000.0) {}
    };
    class Laptop : public Collectible {
    public:
        Laptop() : Collectible("笔记本电脑", 100000.0) {}
    };
    class MilitaryShell : public Collectible {
    public:
        MilitaryShell() : Collectible("军用炮弹", 50000.0) {}
    };
    class Bandage : public Collectible {
    public:
        Bandage() : Collectible("绷带", 1000.0) {}
    };
    class Painkiller : public Collectible {
    public:
        Painkiller() : Collectible("止痛药", 2000.0) {}
    };
    class Screw : public Collectible {
    public:
        Screw() : Collectible("螺丝", 500.0) {}
    };
    class Tape : public Collectible {
    public:
        Tape() : Collectible("胶带", 800.0) {}
    };
    class Document : public Collectible {
    public:
        Document() : Collectible("机密文件", 5000.0) {}
    };
    // ---------- 容器类型 ----------
    enum ContainerType {
        CRATE_TYPE,
        WEAPON_BOX_TYPE,
        MEDICAL_BOX_TYPE,
        SAFE_TYPE,
        FILE_CABINET_TYPE,
        TOOLBOX_TYPE
    };
    
    string getContainerSymbol(ContainerType type) {
        switch(type) {
            case CRATE_TYPE: return "[箱]";
            case WEAPON_BOX_TYPE: return "[武]";
            case MEDICAL_BOX_TYPE: return "[医]";
            case SAFE_TYPE: return "[险]";
            case FILE_CABINET_TYPE: return "[柜]";
            case TOOLBOX_TYPE: return "[具]";
            default: return "[箱]";
        }
    }
    
    Collectible* generateItemByContainer(ContainerType type) {
        int r = rand() % 100;
        switch(type) {
            case SAFE_TYPE:
                if (r < 15) return new AfricanHeart();
                else if (r < 30) return new Resuscitator();
                else if (r < 45) return new MilitaryRadar();
                else if (r < 60) return new QuantumStorage();
                else if (r < 75) return new ExperimentalData();
                else if (r < 85) return new MechanicalWatch();
                else if (r < 95) return new Laptop();
                else return new MilitaryShell();
            case WEAPON_BOX_TYPE:
                if (r < 5) return new AfricanHeart();
                else if (r < 12) return new MilitaryRadar();
                else if (r < 22) return new QuantumStorage();
                else if (r < 35) return new MilitaryShell();
                else if (r < 50) return new Laptop();
                else return new Screw();
            case MEDICAL_BOX_TYPE:
                if (r < 5) return new Resuscitator();
                else if (r < 15) return new ExperimentalData();
                else if (r < 30) return new MechanicalWatch();
                else if (r < 50) return new Bandage();
                else return new Painkiller();
            case FILE_CABINET_TYPE:
                if (r < 2) return new AfricanHeart();
                else if (r < 6) return new QuantumStorage();
                else if (r < 12) return new ExperimentalData();
                else if (r < 25) return new Document();
                else return new Tape();
            case TOOLBOX_TYPE:
                if (r < 3) return new MilitaryRadar();
                else if (r < 10) return new Laptop();
                else if (r < 25) return new Screw();
                else return new Tape();
            default: // CRATE_TYPE
                if (r < 2) return new AfricanHeart();
                else if (r < 5) return new Resuscitator();
                else if (r < 9) return new MilitaryRadar();
                else if (r < 14) return new QuantumStorage();
                else if (r < 20) return new ExperimentalData();
                else if (r < 27) return new MechanicalWatch();
                else if (r < 35) return new Laptop();
                else if (r < 45) return new MilitaryShell();
                else if (r < 60) return new Document();
                else return new Bandage();
        }
    }
    
    struct Box {
        Point pos;
        bool isOpen;
        ContainerType type;
        Collectible* item;
        
        Box(int x, int y, bool open = false, ContainerType t = CRATE_TYPE) 
            : pos(x, y), isOpen(open), type(t), item(NULL) 
        {
            if (!isOpen) {
                item = generateItemByContainer(type);
            }
        }
        
     ~Box() {
            delete item;
        }
        
    private:
        Box(const Box&);
        Box& operator=(const Box&);
    };
    
    // ---------- 全局变量 ----------
    Point manPos(40, 12);
    vector<Enemy> enemies;
    vector<Box> boxes;
    vector<Bullet> bullets;
    ExtractionPoint extraction(70, 20);
    int playerHealth = 3;
    int bulletSpeed = 8;
    const int MAX_HEALTH = 3;
    double totalValue = 0.0;
    bool gameOver = false;
    bool gameWin = false;
    
    const int SCREEN_W = 80;
    const int SCREEN_H = 25;
    
    // ---------- 辅助函数 ----------
    float distance(const Point& a, const Point& b) {
        return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
    }
    
    int findNearestEnemy(const Point& from) {
        if (enemies.empty()) return -1;
        int nearestIdx = -1;
        float minDist = 1e9;
        for (size_t i = 0; i < enemies.size(); i++) {
            if (!enemies[i].alive) continue;
            Point enemyCenter(enemies[i].pos.x + 1, enemies[i].pos.y + 1);
            float d = distance(from, enemyCenter);
            if (d < minDist) {
                minDist = d;
                nearestIdx = i;
            }
        }
        return nearestIdx;
    }
    
    void shoot() {
        Point manCenter(manPos.x + 1, manPos.y + 1);
        int targetIdx = findNearestEnemy(manCenter);
        if (targetIdx != -1) {
            Point enemyCenter(enemies[targetIdx].pos.x + 1, enemies[targetIdx].pos.y + 1);
            bullets.push_back(Bullet(manCenter, enemyCenter, bulletSpeed));
        }
    }
    
    void updateBullets() {
        for (int i = 0; i < (int)bullets.size(); ) {
            bullets[i].update();
            if (bullets[i].pos.x < 0 || bullets[i].pos.x >= SCREEN_W || bullets[i].pos.y < 0 || bullets[i].pos.y >= SCREEN_H) {
                bullets.erase(bullets.begin() + i);
                continue;
            }
            bool hit = false;
            for (int j = 0; j < (int)enemies.size(); j++) {
                if (!enemies[j].alive) continue;
                if (bullets[i].pos.x >= enemies[j].pos.x && bullets[i].pos.x <= enemies[j].pos.x + 2 &&
                    bullets[i].pos.y >= enemies[j].pos.y && bullets[i].pos.y <= enemies[j].pos.y + 1) {
                    // 敌人死亡,生成随机容器
                    int rt = rand() % 100;
                    ContainerType t;
                    if (rt < 40) t = CRATE_TYPE;
                    else if (rt < 55) t = WEAPON_BOX_TYPE;
                    else if (rt < 70) t = MEDICAL_BOX_TYPE;
                    else if (rt < 80) t = SAFE_TYPE;
                    else if (rt < 90) t = FILE_CABINET_TYPE;
                    else t = TOOLBOX_TYPE;
                    boxes.push_back(Box(enemies[j].pos.x, enemies[j].pos.y, false, t));
                    enemies[j].alive = false;
                    hit = true;
                    break;
                }
            }
            if (hit) {
                bullets.erase(bullets.begin() + i);
            } else {
                i++;
            }
        }
       // 移除死亡敌人
        for (int i = 0; i < (int)enemies.size(); ) {
            if (!enemies[i].alive) enemies.erase(enemies.begin() + i);
            else i++;
        }
    }
    
    void updateEnemies() {
        for (int i = 0; i < (int)enemies.size(); i++) {
            if (!enemies[i].alive) continue;
            int dx = 0, dy = 0;
            if (enemies[i].pos.x < manPos.x) dx = 1;
            else if (enemies[i].pos.x > manPos.x) dx = -1;
            if (enemies[i].pos.y < manPos.y) dy = 1;
            else if (enemies[i].pos.y > manPos.y) dy = -1;
            int newX = enemies[i].pos.x + dx;
            int newY = enemies[i].pos.y + dy;
            if (newX < 0) newX = 0;
            if (newX > SCREEN_W - 3) newX = SCREEN_W - 3;
            if (newY < 0) newY = 0;
            if (newY > SCREEN_H - 2) newY = SCREEN_H - 2;
            enemies[i].pos.x = newX;
            enemies[i].pos.y = newY;
        }
    }
    
    void damagePlayer(int dmg = 1) {
        playerHealth -= dmg;
        if (playerHealth <= 0) {
            gameOver = true;
            gameWin = false;
            return;
        }
        // 弹开
        if (!enemies.empty()) {
            int nearestIdx = findNearestEnemy(Point(manPos.x + 1, manPos.y + 1));
            if (nearestIdx != -1) {
                Point enemyCenter(enemies[nearestIdx].pos.x + 1, enemies[nearestIdx].pos.y + 1);
                int dx = manPos.x + 1 - enemyCenter.x;
                int dy = manPos.y + 1 - enemyCenter.y;
                if (dx != 0 || dy != 0) {
                    float len = sqrt(dx*dx + dy*dy);
                    dx = (int)(dx / len * 10);
                    dy = (int)(dy / len * 10);
                    manPos.x += dx;
                    manPos.y += dy;
                    if (manPos.x < 0) manPos.x = 0;
                    if (manPos.x > SCREEN_W - 3) manPos.x = SCREEN_W - 3;
                    if (manPos.y < 0) manPos.y = 0;
                    if (manPos.y > SCREEN_H - 3) manPos.y = SCREEN_H - 3;
                }
            }
        }
    }
    
    void checkCollision() {
        for (int i = 0; i < (int)enemies.size(); i++) {
            if (!enemies[i].alive) continue;
            if (manPos.x <= enemies[i].pos.x + 2 && manPos.x + 2 >= enemies[i].pos.x &&
                manPos.y <= enemies[i].pos.y + 1 && manPos.y + 2 >= enemies[i].pos.y) {
                damagePlayer(1);
                return;
            }
        }
    }
    
    void tryOpenBox() {
        for (int i = 0; i < (int)boxes.size(); i++) {
            if (boxes[i].isOpen) continue;
            int bx = boxes[i].pos.x, by = boxes[i].pos.y;
            int mx = manPos.x, my = manPos.y;
            if (mx <= bx + 2 && mx + 2 >= bx &&
                my <= by + 1 && my + 2 >= by) {
                boxes[i].isOpen = true;
                if (boxes[i].item) {
                    totalValue += boxes[i].item->price;
                    gotoxy(0, 27);
                    cout << "?? 打开" << getContainerSymbol(boxes[i].type) << " 获得 " << boxes[i].item->name << " (+" << (int)boxes[i].item->price << "金)                ";
                }
                Sleep(800);
                return;
            }
        }
    }
    void tryExtract() {
        int mx = manPos.x, my = manPos.y;
        int ex = extraction.pos.x, ey = extraction.pos.y;
        if (mx <= ex + 2 && mx + 2 >= ex &&
            my <= ey + 1 && my + 2 >= ey) {
            if (!enemies.empty()) {
                gotoxy(0, 27);
                cout << "?? 还有敌人!无法撤离。";
                Sleep(800);
                return;
            }
            gameOver = true;
            gameWin = true;
        } else {
            gotoxy(0, 27);
            cout << "? 你不在撤离点上!";
            Sleep(800);
        }
    }
    
    bool canMoveTo(int x, int y) {
        if (x < 0 || x > SCREEN_W - 3 || y < 0 || y > SCREEN_H - 3) return false;
        for (int i = 0; i < (int)enemies.size(); i++) {
            if (!enemies[i].alive) continue;
            if (x <= enemies[i].pos.x + 2 && x + 2 >= enemies[i].pos.x &&
                y <= enemies[i].pos.y + 1 && y + 2 >= enemies[i].pos.y) {
                return false;
            }
        }
        return true;
    }
    
    void draw() {
        system("cls");
        for (int i = 0; i < 3; i++) {
            gotoxy(manPos.x, manPos.y + i);
            cout << stickman[i];
        }
        for (int i = 0; i < (int)enemies.size(); i++) {
            if (!enemies[i].alive) continue;
            gotoxy(enemies[i].pos.x, enemies[i].pos.y);
            cout << "[E]";
            gotoxy(enemies[i].pos.x, enemies[i].pos.y + 1);
            cout << " ^ ";
        }
        for (int i = 0; i < (int)boxes.size(); i++) {
            gotoxy(boxes[i].pos.x, boxes[i].pos.y);
            if (!boxes[i].isOpen) {
                cout << getContainerSymbol(boxes[i].type);
                gotoxy(boxes[i].pos.x, boxes[i].pos.y + 1);
                cout << "~~~";
            } else {
                cout << "[开]";
                gotoxy(boxes[i].pos.x, boxes[i].pos.y + 1);
                cout << "   ";
            }
        }
        gotoxy(extraction.pos.x, extraction.pos.y);
        cout << "[G]";
        gotoxy(extraction.pos.x, extraction.pos.y + 1);
        cout << " ^ ";
        for (int i = 0; i < (int)bullets.size(); i++) {
            gotoxy(bullets[i].pos.x, bullets[i].pos.y);
            cout << "*";
        }
        gotoxy(0, SCREEN_H);
        cout << "生命: ";
        for (int i = 0; i < playerHealth; i++) cout << "?? ";
        cout << "  总价值: " << (int)totalValue << " 金  子弹速度: " << bulletSpeed;
        gotoxy(0, SCREEN_H + 1);
        cout << "WASD移动, 空格射击, F开箱, G撤离, Q退出";
        if (gameOver) {
            gotoxy(SCREEN_W / 2 - 8, SCREEN_H / 2);
            if (gameWin) {
                cout << "撤离成功!";
                gotoxy(SCREEN_W / 2 - 10, SCREEN_H / 2 + 1);
                cout << "获得总价值: " << (int)totalValue << " 金币";
            } else {
                cout << "撤离失败";
            }
        }
    }
    void handleInput() {
        if (_kbhit()) {
            char key = _getch();
            if (key == 'q' || key == 'Q') exit(0);
            if (gameOver) return;
            if (key == 'g' || key == 'G') {
                tryExtract();
                return;
            }
            if (key == 'f' || key == 'F') {
                tryOpenBox();
                return;
            }
            if (key == ' ') {
                shoot();
                return;
            }
            int newX = manPos.x, newY = manPos.y;
            switch (key) {
                case 'w': case 'W': newY--; break;
                case 's': case 'S': newY++; break;
                case 'a': case 'A': newX--; break;
                case 'd': case 'D': newX++; break;
                default: return;
            }
            if (canMoveTo(newX, newY)) {
                manPos.x = newX;
                manPos.y = newY;
            }
        }
    }
    
    int main() {
        srand((unsigned)time(0));
        hideCursor();
        for (int i = 0; i < 3; i++) {
            int x, y;
            do {
                x = rand() % (SCREEN_W - 3);
                y = rand() % (SCREEN_H - 2);
            } while (distance(Point(x, y), manPos) < 10);
            enemies.push_back(Enemy(x, y));
        }
        for (int i = 0; i < 5; i++) {
            int x = rand() % (SCREEN_W - 3);
            int y = rand() % (SCREEN_H - 2);
            if (distance(Point(x, y), manPos) > 5) {
                ContainerType t = (ContainerType)(rand() % 6);
                boxes.push_back(Box(x, y, false, t));
            }
        }
        while (!gameOver) {
            handleInput();
            updateBullets();
            updateEnemies();
            checkCollision();
            draw();
            Sleep(50);
        }
        draw();
        _getch();
        return 0;
    }
    

    信息

    ID
    101
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    103
    已通过
    21
    上传者