#include <stdio.h>
#include <stdlib.h>
/*
所用的堆栈是链表形式, 并且带有头结点, 整个迷宫地图有4种状态,
0通路 1走过的路 2墙壁 3已经走过并确认为错误路径
*/
// 老鼠的移动始终遵循 上右下左 规律
// MAZE是迷宫数组
#define UP MAZE[x-1][y] // 上
#define RIGHT MAZE[x][y+1] // 右
#define DOWN MAZE[x+1][y] // 下
#define LEFT MAZE[x][y-1] // 左
#define EX 2 // 出口x坐标
#define EY 3 // 出口y坐标
#define MAZEX 10 // 迷宫竖向长度
#define MAZEY 12 // 迷宫横向长度
struct list {
int x;
int y;
struct list* next;
};
typedef struct list node;
typedef struct list* link;
// 定义迷宫数组 0通路 1走过的路 2墙壁 3已经走过并确认为错误路径
/* 测试地图1 4x4
int MAZE[MAZEX][MAZEY] = {
2, 2, 2, 2,
2, 0, 0, 2,
2, 0, 0, 0,
2, 2, 2, 2
};
*/
// 测试地图 2 5x5
/*
int MAZE[MAZEX][MAZEY] = {
2, 2, 2, 2, 2,
2, 0, 0, 2, 2,
2, 0, 2, 0, 2,
2, 0, 0, 0, 2,
2, 2, 2, 0, 2
};
*/
// 测试地图 3 10x12
int MAZE[MAZEX][MAZEY] = {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2,
2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
2, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2,
2, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2,
2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
};
// 函数声明
void push (link head, int x, int y);
int pop (link head, int* x, int* y);
int isExit (int x, int y);
void printMaze ();
void printStack (link stack);
int main () {
int i;
int j;
int x = 1; // 老鼠当前位置, 初始状态表示入口x坐标
int y = 1; // 老鼠当前位置, 初始状态表示入口y坐标
// 栈的初始化
link pathHead = (node*)malloc(sizeof(node));
pathHead->next = NULL;
// 打印迷宫路径图
printf("0通路 1走过的路 2墙壁 3已经走过并确认为错误路径
");
printf("初始迷宫地图:
");
printMaze();
// 0通路 1走过的路 2墙壁 3已经走过并确认为错误路径
MAZE[x][y] = 1; // 初始点标记为1
push(pathHead, x, y); // 首先把初始点压入栈中存放
while (isExit(x, y) == 0) {
printf("老鼠现在的位置: %d, %d
", x, y);
if (UP == 0) {
x--;
MAZE[x][y] = 1; // 走过的路径标记为1
push(pathHead, x, y);
} else if (RIGHT == 0) {
y++;
MAZE[x][y] = 1; // 走过的路径标记为1
push(pathHead, x, y);
} else if (DOWN == 0) {
x++;
MAZE[x][y] = 1; // 走过的路径标记为1
push(pathHead, x, y);
} else if (LEFT == 0) {
y--;
MAZE[x][y] = 1; // 走过的路径标记为1
push(pathHead, x, y);
} else {
printf("当前位置上下左右都不通, 回退!
");
pop(pathHead, &x, &y); // 把当前的坐标也就错误坐标, 弹出去
MAZE[x][y] = 3; // 标记当前死路为3
// 让x和y回到上一次的位置
x = pathHead->next->x;
y = pathHead->next->y;
}
}
printf("老鼠走过的路径如下
");
printMaze();
return 0;
}
// 入栈
void push (link head, int x, int y) {
link newNode = (node*)malloc(sizeof(node));
newNode->x = x;
newNode->y = y;
newNode->next = head->next;
head->next = newNode;
}
// 出栈
// 运行结果: 直接对当前x和y的位置进行修改
int pop (link head, int* x, int* y) {
if (head->next == NULL) {
printf("栈空
");
return 0;
}
link popNode = head->next;
head->next = popNode->next;
*x = popNode->x;
*y = popNode->y;
free(popNode);
return 1;
}
// 检查是否已经走到出口
// 参数: x 当前x坐标, y当前y坐标
// 返回值: 到出口返回1 ,不在出口返回0
int isExit (int x, int y) {
// 检查当前位置的上右下左4个位置, 是否已经超出迷宫范围
// 即可判断, 当前位置是否是出口
// 也就是说如果当前位置是出口, 当前的位置一定是在迷宫边界上
if (x <= 0 || x > MAZEX - 1 || y <= 0 || y >= MAZEY - 1) {
printf("成功找到出口
");
printf("
");
return 1;
} else {
printf("还没找到出口
");
printf("
");
return 0;
}
}
// 打印迷宫数组
void printMaze () {
int i;
int j;
for (i=0; i<MAZEX; i++) {
for (j=0; j<MAZEY; j++) {
printf("%2d", MAZE[i][j]);
}
printf("
");
}
printf("
");
printf("
");
}
// 打印堆栈
void printStack (link stack) {
int length = 0;
stack = stack->next;
while (stack) {
printf("%d %d
", stack->x, stack->y);
length += 1;
stack = stack->next;
}
printf("当前一共存储了%d个路径
", length);
printf("
");
}