我们通常见的迷宫多种多样,在这里以多通路迷宫为例,对迷宫进行求解,找出最短路径,用C语言对其进行编写,涉及到一些操作包括:
1. 初始化迷宫地图数据 --》2.检测迷宫的入口是否有效 --》 3. 检测当前位置是否为迷宫的出口 --》4. 保存最短路径 --》5. 检测当前位置的下一步是否能够走通 --》6. 走迷宫 --》7. 具体走迷宫方式 --》8. 打印迷宫地图数据 --》9. 打印路径
下面用C实现该操作的一些代码:
maze.c-->下面是用递归的方式找到迷宫中的最短路径
#define _CRT_SECURE_NO_WARNINGS 0;
#include "maze.h"
#include "stack.h"
#include <stdio.h>
#include <assert.h>
//初始化迷宫
void MazeInit(maze* s, DataTypeMaze arr[MAZE_ROW][MAZE_COL])
{
assert(s);
int i = 0, j = 0;
for (i = 0; i < MAZE_ROW; i++)
{
for (j = 0; j < MAZE_COL; j++)
{
s->maze[i][j] = arr[i][j];
}
}
}
//打印迷宫
void PrintMaze(maze m)
{
int i = 0, j = 0;
for (i = 0; i < MAZE_ROW; i++)
{
for (j = 0; j < MAZE_COL; j++)
{
printf("%d ", m.maze[i][j]);
}
printf("\n");
}
}
// 检测迷宫的入口是否有效
int IsValidEnter(maze *m, PosType enter)
{
assert(m);
if ((enter._x == 0) || (enter._y == 0) || (enter._x == MAZE_ROW - 1) || (enter._y == MAZE_COL - 1))
{
if (m->maze[enter._x][enter._y] >= 1)
return 1;
}
return 0;
}
// 检测cur位置是否为迷宫的出口
int IsMazeExit(maze* m, PosType cur, PosType enter)
{
assert(m);
if (cur._x == enter._x && cur._y == enter._y)
return 0;
if (cur._x == 0 || cur._x == MAZE_COL - 1 || cur._y == 0 || cur._y == MAZE_ROW - 1)
{
return 1;
}
return 0;
}
// 检测当前位置是否为通路
int IsPass(maze* m, PosType cur)
{
assert(m);
if (m->maze[cur._x][cur._y] == 1)
return 1;
return 0;
}
// 打印路径
void PrintPath(Stack* s)
{
assert(s);
printf("over");
while (!IsEmptyStack(s))
{
printf("<- %d,%d ", StackTop(s));
StackPop(s);
}
}
// 检测当前位置的下一步是否能够走通
int IsNextPass(maze* m,PosType cur, PosType next)
{
assert(m);
if ((m->maze[next._x][next._y] == 1) || (m->maze[cur._x][cur._y]< m->maze[next._x][next._y]))
return 1;
return 0;
}
void printPath(Stack Path)
{
int i = 0;
for (; i < stackSize(&Path); i++)
{
printf("%d,%d-> ", Path.arr[i]);
}
printf("over \n");
}
// 保存最短路径
void SaveShortPath(Stack* path, Stack* shortPath)
{
assert(path);
assert(shortPath);
int i = 0;
shortPath->_top = 0;
for (; i < stackSize(path); i++)
{
StackPush(shortPath, path->arr[i]);
}
}
// 走迷宫
void PassMaze(maze* m, PosType enter, Stack* ShortPath)
{
assert(m);
assert(ShortPath);
Stack path;
if (!IsValidEnter(m, enter))
{
printf("无效的入口点");
return;
}
StackInit(&path);
_PassMaze(m, enter, enter,&path,ShortPath);
}
// 复杂迷宫--》具体走迷宫方式
void _PassMaze(maze *m, PosType enter,PosType cur, Stack *path,Stack* shortPath)
{
assert(path);
assert(shortPath);
PosType next = cur;
if (cur._x ==enter._x && cur._y == enter._y)
m->maze[cur._x][cur._y] = 2;
StackPush(path, cur);
if (IsMazeExit(m, cur, enter))
{
if (shortPath->_top == 0 || stackSize(path)<stackSize(shortPath))
SaveShortPath(path, shortPath);
StackPop(path);
return;
}
//上
next = cur;
next._x -= 1;
if (IsNextPass(m, cur, next))
{
m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
_PassMaze(m,enter, next, path, shortPath);
}
//右
next = cur;
next._y += 1;
if (IsNextPass(m, cur, next))
{
m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
_PassMaze(m, enter, next, path, shortPath);
}
//左
next = cur;
next._y -= 1;
if (IsNextPass(m, cur, next))
{
m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
_PassMaze(m, enter, next, path, shortPath);
}
//下
next = cur;
next._x += 1;
if (IsNextPass(m, cur, next))
{
m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
_PassMaze(m, enter, next, path, shortPath);
}
StackPop(path);
}
下面是用测试代码
上面就是实现复杂迷宫求解的C代码,下一篇会写用循环和递归两种方式对简单迷宫进行求解!!!//多通络带环迷宫 void testMaze() { maze m; Stack shortPath; StackInit(&shortPath); DataType x; x._x = 5; x._y = 1; DataTypeMaze arr[MAZE_ROW][MAZE_COL] = { { 0,0 },{ 0, 1,1,1 },{ 0, 1,0,1 },{ 0, 1, 0, 1},{ 0,1,1,1,1,1 },{ 0, 1} }; MazeInit(&m, arr); PrintMaze(m); PassMaze(&m, x, &shortPath); printf("迷宫最短路径--:"); PrintPath(&shortPath); printf("**********************\n"); PrintMaze(m); } int main() { testMaze(); system("pause"); return 0; }