混沌迷局

#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <mmsystem.h>
#include <math.h>
#pragma comment(lib, "winmm.lib")
#define MAX_STACK_SIZE 1500
#define MAX_BLACKHOLES 30
#define MAX_SWORDS 10
#define MAX_POISONS 15
struct Maze;
struct Player;
struct Robot;
int canMove(struct Maze* maze, int row, int col, int direction);
void presentBuffer();
struct Cell {
    int visited;
    int walls[4];
    int row, col;
    int hasBlackHole;
    int blackHoleId;
    int hasSword;
    int swordId;
    int hasPoison;
    int poisonId;
};
struct Stack {
    int row[MAX_STACK_SIZE];
    int col[MAX_STACK_SIZE];
    int top;
};
struct Maze {
    struct Cell grid[50][60];
    int rows, cols;
    int cellSize;
    int startRow, startCol;
    int endRow, endCol;
    struct Stack stack;
};
struct Player {
    int row, col;
    int color;
    int imgData[25][25];
    int isTeleporting;
    int moveSpeed;
    int baseMoveSpeed;
    int hasMoved;
    int swordActive;
    clock_t swordStartTime;
    int poisoned;
    clock_t poisonStartTime;
    int poisonDuration;
    int speedBoostActive;
    clock_t speedBoostStartTime;
    int speedBoostDuration;
    int speedBoostCooldown;
    clock_t speedBoostCooldownStart;
    int speedBoostCooldownDuration;
    int lastKeyPressTime;
};
struct PathNode {
    int row, col;
    int parent;
    int g;
    int h;
    int f;
};
struct Robot {
    int row, col;
    int active;
    int startTime;
    int moveCounter;
    int moveDelay;
    int baseMoveDelay;
    int imgData[25][25];
    struct PathNode path[2000];
    int pathLength;
    int targetRow, targetCol;
    int lastPlayerRow, lastPlayerCol;
    int stuckCounter;
    int useTeleport;
    int swordDebuff;
    clock_t swordStartTime;
    int lastTeleportTime;
    int poisoned;
    clock_t poisonStartTime;
    int poisonDuration;
    int speedBoostActive;
    clock_t speedBoostStartTime;
    int speedBoostDuration;
    int speedBoostCooldown;
    clock_t speedBoostCooldownStart;
    int speedBoostCooldownDuration;
};
struct BlackHole {
    int row, col;
    int id;
    int active;
};
struct Sword {
    int row, col;
    int id;
    int active;
};
struct Poison {
    int row, col;
    int id;
    int active;
};
clock_t gameStartTime;
int robotDelay = 5000;
int playerFirstMove = 0;
struct BlackHole blackHoles[MAX_BLACKHOLES];
int blackHoleCount = 0;
int nextBlackHoleId = 1;
struct Sword swords[MAX_SWORDS];
int swordCount = 0;
int nextSwordId = 1;
struct Poison poisons[MAX_POISONS];
int poisonCount = 0;
int nextPoisonId = 1;
IMAGE* pBackBuffer = NULL;
int infoPanelWidth = 200;
void initStack(struct Stack* s) {
    s->top = -1;
}
void push(struct Stack* s, int row, int col) {
    if (s->top < MAX_STACK_SIZE - 1) {
        s->top++;
        s->row[s->top] = row;
        s->col[s->top] = col;
    }
}
void pop(struct Stack* s) {
    if (s->top >= 0) {
        s->top--;
    }
}
void top(struct Stack* s, int* row, int* col) {
    if (s->top >= 0) {
        *row = s->row[s->top];
        *col = s->col[s->top];
    }
}
int isStackEmpty(struct Stack* s) {
    return s->top == -1;
}
void initBlackHoles() {
    blackHoleCount = 0;
    nextBlackHoleId = 1;
    for (int i = 0; i < MAX_BLACKHOLES; i++) {
        blackHoles[i].active = 0;
    }
}
void generateBlackHole(struct Maze* maze) {
    if (blackHoleCount >= MAX_BLACKHOLES) return;
    int row, col;
    int attempts = 0;
    int maxAttempts = 2000;
    do {
        row = rand() % maze->rows;
        col = rand() % maze->cols;
        attempts++;
    } while ((row == maze->startRow && col == maze->startCol) || 
             (row == maze->endRow && col == maze->endCol) || 
             maze->grid[row][col].hasBlackHole || 
             maze->grid[row][col].hasSword || 
             maze->grid[row][col].hasPoison && attempts < maxAttempts);
    int id = nextBlackHoleId++;
    blackHoles[blackHoleCount].row = row;
    blackHoles[blackHoleCount].col = col;
    blackHoles[blackHoleCount].id = id;
    blackHoles[blackHoleCount].active = 1;
    blackHoleCount++;
    maze->grid[row][col].hasBlackHole = 1;
    maze->grid[row][col].blackHoleId = id;
}
void removeBlackHole(struct Maze* maze, int row, int col) {
    for (int i = 0; i < blackHoleCount; i++) {
        if (blackHoles[i].row == row && blackHoles[i].col == col) {
            blackHoles[i].active = 0;
            break;
        }
    }
    maze->grid[row][col].hasBlackHole = 0;
    maze->grid[row][col].blackHoleId = 0;
}
void initSwords() {
    swordCount = 0;
    nextSwordId = 1;
    for (int i = 0; i < MAX_SWORDS; i++) {
        swords[i].active = 0;
    }
}
void generateSword(struct Maze* maze) {
    if (swordCount >= MAX_SWORDS) return;
    int row, col;
    int attempts = 0;
    int maxAttempts = 2000;
    do {
        row = rand() % maze->rows;
        col = rand() % maze->cols;
        attempts++;
    } while ((row == maze->startRow && col == maze->startCol) || 
             (row == maze->endRow && col == maze->endCol) || 
             maze->grid[row][col].hasBlackHole || 
             maze->grid[row][col].hasSword || 
             maze->grid[row][col].hasPoison && attempts < maxAttempts);
    int id = nextSwordId++;
    swords[swordCount].row = row;
    swords[swordCount].col = col;
    swords[swordCount].id = id;
    swords[swordCount].active = 1;
    swordCount++;
    maze->grid[row][col].hasSword = 1;
    maze->grid[row][col].swordId = id;
}
void removeSword(struct Maze* maze, int row, int col) {
    for (int i = 0; i < swordCount; i++) {
        if (swords[i].row == row && swords[i].col == col) {
            swords[i].active = 0;
            break;
        }
    }
    maze->grid[row][col].hasSword = 0;
    maze->grid[row][col].swordId = 0;
}
void initPoisons() {
    poisonCount = 0;
    nextPoisonId = 1;
    for (int i = 0; i < MAX_POISONS; i++) {
        poisons[i].active = 0;
    }
}
void generatePoison(struct Maze* maze) {
    if (poisonCount >= MAX_POISONS) return;
    int row, col;
    int attempts = 0;
    int maxAttempts = 2000;
    do {
        row = rand() % maze->rows;
        col = rand() % maze->cols;
        attempts++;
    } while ((row == maze->startRow && col == maze->startCol) || 
             (row == maze->endRow && col == maze->endCol) || 
             maze->grid[row][col].hasBlackHole || 
             maze->grid[row][col].hasSword || 
             maze->grid[row][col].hasPoison && attempts < maxAttempts);
    int id = nextPoisonId++;
    poisons[poisonCount].row = row;
    poisons[poisonCount].col = col;
    poisons[poisonCount].id = id;
    poisons[poisonCount].active = 1;
    poisonCount++;
    maze->grid[row][col].hasPoison = 1;
    maze->grid[row][col].poisonId = id;
}
void removePoison(struct Maze* maze, int row, int col) {
    for (int i = 0; i < poisonCount; i++) {
        if (poisons[i].row == row && poisons[i].col == col) {
            poisons[i].active = 0;
            break;
        }
    }
    maze->grid[row][col].hasPoison = 0;
    maze->grid[row][col].poisonId = 0;
}
void checkPickupSword(struct Maze* maze, struct Player* player, struct Robot* robot) {
    int currentRow = player->row;
    int currentCol = player->col;
    if (maze->grid[currentRow][currentCol].hasSword) {
        removeSword(maze, currentRow, currentCol);
        player->swordActive = 1;
        player->swordStartTime = clock();
        robot->row = maze->startRow;
        robot->col = maze->startCol;
        robot->pathLength = 0;
        robot->swordDebuff = 1;
        robot->swordStartTime = clock();
        robot->moveDelay = robot->baseMoveDelay / 2;
        if (robot->moveDelay < 1) robot->moveDelay = 1;
        SetWorkingImage(pBackBuffer);
        settextcolor(YELLOW);
        settextstyle(30, 0, "楷体");
        setbkmode(TRANSPARENT);
        outtextxy(maze->cols * maze->cellSize / 2 - 150, 
                  maze->rows * maze->cellSize / 2 - 50, 
                  "获得宝剑!");
        outtextxy(maze->cols * maze->cellSize / 2 - 200, 
                  maze->rows * maze->cellSize / 2, 
                  "机器人回到起点!");
        outtextxy(maze->cols * maze->cellSize / 2 - 180, 
                  maze->rows * maze->cellSize / 2 + 50, 
                  "机器人速度翻倍!");
        SetWorkingImage(NULL);
        presentBuffer();
        Sleep(1500);
    }
}
void checkPlayerPoison(struct Maze* maze, struct Player* player) {
    int currentRow = player->row;
    int currentCol = player->col;
    if (maze->grid[currentRow][currentCol].hasPoison && !player->poisoned) {
        removePoison(maze, currentRow, currentCol);
        player->poisoned = 1;
        player->poisonStartTime = clock();
        player->poisonDuration = 2000;
    }
}
void checkRobotPoison(struct Maze* maze, struct Robot* robot) {
    int currentRow = robot->row;
    int currentCol = robot->col;
    if (maze->grid[currentRow][currentCol].hasPoison && !robot->poisoned) {
        removePoison(maze, currentRow, currentCol);
        robot->poisoned = 1;
        robot->poisonStartTime = clock();
        robot->poisonDuration = 2000;
        robot->pathLength = 0;
    }
}
void updatePoisonStatus(struct Player* player, struct Robot* robot) {
    clock_t currentTime = clock();
    if (player->poisoned) {
        if (currentTime - player->poisonStartTime >= player->poisonDuration) {
            player->poisoned = 0;
        }
    }
    if (robot->poisoned) {
        if (currentTime - robot->poisonStartTime >= robot->poisonDuration) {
            robot->poisoned = 0;
        }
    }
}
void updateSpeedBoostStatus(struct Player* player, struct Robot* robot) {
    clock_t currentTime = clock();
    if (player->speedBoostActive) {
        if (currentTime - player->speedBoostStartTime >= player->speedBoostDuration) {
            player->speedBoostActive = 0;
            player->moveSpeed = player->baseMoveSpeed;
        }
    }
    if (player->speedBoostCooldown) {
        if (currentTime - player->speedBoostCooldownStart >= player->speedBoostCooldownDuration) {
            player->speedBoostCooldown = 0;
        }
    }
    if (robot->speedBoostActive) {
        if (currentTime - robot->speedBoostStartTime >= robot->speedBoostDuration) {
            robot->speedBoostActive = 0;
            if (!robot->swordDebuff) {
                robot->moveDelay = robot->baseMoveDelay;
            }
        }
    }
    if (robot->speedBoostCooldown) {
        if (currentTime - robot->speedBoostCooldownStart >= robot->speedBoostCooldownDuration) {
            robot->speedBoostCooldown = 0;
        }
    }
}
void usePlayerSpeedBoost(struct Player* player) {
    clock_t currentTime = clock();
    if (player->speedBoostCooldown) {
        return;
    }
    player->speedBoostActive = 1;
    player->speedBoostStartTime = currentTime;
    player->speedBoostDuration = 3000;
    player->moveSpeed = player->baseMoveSpeed * 2 / 3;
    if (player->moveSpeed < 1) player->moveSpeed = 1;
    player->speedBoostCooldown = 1;
    player->speedBoostCooldownStart = currentTime;
    player->speedBoostCooldownDuration = 10000;
}
void useRobotSpeedBoost(struct Robot* robot) {
    clock_t currentTime = clock();
    if (robot->speedBoostCooldown) {
        return;
    }
    robot->speedBoostActive = 1;
    robot->speedBoostStartTime = currentTime;
    robot->speedBoostDuration = 3000;
    robot->moveDelay = robot->baseMoveDelay * 2 / 3;
    if (robot->moveDelay < 1) robot->moveDelay = 1;
    robot->speedBoostCooldown = 1;
    robot->speedBoostCooldownStart = currentTime;
    robot->speedBoostCooldownDuration = 10000;
}
int manhattanDistance(int r1, int c1, int r2, int c2) {
    return abs(r1 - r2) + abs(c1 - c2);
}
void checkPlayerTeleport(struct Maze* maze, struct Player* player) {
    if (player->isTeleporting) return;
    int currentRow = player->row;
    int currentCol = player->col;
    if (maze->grid[currentRow][currentCol].hasBlackHole) {
        player->isTeleporting = 1;
        int usedRow = currentRow;
        int usedCol = currentCol;
        int availableHoles[MAX_BLACKHOLES][2];
        int availableCount = 0;
        for (int i = 0; i < blackHoleCount; i++) {
            if (blackHoles[i].active) {
                if (!(blackHoles[i].row == currentRow && blackHoles[i].col == currentCol)) {
                    availableHoles[availableCount][0] = blackHoles[i].row;
                    availableHoles[availableCount][1] = blackHoles[i].col;
                    availableCount++;
                }
            }
        }
        removeBlackHole(maze, usedRow, usedCol);
        if (availableCount == 0) {
            int attempts = 0;
            int newRow, newCol;
            do {
                newRow = rand() % maze->rows;
                newCol = rand() % maze->cols;
                attempts++;
            } while ((newRow == currentRow && newCol == currentCol) && attempts < 100);
            player->row = newRow;
            player->col = newCol;
        } else {
            int index = rand() % availableCount;
            player->row = availableHoles[index][0];
            player->col = availableHoles[index][1];
        }
        for (int k = 0; k < 5; k++) {
            Sleep(50);
        }
        player->isTeleporting = 0;
    }
}
int checkRobotTeleport(struct Maze* maze, struct Robot* robot, struct Player* player) {
    int currentRow = robot->row;
    int currentCol = robot->col;
    if (maze->grid[currentRow][currentCol].hasBlackHole) {
        int usedRow = currentRow;
        int usedCol = currentCol;
        int availableHoles[MAX_BLACKHOLES][2];
        int availableCount = 0;
        for (int i = 0; i < blackHoleCount; i++) {
            if (blackHoles[i].active) {
                if (!(blackHoles[i].row == currentRow && blackHoles[i].col == currentCol)) {
                    availableHoles[availableCount][0] = blackHoles[i].row;
                    availableHoles[availableCount][1] = blackHoles[i].col;
                    availableCount++;
                }
            }
        }
        removeBlackHole(maze, usedRow, usedCol);
        if (availableCount == 0) {
            int attempts = 0;
            int newRow, newCol;
            do {
                newRow = rand() % maze->rows;
                newCol = rand() % maze->cols;
                attempts++;
            } while ((newRow == currentRow && newCol == currentCol) && attempts < 100);
            robot->row = newRow;
            robot->col = newCol;
        } else {
            int bestIndex = 0;
            int bestDistance = 10000;
            for (int i = 0; i < availableCount; i++) {
                int targetRow = availableHoles[i][0];
                int targetCol = availableHoles[i][1];
                int distanceToPlayer = manhattanDistance(targetRow, targetCol, player->row, player->col);
                if (distanceToPlayer < bestDistance) {
                    bestDistance = distanceToPlayer;
                    bestIndex = i;
                }
            }
            robot->row = availableHoles[bestIndex][0];
            robot->col = availableHoles[bestIndex][1];
        }
        robot->pathLength = 0;
        return 1;
    }
    return 0;
}
void initMaze(struct Maze* maze, int r, int c, int size) {
    int i, j, k;
    maze->rows = r;
    maze->cols = c;
    maze->cellSize = size;
    maze->startRow = 0;
    maze->startCol = 0;
    maze->endRow = r - 1;
    maze->endCol = c - 1;
    for (i = 0; i < r; i++) {
        for (j = 0; j < c; j++) {
            maze->grid[i][j].row = i;
            maze->grid[i][j].col = j;
            maze->grid[i][j].visited = 0;
            maze->grid[i][j].hasBlackHole = 0;
            maze->grid[i][j].blackHoleId = 0;
            maze->grid[i][j].hasSword = 0;
            maze->grid[i][j].swordId = 0;
            maze->grid[i][j].hasPoison = 0;
            maze->grid[i][j].poisonId = 0;
            for (k = 0; k < 4; k++) {
                maze->grid[i][j].walls[k] = 1;
            }
        }
    }
    initStack(&maze->stack);
    initBlackHoles();
    initSwords();
    initPoisons();
    int blackHoleCount = 6 + rand() % 5;
    for (i = 0; i < blackHoleCount; i++) {
        generateBlackHole(maze);
    }
    int swordCount = 2 + rand() % 2;
    for (i = 0; i < swordCount; i++) {
        generateSword(maze);
    }
    int poisonCount = 4 + rand() % 3;
    for (i = 0; i < poisonCount; i++) {
        generatePoison(maze);
    }
}
void initPlayerImage(struct Player* player) {
    int i, j;
    for (i = 0; i < 25; i++) {
        for (j = 0; j < 25; j++) {
            player->imgData[i][j] = BLUE;
        }
    }
    for (i = 6; i <= 10; i++) {
        for (j = 6; j <= 10; j++) {
            if ((i-8)*(i-8) + (j-8)*(j-8) <= 4) {
                player->imgData[i][j] = WHITE;
            }
        }
    }
    for (i = 6; i <= 10; i++) {
        for (j = 14; j <= 18; j++) {
            if ((i-8)*(i-8) + (j-16)*(j-16) <= 4) {
                player->imgData[i][j] = WHITE;
            }
        }
    }
    for (i = 7; i <= 9; i++) {
        for (j = 7; j <= 9; j++) {
            if ((i-8)*(i-8) + (j-8)*(j-8) <= 1) {
                player->imgData[i][j] = BLACK;
            }
        }
    }
    for (i = 7; i <= 9; i++) {
        for (j = 15; j <= 17; j++) {
            if ((i-8)*(i-8) + (j-16)*(j-16) <= 1) {
                player->imgData[i][j] = BLACK;
            }
        }
    }
    for (i = 14; i <= 18; i++) {
        for (j = 8; j <= 16; j++) {
            if (abs(i - 16) <= 2 && j > 8 && j < 16) {
                player->imgData[i][j] = YELLOW;
            }
        }
    }
}
void initRobotImage(struct Robot* robot) {
    int i, j;
    for (i = 0; i < 25; i++) {
        for (j = 0; j < 25; j++) {
            robot->imgData[i][j] = MAGENTA;
        }
    }
    for (i = 6; i <= 10; i++) {
        for (j = 6; j <= 10; j++) {
            if ((i-8)*(i-8) + (j-8)*(j-8) <= 4) {
                robot->imgData[i][j] = WHITE;
            }
        }
    }
    for (i = 6; i <= 10; i++) {
        for (j = 14; j <= 18; j++) {
            if ((i-8)*(i-8) + (j-16)*(j-16) <= 4) {
                robot->imgData[i][j] = WHITE;
            }
        }
    }
    for (i = 7; i <= 9; i++) {
        for (j = 7; j <= 9; j++) {
            if ((i-8)*(i-8) + (j-8)*(j-8) <= 1) {
                robot->imgData[i][j] = RED;
            }
        }
    }
    for (i = 7; i <= 9; i++) {
        for (j = 15; j <= 17; j++) {
            if ((i-8)*(i-8) + (j-16)*(j-16) <= 1) {
                robot->imgData[i][j] = RED;
            }
        }
    }
    for (i = 4; i <= 12; i++) {
        for (j = 4; j <= 12; j++) {
            if (abs(i - 8) == abs(j - 8) && abs(i - 8) <= 4) {
                robot->imgData[i][j] = BLACK;
            }
        }
    }
    for (i = 4; i <= 12; i++) {
        for (j = 12; j <= 20; j++) {
            if (abs(i - 8) == abs(j - 16) && abs(i - 8) <= 4) {
                robot->imgData[i][j] = BLACK;
            }
        }
    }
}
void drawBlackHole(int x, int y, int cellSize) {
    int centerX = x + cellSize / 2;
    int centerY = y + cellSize / 2;
    int maxRadius = cellSize / 2 - 2;
    for (int r = maxRadius; r > 0; r -= 2) {
        int color;
        if (r > maxRadius * 0.7) {
            color = DARKGRAY;
        } else if (r > maxRadius * 0.4) {
            color = MAGENTA;
        } else if (r > maxRadius * 0.2) {
            color = LIGHTMAGENTA;
        } else {
            color = BLACK;
        }
        for (int angle = 0; angle < 360; angle += 5) {
            float rad = angle * 3.14159 / 180;
            int px = centerX + (int)(r * cos(rad));
            int py = centerY + (int)(r * sin(rad));
            if (px > x + 1 && px < x + cellSize - 1 &&
                py > y + 1 && py < y + cellSize - 1) {
                putpixel(px, py, color);
            }
        }
    }
    setcolor(LIGHTMAGENTA);
    for (float t = 0; t < 2 * 3.14159 * 3; t += 0.1) {
        float r = maxRadius * 0.8 * (1 - t / (6 * 3.14159));
        if (r < 2) continue;
        int px = centerX + (int)(r * cos(t));
        int py = centerY + (int)(r * sin(t));
        if (px > x + 2 && px < x + cellSize - 2 &&
            py > y + 2 && py < y + cellSize - 2) {
            putpixel(px, py, WHITE);
        }
    }
    setfillcolor(BLACK);
    setcolor(BLACK);
    int innerRadius = maxRadius / 3;
    for (int dy = -innerRadius; dy <= innerRadius; dy++) {
        for (int dx = -innerRadius; dx <= innerRadius; dx++) {
            int px = centerX + dx;
            int py = centerY + dy;
            if (px > x && px < x + cellSize && py > y && py < y + cellSize) {
                if (dx*dx + dy*dy <= innerRadius*innerRadius) {
                    putpixel(px, py, BLACK);
                }
            }
        }
    }
    for (int i = 0; i < 5; i++) {
        int px = centerX - 4 + rand() % 9;
        int py = centerY - 4 + rand() % 9;
        if (px > x + 2 && px < x + cellSize - 2 &&
            py > y + 2 && py < y + cellSize - 2) {
            putpixel(px, py, WHITE);
        }
    }
}
void drawSword(int x, int y, int cellSize) {
    int centerX = x + cellSize / 2;
    int centerY = y + cellSize / 2;
    setfillcolor(BROWN);
    setcolor(BROWN);
    int handleWidth = cellSize / 5;
    int handleHeight = cellSize / 3;
    solidrectangle(centerX - handleWidth, centerY + handleHeight/2,
                   centerX + handleWidth, centerY + handleHeight);
    setcolor(DARKGRAY);
    for (int i = 0; i < 3; i++) {
        int yPos = centerY + handleHeight/2 + i * (handleHeight/3);
        line(centerX - handleWidth, yPos, centerX + handleWidth, yPos);
    }
    setfillcolor(YELLOW);
    setcolor(YELLOW);
    int pommelX = centerX;
    int pommelY = centerY + handleHeight * 3/4;
    for (int dy = -2; dy <= 2; dy++) {
        for (int dx = -2; dx <= 2; dx++) {
            if (dx*dx + dy*dy <= 4) {
                putpixel(pommelX + dx, pommelY + dy, YELLOW);
            }
        }
    }
    setfillcolor(YELLOW);
    setcolor(YELLOW);
    int guardWidth = cellSize / 2;
    int guardHeight = cellSize / 6;
    solidrectangle(centerX - guardWidth, centerY - guardHeight,
                   centerX + guardWidth, centerY + guardHeight);
    setcolor(RED);
    circle(centerX - guardWidth/2, centerY, 2);
    circle(centerX + guardWidth/2, centerY, 2);
    setfillcolor(RED);
    setcolor(RED);
    for (int dy = -1; dy <= 1; dy++) {
        for (int dx = -1; dx <= 1; dx++) {
            if (abs(dx) + abs(dy) <= 1) {
                putpixel(centerX - guardWidth/2 + dx, centerY + dy, RED);
                putpixel(centerX + guardWidth/2 + dx, centerY + dy, RED);
            }
        }
    }
    int bladeWidth = cellSize / 6;
    int bladeHeight = cellSize / 2 + 4;
    for (int i = 0; i < bladeHeight; i++) {
        int width = bladeWidth * (1 - i * 0.6 / bladeHeight);
        int left = centerX - width/2;
        int right = centerX + width/2;
        int yPos = centerY - bladeHeight/2 + i;
        int color;
        if (i < bladeHeight/3) {
            color = WHITE;
        } else if (i < bladeHeight*2/3) {
            color = LIGHTGRAY;
        } else {
            color = LIGHTGRAY;
        }
        for (int px = left; px <= right; px++) {
            putpixel(px, yPos, color);
        }
    }
    setcolor(WHITE);
    for (int i = 2; i < bladeHeight - 2; i++) {
        int yPos = centerY - bladeHeight/2 + i;
        putpixel(centerX, yPos, WHITE);
    }
    setcolor(WHITE);
    for (int i = 0; i < bladeHeight; i += 2) {
        int yPos = centerY - bladeHeight/2 + i;
        int width = bladeWidth * (1 - i * 0.6 / bladeHeight);
        putpixel(centerX - width/2, yPos, WHITE);
        putpixel(centerX + width/2, yPos, WHITE);
    }
    int tipX = centerX;
    int tipY = centerY - bladeHeight/2 - 2;
    setcolor(LIGHTMAGENTA);
    for (int dy = -2; dy <= 2; dy++) {
        for (int dx = -2; dx <= 2; dx++) {
            if (dx*dx + dy*dy <= 4) {
                putpixel(tipX + dx, tipY + dy, LIGHTMAGENTA);
            }
        }
    }
    setcolor(WHITE);
    for (int dy = -1; dy <= 1; dy++) {
        for (int dx = -1; dx <= 1; dx++) {
            if (abs(dx) + abs(dy) <= 1) {
                putpixel(tipX + dx, tipY + dy, WHITE);
            }
        }
    }
    for (int i = 0; i < 3; i++) {
        int offsetX = (rand() % 5) - 2;
        int offsetY = -2 - (rand() % 3);
        if (abs(offsetX) + abs(offsetY) < 4) {
            putpixel(tipX + offsetX, tipY + offsetY, LIGHTMAGENTA);
        }
    }
    for (int i = 0; i < 3; i++) {
        int fx = centerX - 2 + rand() % 5;
        int fy = centerY - bladeHeight/4 + rand() % (bladeHeight/2);
        if (rand() % 3 == 0) {
            putpixel(fx, fy, LIGHTBLUE);
        }
    }
}
void drawPoison(int x, int y, int cellSize) {
    int centerX = x + cellSize / 2;
    int centerY = y + cellSize / 2;
    int radius = cellSize / 3;
    for (int dy = -radius; dy <= radius; dy++) {
        for (int dx = -radius; dx <= radius; dx++) {
            int dist = dx*dx + dy*dy;
            if (dist <= radius*radius) {
                int color;
                if (dist < radius*radius/4) {
                    color = LIGHTGREEN;
                } else if (dist < radius*radius/2) {
                    color = GREEN;
                } else {
                    color = DARKGRAY;
                }
                int px = centerX + dx;
                int py = centerY + dy;
                if (px > x && px < x + cellSize && py > y && py < y + cellSize) {
                    putpixel(px, py, color);
                }
            }
        }
    }
    for (int i = 0; i < 3; i++) {
        int tailX = centerX - 2 + rand() % 5;
        int tailY = centerY + radius + 1 + rand() % 3;
        putpixel(tailX, tailY, GREEN);
    }
    for (int i = 0; i < 3; i++) {
        int bubbleX = centerX - 3 + rand() % 7;
        int bubbleY = centerY - 3 + rand() % 7;
        if (rand() % 2 == 0) {
            putpixel(bubbleX, bubbleY, WHITE);
        }
    }
    setcolor(LIGHTGREEN);
    for (int angle = 0; angle < 360; angle += 45) {
        float rad = angle * 3.14159 / 180;
        int px = centerX + (int)(radius * cos(rad));
        int py = centerY + (int)(radius * sin(rad));
        if (px > x && px < x + cellSize && py > y && py < y + cellSize) {
            putpixel(px, py, LIGHTGREEN);
        }
    }
}
void drawPlayerImage(struct Player* player, int x, int y) {
    int i, j;
    for (i = 0; i < 25; i++) {
        for (j = 0; j < 25; j++) {
            if (player->imgData[i][j] != -1) {
                putpixel(x + j, y + i, player->imgData[i][j]);
            }
        }
    }
    if (player->swordActive) {
        setcolor(YELLOW);
        setlinestyle(PS_DOT, 1);
        circle(x + 12, y + 12, 15);
        setlinestyle(PS_SOLID, 1);
    }
    if (player->poisoned) {
        setcolor(GREEN);
        setlinestyle(PS_DOT, 1);
        circle(x + 12, y + 12, 18);
        setlinestyle(PS_SOLID, 1);
    }
    if (player->speedBoostActive) {
        setcolor(CYAN);
        setlinestyle(PS_DOT, 1);
        circle(x + 12, y + 12, 21);
        setlinestyle(PS_SOLID, 1);
    }
}
void drawRobotImage(struct Robot* robot, int x, int y) {
    int i, j;
    for (i = 0; i < 25; i++) {
        for (j = 0; j < 25; j++) {
            if (robot->imgData[i][j] != -1) {
                putpixel(x + j, y + i, robot->imgData[i][j]);
            }
        }
    }
    if (robot->swordDebuff) {
        setcolor(RED);
        setlinestyle(PS_DOT, 2);
        circle(x + 12, y + 12, 18);
        setlinestyle(PS_SOLID, 1);
    }
    if (robot->poisoned) {
        setcolor(GREEN);
        setlinestyle(PS_DOT, 2);
        circle(x + 12, y + 12, 21);
        setlinestyle(PS_SOLID, 1);
    }
    if (robot->speedBoostActive) {
        setcolor(CYAN);
        setlinestyle(PS_DOT, 2);
        circle(x + 12, y + 12, 24);
        setlinestyle(PS_SOLID, 1);
    }
}
void drawInfoPanel(struct Maze* maze, struct Player* player, struct Robot* robot, int showCountdown, int countdownValue) {
    int panelX = maze->cols * maze->cellSize + 10;
    int panelY = 10;
    int panelWidth = infoPanelWidth - 20;
    setcolor(WHITE);
    rectangle(panelX - 5, panelY - 5, panelX + panelWidth + 5, maze->rows * maze->cellSize - 5);
    setfillcolor(DARKGRAY);
    setcolor(WHITE);
    settextstyle(20, 0, "宋体");
    setbkmode(TRANSPARENT);
    outtextxy(panelX, panelY, "=== 游戏信息 ===");
    panelY += 30;
    outtextxy(panelX, panelY, "【加速状态】");
    panelY += 25;
    char speedText[50];
    if (player->speedBoostActive) {
        int remainingTime = (player->speedBoostDuration - (clock() - player->speedBoostStartTime)) / 1000;
        sprintf(speedText, "加速中: %d秒", remainingTime + 1);
        setcolor(CYAN);
    } else if (player->speedBoostCooldown) {
        int remainingCooldown = (player->speedBoostCooldownDuration - (clock() - player->speedBoostCooldownStart)) / 1000;
        sprintf(speedText, "冷却中: %d秒", remainingCooldown + 1);
        setcolor(RED);
    } else {
        sprintf(speedText, "就绪 (WASD按下时)");
        setcolor(GREEN);
    }
    outtextxy(panelX, panelY, speedText);
    setcolor(WHITE);
    panelY += 30;
    outtextxy(panelX, panelY, "【敌我距离】");
    panelY += 25;
    if (robot->active) {
        int distance = manhattanDistance(player->row, player->col, robot->row, robot->col);
        char distText[50];
        sprintf(distText, "距离: %d 格", distance);
        if (distance <= 3) {
            setcolor(RED);
        } else if (distance <= 6) {
            setcolor(YELLOW);
        } else {
            setcolor(GREEN);
        }
        outtextxy(panelX, panelY, distText);
        setcolor(WHITE);
    } else {
        outtextxy(panelX, panelY, "机器人未激活");
    }
    panelY += 30;
    outtextxy(panelX, panelY, "【剩余道具】");
    panelY += 25;
    int activeBlackHoles = 0;
    int activeSwords = 0;
    int activePoisons = 0;
    for (int i = 0; i < blackHoleCount; i++) {
        if (blackHoles[i].active) activeBlackHoles++;
    }
    for (int i = 0; i < swordCount; i++) {
        if (swords[i].active) activeSwords++;
    }
    for (int i = 0; i < poisonCount; i++) {
        if (poisons[i].active) activePoisons++;
    }
    char blackHoleText[50];
    sprintf(blackHoleText, "黑洞: %d", activeBlackHoles);
    outtextxy(panelX, panelY, blackHoleText);
    panelY += 20;
    char swordText[50];
    sprintf(swordText, "宝剑: %d", activeSwords);
    setcolor(YELLOW);
    outtextxy(panelX, panelY, swordText);
    setcolor(WHITE);
    panelY += 20;
    char poisonText[50];
    sprintf(poisonText, "毒液: %d", activePoisons);
    setcolor(GREEN);
    outtextxy(panelX, panelY, poisonText);
    setcolor(WHITE);
    panelY += 30;
    outtextxy(panelX, panelY, "【机器人状态】");
    panelY += 25;
    if (robot->active) {
        if (robot->poisoned) {
            outtextxy(panelX, panelY, "中毒中");
        } else if (robot->speedBoostActive) {
            setcolor(CYAN);
            outtextxy(panelX, panelY, "加速中");
            setcolor(WHITE);
        } else if (robot->swordDebuff) {
            setcolor(RED);
            outtextxy(panelX, panelY, "速度翻倍");
            setcolor(WHITE);
        } else {
            outtextxy(panelX, panelY, "正常");
        }
    } else {
        outtextxy(panelX, panelY, "未激活");
    }
    panelY += 30;
    outtextxy(panelX, panelY, "【玩家状态】");
    panelY += 25;
    if (player->poisoned) {
        outtextxy(panelX, panelY, "中毒中");
    } else if (player->speedBoostActive) {
        setcolor(CYAN);
        outtextxy(panelX, panelY, "加速中");
        setcolor(WHITE);
    } else if (player->swordActive) {
        setcolor(YELLOW);
        outtextxy(panelX, panelY, "宝剑光环");
        setcolor(WHITE);
    } else {
        outtextxy(panelX, panelY, "正常");
    }
    panelY += 30;
    outtextxy(panelX, panelY, "【控制说明】");
    panelY += 25;
    outtextxy(panelX, panelY, "WASD: 移动/加速");
}
void drawMazeToBuffer(struct Maze* maze, struct Player* player, struct Robot* robot, int showCountdown, int countdownValue) {
    int i, j;
    int x, y;
    SetWorkingImage(pBackBuffer);
    cleardevice();
    setlinecolor(WHITE);
    setlinestyle(PS_SOLID, 1);
    for (i = 0; i < maze->rows; i++) {
        for (j = 0; j < maze->cols; j++) {
            x = j * maze->cellSize;
            y = i * maze->cellSize;
            setfillcolor(DARKGRAY);
            solidrectangle(x, y, x + maze->cellSize, y + maze->cellSize);
            setcolor(WHITE);
            if (maze->grid[i][j].walls[0]) {
                line(x, y, x + maze->cellSize, y);
            }
            if (maze->grid[i][j].walls[1]) {
                line(x + maze->cellSize, y, x + maze->cellSize, y + maze->cellSize);
            }
            if (maze->grid[i][j].walls[2]) {
                line(x, y + maze->cellSize, x + maze->cellSize, y + maze->cellSize);
            }
            if (maze->grid[i][j].walls[3]) {
                line(x, y, x, y + maze->cellSize);
            }
        }
    }
    for (i = 0; i < maze->rows; i++) {
        for (j = 0; j < maze->cols; j++) {
            if (maze->grid[i][j].hasBlackHole) {
                x = j * maze->cellSize;
                y = i * maze->cellSize;
                drawBlackHole(x, y, maze->cellSize);
            }
        }
    }
    for (i = 0; i < maze->rows; i++) {
        for (j = 0; j < maze->cols; j++) {
            if (maze->grid[i][j].hasSword) {
                x = j * maze->cellSize;
                y = i * maze->cellSize;
                drawSword(x, y, maze->cellSize);
            }
        }
    }
    for (i = 0; i < maze->rows; i++) {
        for (j = 0; j < maze->cols; j++) {
            if (maze->grid[i][j].hasPoison) {
                x = j * maze->cellSize;
                y = i * maze->cellSize;
                drawPoison(x, y, maze->cellSize);
            }
        }
    }
    setfillcolor(GREEN);
    setcolor(GREEN);
    x = maze->startCol * maze->cellSize + maze->cellSize / 4;
    y = maze->startRow * maze->cellSize + maze->cellSize / 4;
    solidrectangle(x, y, x + maze->cellSize / 2, y + maze->cellSize / 2);
    setfillcolor(RED);
    setcolor(RED);
    x = maze->endCol * maze->cellSize + maze->cellSize / 4;
    y = maze->endRow * maze->cellSize + maze->cellSize / 4;
    solidrectangle(x, y, x + maze->cellSize / 2, y + maze->cellSize / 2);
    x = player->col * maze->cellSize + (maze->cellSize - 25) / 2;
    y = player->row * maze->cellSize + (maze->cellSize - 25) / 2;
    drawPlayerImage(player, x, y);
    if (robot->active) {
        x = robot->col * maze->cellSize + (maze->cellSize - 25) / 2;
        y = robot->row * maze->cellSize + (maze->cellSize - 25) / 2;
        drawRobotImage(robot, x, y);
    }
    drawInfoPanel(maze, player, robot, showCountdown, countdownValue);
    if (showCountdown && !robot->active) {
        settextcolor(RED);
        settextstyle(40, 0, "Arial");
        setbkmode(TRANSPARENT);
        char countdownText[10];
        sprintf(countdownText, "%d", countdownValue);
        outtextxy(maze->cols * maze->cellSize / 2 - 20, 
                  maze->rows * maze->cellSize / 2 - 20, 
                  countdownText);
    }
    SetWorkingImage(NULL);
}
void presentBuffer() {
    putimage(0, 0, pBackBuffer);
}
int findPathWithPoison(struct Maze* maze, struct Robot* robot, int targetRow, int targetCol) {
    int openList[2000][2];
    int openCount = 0;
    int closed[50][60] = {0};
    struct PathNode nodes[50][60];
    int parent[50][60][2];
    for (int i = 0; i < maze->rows; i++) {
        for (int j = 0; j < maze->cols; j++) {
            nodes[i][j].g = 10000;
            int poisonPenalty = 0;
            if (maze->grid[i][j].hasPoison) {
                poisonPenalty = 5;
            }
            nodes[i][j].h = abs(i - targetRow) + abs(j - targetCol) + poisonPenalty;
            nodes[i][j].f = 10000;
            parent[i][j][0] = -1;
            parent[i][j][1] = -1;
        }
    }
    nodes[robot->row][robot->col].g = 0;
    nodes[robot->row][robot->col].f = nodes[robot->row][robot->col].h;
    openList[openCount][0] = robot->row;
    openList[openCount][1] = robot->col;
    openCount++;
    while (openCount > 0) {
        int minIndex = 0;
        for (int i = 1; i < openCount; i++) {
            if (nodes[openList[i][0]][openList[i][1]].f < 
                nodes[openList[minIndex][0]][openList[minIndex][1]].f) {
                minIndex = i;
            }
        }
        int currentRow = openList[minIndex][0];
        int currentCol = openList[minIndex][1];
        if (currentRow == targetRow && currentCol == targetCol) {
            robot->pathLength = 0;
            int r = currentRow, c = currentCol;
            while (r != robot->row || c != robot->col) {
                robot->path[robot->pathLength].row = r;
                robot->path[robot->pathLength].col = c;
                robot->pathLength++;
                int pr = parent[r][c][0];
                int pc = parent[r][c][1];
                if (pr == -1) break;
                r = pr;
                c = pc;
            }
            for (int i = 0; i < robot->pathLength / 2; i++) {
                struct PathNode temp = robot->path[i];
                robot->path[i] = robot->path[robot->pathLength - 1 - i];
                robot->path[robot->pathLength - 1 - i] = temp;
            }
            return 1;
        }
        for (int i = minIndex; i < openCount - 1; i++) {
            openList[i][0] = openList[i+1][0];
            openList[i][1] = openList[i+1][1];
        }
        openCount--;
        closed[currentRow][currentCol] = 1;
        int dr[4] = {-1, 0, 1, 0};
        int dc[4] = {0, 1, 0, -1};
        for (int i = 0; i < 4; i++) {
            int newRow = currentRow + dr[i];
            int newCol = currentCol + dc[i];
            if (newRow >= 0 && newRow < maze->rows && 
                newCol >= 0 && newCol < maze->cols && 
                !closed[newRow][newCol]) {
                if (i == 0 && maze->grid[currentRow][currentCol].walls[0]) continue;
                if (i == 1 && maze->grid[currentRow][currentCol].walls[1]) continue;
                if (i == 2 && maze->grid[currentRow][currentCol].walls[2]) continue;
                if (i == 3 && maze->grid[currentRow][currentCol].walls[3]) continue;
                int moveCost = 1;
                if (maze->grid[newRow][newCol].hasPoison) {
                    moveCost = 5;
                }
                int newG = nodes[currentRow][currentCol].g + moveCost;
                int inOpen = 0;
                for (int j = 0; j < openCount; j++) {
                    if (openList[j][0] == newRow && openList[j][1] == newCol) {
                        inOpen = 1;
                        break;
                    }
                }
                if (!inOpen || newG < nodes[newRow][newCol].g) {
                    nodes[newRow][newCol].g = newG;
                    nodes[newRow][newCol].f = newG + nodes[newRow][newCol].h;
                    parent[newRow][newCol][0] = currentRow;
                    parent[newRow][newCol][1] = currentCol;
                    if (!inOpen) {
                        openList[openCount][0] = newRow;
                        openList[openCount][1] = newCol;
                        openCount++;
                    }
                }
            }
        }
    }
    return 0;
}
void moveRobot(struct Maze* maze, struct Robot* robot, struct Player* player) {
    if (!robot->active) return;
    if (robot->poisoned) {
        return;
    }
    robot->moveCounter++;
    if (robot->moveCounter < robot->moveDelay) {
        return;
    }
    robot->moveCounter = 0;
    robot->lastPlayerRow = player->row;
    robot->lastPlayerCol = player->col;
    robot->useTeleport = 1;
    if (robot->useTeleport) {
        if (maze->grid[robot->row][robot->col].hasBlackHole) {
            if (checkRobotTeleport(maze, robot, player)) {
                robot->pathLength = 0;
                return;
            }
        }
    }
    if (!robot->speedBoostActive && !robot->speedBoostCooldown) {
        int distanceToPlayer = manhattanDistance(robot->row, robot->col, player->row, player->col);
        if (distanceToPlayer > 5) {
            useRobotSpeedBoost(robot);
        }
    }
    static int pathCalcCounter = 0;
    pathCalcCounter++;
    if (pathCalcCounter >= 1 || robot->pathLength == 0 || 
        robot->targetRow != player->row || robot->targetCol != player->col) {
        pathCalcCounter = 0;
        if (findPathWithPoison(maze, robot, player->row, player->col)) {
            robot->targetRow = player->row;
            robot->targetCol = player->col;
        }
    }
    if (robot->pathLength > 0) {
        robot->row = robot->path[0].row;
        robot->col = robot->path[0].col;
        checkRobotPoison(maze, robot);
        for (int i = 0; i < robot->pathLength - 1; i++) {
            robot->path[i] = robot->path[i+1];
        }
        robot->pathLength--;
    } else {
        int bestDirection = -1;
        int minDist = 10000;
        for (int dir = 0; dir < 4; dir++) {
            int newRow = robot->row;
            int newCol = robot->col;
            if (dir == 0 && canMove(maze, robot->row, robot->col, 0)) newRow--;
            else if (dir == 1 && canMove(maze, robot->row, robot->col, 1)) newCol++;
            else if (dir == 2 && canMove(maze, robot->row, robot->col, 2)) newRow++;
            else if (dir == 3 && canMove(maze, robot->row, robot->col, 3)) newCol--;
            else continue;
            int dist = abs(newRow - player->row) + abs(newCol - player->col);
            if (maze->grid[newRow][newCol].hasPoison) {
                dist += 5;
            }
            if (dist < minDist) {
                minDist = dist;
                bestDirection = dir;
            }
        }
        if (bestDirection != -1) {
            if (bestDirection == 0) robot->row--;
            else if (bestDirection == 1) robot->col++;
            else if (bestDirection == 2) robot->row++;
            else if (bestDirection == 3) robot->col--;
            checkRobotPoison(maze, robot);
        }
    }
}
int checkRobotCatch(struct Robot* robot, struct Player* player) {
    return (robot->active && robot->row == player->row && robot->col == player->col);
}
void showLoseMessage(int height, int width, struct Maze* maze, struct Player* player, struct Robot* robot) {
    settextcolor(RED);
    settextstyle(30, 0, "楷体");
    setbkmode(TRANSPARENT);
    for (int i = 0; i < 5; i++) {
        drawMazeToBuffer(maze, player, robot, 0, 0);
        SetWorkingImage(pBackBuffer);
        outtextxy(width/2 - 120, height/2 - 20, "游戏结束!");
        outtextxy(width/2 - 120, height/2 + 20, "被机器人抓住了!");
        SetWorkingImage(NULL);
        presentBuffer();
        Sleep(200);
        drawMazeToBuffer(maze, player, robot, 0, 0);
        presentBuffer();
        Sleep(100);
    }
}
void movePlayerSmooth(struct Maze* maze, struct Player* player, struct Robot* robot, int direction, int* playerFirstMove, clock_t* gameStartTime) {
    if (player->poisoned) {
        return;
    }
    if (canMove(maze, player->row, player->col, direction)) {
        if (!(*playerFirstMove)) {
            *playerFirstMove = 1;
            *gameStartTime = clock();
        }
        clock_t currentTime = clock();
        if (currentTime - player->lastKeyPressTime < 200) {
            usePlayerSpeedBoost(player);
        }
        player->lastKeyPressTime = currentTime;
        int startCol = player->col;
        int startRow = player->row;
        int endCol = player->col;
        int endRow = player->row;
        int steps = player->moveSpeed;
        if (direction == 0) endRow--;
        else if (direction == 1) endCol++;
        else if (direction == 2) endRow++;
        else if (direction == 3) endCol--;
        for (int i = 1; i <= steps; i++) {
            float t = (float)i / steps;
            int currentCol = startCol + (int)((endCol - startCol) * t + 0.5);
            int currentRow = startRow + (int)((endRow - startRow) * t + 0.5);
            drawMazeToBuffer(maze, player, robot, 0, 0);
            SetWorkingImage(pBackBuffer);
            int x = currentCol * maze->cellSize + (maze->cellSize - 25) / 2;
            int y = currentRow * maze->cellSize + (maze->cellSize - 25) / 2;
            drawPlayerImage(player, x, y);
            SetWorkingImage(NULL);
            presentBuffer();
            Sleep(8);
        }
        player->row = endRow;
        player->col = endCol;
        checkPlayerTeleport(maze, player);
        checkPickupSword(maze, player, robot);
        checkPlayerPoison(maze, player);
        drawMazeToBuffer(maze, player, robot, 0, 0);
        presentBuffer();
    }
}
void drawMaze(struct Maze* maze, struct Player* player, struct Robot* robot, int showCountdown, int countdownValue) {
    drawMazeToBuffer(maze, player, robot, showCountdown, countdownValue);
    presentBuffer();
}
int getUnvisitedNeighbor(struct Maze* maze, int row, int col, 
                         int* nRow, int* nCol) {
    int neighbors[4][2];
    int count = 0;
    if (row > 0 && !maze->grid[row-1][col].visited) {
        neighbors[count][0] = row - 1;
        neighbors[count][1] = col;
        count++;
    }
    if (col < maze->cols - 1 && !maze->grid[row][col+1].visited) {
        neighbors[count][0] = row;
        neighbors[count][1] = col + 1;
        count++;
    }
    if (row < maze->rows - 1 && !maze->grid[row+1][col].visited) {
        neighbors[count][0] = row + 1;
        neighbors[count][1] = col;
        count++;
    }
    if (col > 0 && !maze->grid[row][col-1].visited) {
        neighbors[count][0] = row;
        neighbors[count][1] = col - 1;
        count++;
    }
    if (count == 0) return 0;
    int index = rand() % count;
    *nRow = neighbors[index][0];
    *nCol = neighbors[index][1];
    return 1;
}
void removeWalls(struct Maze* maze, int row1, int col1, int row2, int col2) {
    if (row2 < row1) {
        maze->grid[row1][col1].walls[0] = 0;
        maze->grid[row2][col2].walls[2] = 0;
    }
    else if (col2 > col1) {
        maze->grid[row1][col1].walls[1] = 0;
        maze->grid[row2][col2].walls[3] = 0;
    }
    else if (row2 > row1) {
        maze->grid[row1][col1].walls[2] = 0;
        maze->grid[row2][col2].walls[0] = 0;
    }
    else if (col2 < col1) {
        maze->grid[row1][col1].walls[3] = 0;
        maze->grid[row2][col2].walls[1] = 0;
    }
}
void generateMaze(struct Maze* maze) {
    int currentRow, currentCol;
    int nextRow, nextCol;
    maze->grid[0][0].visited = 1;
    push(&maze->stack, 0, 0);
    while (!isStackEmpty(&maze->stack)) {
        top(&maze->stack, &currentRow, &currentCol);
        if (getUnvisitedNeighbor(maze, currentRow, currentCol, 
                                 &nextRow, &nextCol)) {
            maze->grid[nextRow][nextCol].visited = 1;
            removeWalls(maze, currentRow, currentCol, nextRow, nextCol);
            push(&maze->stack, nextRow, nextCol);
        }
        else {
            pop(&maze->stack);
        }
    }
    int extraWallsToRemove = (maze->rows * maze->cols) / 12;
    for (int i = 0; i < extraWallsToRemove; i++) {
        int row = rand() % maze->rows;
        int col = rand() % maze->cols;
        int wallDir = rand() % 4;
        if (wallDir == 0 && row > 0) {
            maze->grid[row][col].walls[0] = 0;
            maze->grid[row-1][col].walls[2] = 0;
        } else if (wallDir == 1 && col < maze->cols - 1) {
            maze->grid[row][col].walls[1] = 0;
            maze->grid[row][col+1].walls[3] = 0;
        } else if (wallDir == 2 && row < maze->rows - 1) {
            maze->grid[row][col].walls[2] = 0;
            maze->grid[row+1][col].walls[0] = 0;
        } else if (wallDir == 3 && col > 0) {
            maze->grid[row][col].walls[3] = 0;
            maze->grid[row][col-1].walls[1] = 0;
        }
    }
    maze->grid[maze->startRow][maze->startCol].walls[0] = 0;
    maze->grid[maze->endRow][maze->endCol].walls[2] = 0;
}
int canMove(struct Maze* maze, int row, int col, int direction) {
    if (direction == 0 && row > 0 && !maze->grid[row][col].walls[0]) return 1;
    if (direction == 1 && col < maze->cols - 1 && !maze->grid[row][col].walls[1]) return 1;
    if (direction == 2 && row < maze->rows - 1 && !maze->grid[row][col].walls[2]) return 1;
    if (direction == 3 && col > 0 && !maze->grid[row][col].walls[3]) return 1;
    return 0;
}
int checkWin(struct Player* player, struct Maze* maze) {
    return (player->row == maze->endRow && player->col == maze->endCol);
}
void showWinMessage(int height, int width, struct Maze* maze, struct Player* player, struct Robot* robot) {
    settextcolor(YELLOW);
    settextstyle(30, 0, "楷体");
    setbkmode(TRANSPARENT);
    for (int i = 0; i < 5; i++) {
        drawMazeToBuffer(maze, player, robot, 0, 0);
        SetWorkingImage(pBackBuffer);
        outtextxy(width/2 - 60, height/2 - 20, "你赢了!");
        SetWorkingImage(NULL);
        presentBuffer();
        Sleep(100);
        drawMazeToBuffer(maze, player, robot, 0, 0);
        presentBuffer();
        Sleep(50);
    }
}
int main() {
    srand((unsigned)time(NULL));
    int rows = 30;
    int cols = 35;
    int cellSize = 28;
    int width = cols * cellSize + infoPanelWidth;
    int height = rows * cellSize;
    initgraph(width, height);
    pBackBuffer = new IMAGE(width, height);
    struct Maze maze;
    struct Player player;
    struct Robot robot;
    int playerFirstMove = 0;
    initMaze(&maze, rows, cols, cellSize);
    player.row = maze.startRow;
    player.col = maze.startCol;
    player.color = BLUE;
    player.isTeleporting = 0;
    player.baseMoveSpeed = 5;
    player.moveSpeed = player.baseMoveSpeed;
    player.hasMoved = 0;
    player.swordActive = 0;
    player.swordStartTime = 0;
    player.poisoned = 0;
    player.speedBoostActive = 0;
    player.speedBoostCooldown = 0;
    player.lastKeyPressTime = 0;
    robot.row = 0;
    robot.col = 0;
    robot.active = 0;
    robot.startTime = 0;
    robot.baseMoveDelay = 6;
    robot.moveDelay = robot.baseMoveDelay;
    robot.pathLength = 0;
    robot.lastPlayerRow = 0;
    robot.lastPlayerCol = 0;
    robot.stuckCounter = 0;
    robot.useTeleport = 1;
    robot.swordDebuff = 0;
    robot.poisoned = 0;
    robot.speedBoostActive = 0;
    robot.speedBoostCooldown = 0;
    initPlayerImage(&player);
    initRobotImage(&robot);
    setbkcolor(BLACK);
    cleardevice();
    int running = 1;
    int gameActive = 1;
    int gameOver = 0;
    char key;
    clock_t gameStartTime = 0;
    while (running) {
        if (gameActive) {
            generateMaze(&maze);
            player.row = maze.startRow;
            player.col = maze.startCol;
            player.swordActive = 0;
            player.moveSpeed = player.baseMoveSpeed;
            player.poisoned = 0;
            player.speedBoostActive = 0;
            player.speedBoostCooldown = 0;
            robot.row = 0;
            robot.col = 0;
            robot.active = 0;
            robot.startTime = 0;
            robot.baseMoveDelay = 6;
            robot.moveDelay = robot.baseMoveDelay;
            robot.pathLength = 0;
            robot.lastPlayerRow = 0;
            robot.lastPlayerCol = 0;
            robot.stuckCounter = 0;
            robot.useTeleport = 1;
            robot.swordDebuff = 0;
            robot.poisoned = 0;
            robot.speedBoostActive = 0;
            robot.speedBoostCooldown = 0;
            playerFirstMove = 0;
            gameOver = 0;
        }
        while (gameActive && !gameOver) {
            int showCountdown = 0;
            int countdownValue = 0;
            if (playerFirstMove && !robot.active) {
                int elapsedTime = clock() - gameStartTime;
                int remainingTime = (robotDelay - elapsedTime) / 1000 + 1;
                if (remainingTime > 0 && remainingTime <= 5) {
                    showCountdown = 1;
                    countdownValue = remainingTime;
                }
            }
            updatePoisonStatus(&player, &robot);
            updateSpeedBoostStatus(&player, &robot);
            drawMaze(&maze, &player, &robot, showCountdown, countdownValue);
            if (playerFirstMove && !robot.active) {
                if (clock() - gameStartTime >= robotDelay) {
                    robot.active = 1;
                }
            }
            if (robot.active) {
                moveRobot(&maze, &robot, &player);
                if (checkRobotCatch(&robot, &player)) {
                    gameOver = 1;
                    drawMaze(&maze, &player, &robot, 0, 0);
                    showLoseMessage(height, width, &maze, &player, &robot);
                    break;
                }
            }
            if (kbhit()) {
                key = getch();
                if (key == 'w' || key == 'W') {
                    movePlayerSmooth(&maze, &player, &robot, 0, &playerFirstMove, &gameStartTime);
                }
                else if (key == 'd' || key == 'D') {
                    movePlayerSmooth(&maze, &player, &robot, 1, &playerFirstMove, &gameStartTime);
                }
                else if (key == 's' || key == 'S') {
                    movePlayerSmooth(&maze, &player, &robot, 2, &playerFirstMove, &gameStartTime);
                }
                else if (key == 'a' || key == 'A') {
                    movePlayerSmooth(&maze, &player, &robot, 3, &playerFirstMove, &gameStartTime);
                }
            }
            if (robot.active && checkRobotCatch(&robot, &player)) {
                gameOver = 1;
                drawMaze(&maze, &player, &robot, 0, 0);
                showLoseMessage(height, width, &maze, &player, &robot);
                break;
            }
            if (checkWin(&player, &maze)) {
                drawMaze(&maze, &player, &robot, 0, 0);
                showWinMessage(height, width, &maze, &player, &robot);
                break;
            }
            Sleep(10);
        }
    }
    delete pBackBuffer;
    closegraph();
    return 0;
}