混沌迷局
#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, ¤tRow, ¤tCol);
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;
}