#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <string.h>
#include <conio.h>
#define ROW 10
#define COL 10
// 控制台颜色定义
#define RED 12
#define GREEN 10
#define BLUE 9
#define WHITE 15
#define YELLOW 14
// 迷宫地图
char maze[ROW][COL];
// 记录访问状态
int visited[ROW][COL];
// 坐标结构体
typedef struct {
int x, y;
} Node;
// 路径结构体
typedef struct {
Node* nodes;
int size;
int capacity;
} Path;
// 全局变量存储所有路径
Path allPaths[1000];
int pathCount = 0;
// 设置控制台颜色
void setColor(int color) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
// 清屏 - 改为只移动光标而不清屏
void clearScreen() {
//清屏
system("cls");
// 将光标移动到左上角
// COORD coord = {0, 0};
// SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
// 等待指定毫秒
void wait(int ms) {
Sleep(ms);
}
// 初始化路径
void initPath(Path* path) {
path->nodes = NULL;
path->size = 0;
path->capacity = 0;
}
// 添加节点到路径
void addToPath(Path* path, Node node) {
if (path->size >= path->capacity) {
path->capacity = path->capacity == 0 ? 1 : path->capacity * 2;
path->nodes = (Node*)realloc(path->nodes, path->capacity * sizeof(Node));
}
path->nodes[path->size++] = node;
}
// 释放路径内存
void freePath(Path* path) {
if (path->nodes != NULL) {
free(path->nodes);
path->nodes = NULL;
}
path->size = 0;
path->capacity = 0;
}
// 复制路径
void copyPath(Path* dest, Path* src) {
dest->size = src->size;
dest->capacity = src->capacity;
dest->nodes = (Node*)malloc(dest->capacity * sizeof(Node));
memcpy(dest->nodes, src->nodes, src->size * sizeof(Node));
}
// 初始化迷宫
void initMaze() {
// 初始化为全墙
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
maze[i][j] = '1';
}
}
}
// 判断是否可以走
int isValid(int x, int y) {
return x >= 0 && x < ROW && y >= 0 && y < COL &&
(maze[x][y] == '0' || maze[x][y] == 'E') && !visited[x][y];
}
// 重置访问状态
void resetVisited() {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
visited[i][j] = 0;
}
}
}
// 检查迷宫是否可解(BFS算法)
int isMazeSolvable() {
resetVisited();
// 使用数组模拟队列
Node queue[ROW * COL];
int front = 0, rear = 0;
int dir[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}}; // 右、下、左、上
Node start = {1, 0}; // S 的位置
queue[rear++] = start;
visited[start.x][start.y] = 1;
while (front < rear) {
Node cur = queue[front++];
if (maze[cur.x][cur.y] == 'E') {
return 1; // 找到终点,迷宫可解
}
for (int i = 0; i < 4; i++) {
int nx = cur.x + dir[i][0];
int ny = cur.y + dir[i][1];
if (isValid(nx, ny)) {
visited[nx][ny] = 1;
Node next = {nx, ny};
queue[rear++] = next;
}
}
}
return 0; // 未找到路径,迷宫不可解
}
// 随机生成迷宫并确保可解
void generateValidMaze() {
int attempts = 0;
const int max_attempts = 100; // 最大尝试次数
do {
attempts++;
if (attempts > max_attempts) {
printf("无法生成可解迷宫,请调整参数后重试!\n");
exit(1);
}
srand((unsigned int)time(NULL) + attempts);
initMaze();
// 设置起点和终点
maze[1][0] = 'S'; // 起点
maze[ROW-2][COL-1] = 'E'; // 终点
// 随机生成通路
for (int i = 1; i < ROW-1; i++) {
for (int j = 1; j < COL-1; j++) {
if (rand() % 100 < 70) { // 70%概率是通路
maze[i][j] = '0';
}
}
}
// 确保起点和终点附近有通路
maze[1][1] = '0';
maze[ROW-2][COL-2] = '0';
} while (!isMazeSolvable());
printf("生成有效迷宫,尝试次数: %d\n", attempts);
}
// 打印当前迷宫状态
void printMaze(int fullRedraw) {
static char lastMaze[ROW][COL] = {0};
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
// 只重绘发生变化的部分
if (fullRedraw || maze[i][j] != lastMaze[i][j]) {
// 移动光标到指定位置
COORD coord = {(SHORT)(j*2), (SHORT)i};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
char ch = maze[i][j];
if (ch == 'X') setColor(RED);
else if (ch == 'B') setColor(BLUE);
else if (ch == 'E') setColor(GREEN);
else if (ch == 'S') setColor(YELLOW);
else if (ch == 'P') setColor(GREEN); // 最终路径
else setColor(WHITE);
printf("%c ", ch);
lastMaze[i][j] = maze[i][j];
}
}
}
setColor(WHITE);
}
// 迷宫路径搜索(使用栈实现深度优先)
void solveMazeDFS_Stack() {
resetVisited();
// 使用数组模拟栈
Node stack[ROW * COL];
Path paths[ROW * COL];
int top = -1;
int dir[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}}; // 右、下、左、上
Node start = {1, 0}; // S 的位置
Path startPath;
initPath(&startPath);
addToPath(&startPath, start);
stack[++top] = start;
paths[top] = startPath;
visited[start.x][start.y] = 1;
// 初始全绘制
printMaze(1);
wait(100);
while (top >= 0) {
Node cur = stack[top];
Path curPath = paths[top];
top--;
if (maze[cur.x][cur.y] != 'S' && maze[cur.x][cur.y] != 'E') {
maze[cur.x][cur.y] = 'X'; // 红色路径
}
// 动态显示 - 减少刷新频率
static int counter = 0;
if (++counter % 5 == 0) { // 每5步刷新一次
printMaze(0);
wait(50); // 减少等待时间
}
if (maze[cur.x][cur.y] == 'E') {
// 找到终点,标记路径
for (int i = 0; i < curPath.size; i++) {
Node node = curPath.nodes[i];
if (maze[node.x][node.y] != 'S' && maze[node.x][node.y] != 'E') {
maze[node.x][node.y] = 'P';
}
}
freePath(&curPath);
break;
}
for (int i = 0; i < 4; i++) {
int nx = cur.x + dir[i][0];
int ny = cur.y + dir[i][1];
if (isValid(nx, ny)) {
visited[nx][ny] = 1;
Node next = {nx, ny};
Path newPath;
initPath(&newPath);
copyPath(&newPath, &curPath);
addToPath(&newPath, next);
stack[++top] = next;
paths[top] = newPath;
}
}
freePath(&curPath);
// 回退路径标记为蓝色
if (maze[cur.x][cur.y] == 'X') {
maze[cur.x][cur.y] = 'B';
}
}
// 最终展示结果
printMaze(1);
}
// 队列实现的广度优先搜索(BFS)
void solveMazeBFS_Queue() {
resetVisited();
// 使用数组模拟队列
Node queue[ROW * COL];
Path paths[ROW * COL];
int front = 0, rear = 0;
int dir[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}}; // 右、下、左、上
Node start = {1, 0}; // S 的位置
Path startPath;
initPath(&startPath);
addToPath(&startPath, start);
queue[rear] = start;
paths[rear] = startPath;
rear++;
visited[start.x][start.y] = 1;
// 初始全绘制
printMaze(1);
wait(100);
while (front < rear) {
Node cur = queue[front];
Path curPath = paths[front];
front++;
if (maze[cur.x][cur.y] != 'S' && maze[cur.x][cur.y] != 'E') {
maze[cur.x][cur.y] = 'X'; // 红色路径
}
// 动态显示 - 减少刷新频率
static int counter = 0;
if (++counter % 5 == 0) { // 每5步刷新一次
printMaze(0);
wait(50); // 减少等待时间
}
if (maze[cur.x][cur.y] == 'E') {
// 找到终点,标记路径
for (int i = 0; i < curPath.size; i++) {
Node node = curPath.nodes[i];
if (maze[node.x][node.y] != 'S' && maze[node.x][node.y] != 'E') {
maze[node.x][node.y] = 'P';
}
}
freePath(&curPath);
break;
}
for (int i = 0; i < 4; i++) {
int nx = cur.x + dir[i][0];
int ny = cur.y + dir[i][1];
if (isValid(nx, ny)) {
visited[nx][ny] = 1;
Node next = {nx, ny};
Path newPath;
initPath(&newPath);
copyPath(&newPath, &curPath);
addToPath(&newPath, next);
queue[rear] = next;
paths[rear] = newPath;
rear++;
}
}
freePath(&curPath);
}
// 最终展示结果
printMaze(1);
}
// 递归实现深度优先搜索的辅助函数
void dfsHelper(int x, int y, Path* path, int* found) {
if (*found) return;
if (maze[x][y] == 'E') {
*found = 1;
for (int i = 0; i < path->size; i++) {
Node node = path->nodes[i];
if (maze[node.x][node.y] != 'S' && maze[node.x][node.y] != 'E') {
maze[node.x][node.y] = 'P';
}
}
return;
}
int dir[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};
for (int i = 0; i < 4; i++) {
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if (isValid(nx, ny)) {
visited[nx][ny] = 1;
if (maze[nx][ny] != 'E') maze[nx][ny] = 'X';
static int counter = 0;
if (++counter % 5 == 0) {
printMaze(0);
wait(200);
}
Node next = {nx, ny};
addToPath(path, next);
dfsHelper(nx, ny, path, found);
if (path->size > 0) {
path->size--;
}
if (!(*found) && maze[nx][ny] == 'X') {
maze[nx][ny] = 'B';
if (counter % 5 == 0) {
printMaze(0);
wait(200);
}
}
}
}
}
// 递归实现深度优先搜索
void solveMazeDFS_Recursive() {
resetVisited();
Path path;
initPath(&path);
Node start = {1, 0};
addToPath(&path, start);
visited[start.x][start.y] = 1;
printMaze(1);
wait(100);
int found = 0;
dfsHelper(start.x, start.y, &path, &found);
freePath(&path);
printMaze(1);
}
// 清除路径标记
void clearPath() {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
// 只清除路径标记,保留迷宫结构和起点终点
if (maze[i][j] == 'X' || maze[i][j] == 'B' || maze[i][j] == 'P') {
maze[i][j] = '0';
}
}
}
resetVisited(); // 同时重置访问状态
}
// 递归实现深度优先搜索的辅助函数(用于查找所有路径)
void dfsAllPathsHelper(int x, int y, Path* path) {
if (maze[x][y] == 'E') {
// 路径数超限则不再保存,避免内存溢出
if (pathCount < 1000) {
initPath(&allPaths[pathCount]);
copyPath(&allPaths[pathCount], path);
pathCount++;
}
return;
}
int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
for (int i = 0; i < 4; i++) {
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if (isValid(nx, ny)) {
visited[nx][ny] = 1;
Node next = {nx, ny};
addToPath(path, next);
dfsAllPathsHelper(nx, ny, path);
// 严格回溯,确保 visited 状态正确
if (path->size > 0) {
path->size--;
}
visited[nx][ny] = 0;
}
}
}
// 查找所有路径
void findAllPaths() {
resetVisited();
pathCount = 0;
// 防止多次调用未初始化,先清空 allPaths 残留
for (int i = 0; i < pathCount; i++) {
freePath(&allPaths[i]);
}
Path path;
initPath(&path);
Node start = {1, 0};
addToPath(&path, start);
visited[start.x][start.y] = 1;
dfsAllPathsHelper(start.x, start.y, &path);
freePath(&path);
// 打印路径(独立清屏)
clearScreen();
printf("找到 %d 条路径:\n", pathCount);
for (int i = 0; i < pathCount; i++) {
printf("路径 %d: ", i + 1);
for (int j = 0; j < allPaths[i].size; j++) {
printf("(%d,%d)", allPaths[i].nodes[j].x, allPaths[i].nodes[j].y);
if (j < allPaths[i].size - 1) {
printf(" -> ");
}
}
printf("\n");
// 及时释放路径内存,避免堆积
freePath(&allPaths[i]);
}
printf("\n按任意键返回主菜单...");
getch();
// 彻底清屏并重置绘制状态,确保后续功能正常
clearScreen();
// 重新全量绘制迷宫,恢复可视化环境
printMaze(1);
}
// 判断是否重新生成迷宫
void re_generate() {
clearScreen();
char flag;
printf("\n是否需要重新生成迷宫(Y/N):");
flag = getchar();
// 清除输入缓冲区
while (getchar() != '\n');
// 验证输入
while (flag != 'y' && flag != 'Y' && flag != 'n' && flag != 'N') {
printf("输入错误,请重新输入(Y/N):");
flag = getchar();
while (getchar() != '\n');
}
// 重新生成迷宫或清除路径
if (flag == 'Y' || flag == 'y') {
generateValidMaze();
} else {
clearPath();
printf("路径已清除,可以尝试其他算法!\n");
wait(1000);
}
}
// 显示菜单
void showMenu() {
printf("\n=== 迷宫求解算法 ===\n");
printf("1. 使用栈实现深度优先搜索(DFS)\n");
printf("2. 使用队列实现广度优先搜索(BFS)\n");
printf("3. 使用递归实现深度优先搜索(DFS)\n");
printf("4. 查找所有路径\n");
printf("5. 退出\n");
printf("请选择(1-5): ");
}
// 更新主函数
int main() {
// 设置控制台缓冲区大小,防止滚动
system("mode con cols=25 lines=30");
int choice;
// 初始迷宫
generateValidMaze();
do {
clearScreen();
printMaze(1);
showMenu();
// 输入验证
while (scanf("%d", &choice) != 1 || choice < 1 || choice > 5) {
printf("无效选择,请输入1-5的数字:");
while (getchar() != '\n'); // 清除错误输入
}
while (getchar() != '\n'); // 清除输入缓冲区
switch (choice) {
case 1:
solveMazeDFS_Stack();
printf("\n\n\n\n\n\n\n\n\nDFS(栈) 执行完毕,按任意键返回菜单...");
getch();
break;
case 2:
solveMazeBFS_Queue();
printf("\n\n\n\n\n\n\n\n\nBFS(队列) 执行完毕,按任意键返回菜单...");
getch();
break;
case 3:
solveMazeDFS_Recursive();
printf("\n\n\n\n\n\n\n\n\nDFS(递归) 执行完毕,按任意键返回菜单...");
getch();
break;
case 4:
findAllPaths();
break;
case 5:
printf("程序结束\n");
return 0;
}
re_generate();
} while (choice != 5);
}
现在要查找所有路径更新下,使得输出可到达终点的路径,希望在我的代码的基础上,进行更新