2021-07-16
作者:互联网
迷宫寻路算法以及随机生成算法(C语言、栈)
迷宫寻路算法以及随机生成算法
主函数架构
#include"mazestack.h"
//迷宫寻路
void test03()
{
srand(time(NULL));
//创建一个栈区
PtrMazeStackHead Stack1 = InitMazeStackHead();
//创建一个迷宫数组
char MazeMap2[RANDMAZEMAXROW][RANDMAZEMAXCOL] = {0};
//初始化迷宫数组
InitMaze(MazeMap2);
//创建迷宫
CreateMaze(MazeMap2, Stack1,0);
//清空栈区
ClearMazeStack(Stack1);
//显示迷宫
ShowRandMaze(MazeMap2);
//寻路并显示
SerchMazeWay(MazeMap2, Stack1, 0);
//摧毁一个栈区
DestoryMazeStack(&Stack1);
//检测内存是否泄漏
printf("内存泄漏:%d\n", _CrtDumpMemoryLeaks());
}
int main()
{
clock_t start, end;
start = clock();
test03();
end = clock();
printf("执行时间:%lf\n", (double)(end - start) / CLOCKS_PER_SEC);
return 0;
}
迷宫显示
显示效果
printf显示特殊颜色字符参考博客
链接: MiniBirdie.
//打印地图
void ShowRandMaze(const char(*MazeMap1)[RANDMAZEMAXCOL])
{
for (int row = 0; row < RANDMAZEMAXROW; row++)
{
for (int col = 0; col < RANDMAZEMAXCOL; col++)
{
switch (MazeMap1[row][col])
{
case WALL:
//白色
printf("\033[0;37;47mOO\033[m");
break;
case ROAD:
//黑色
printf("\033[0;30;40mOO\033[m");
break;
case EXIT:
//黄色
printf("\033[0;33;43mOO\033[m");
break;
case HAS_PASSED:
//蓝色
printf("\033[0;34;44mOO\033[m");
break;
case REAL_WAY:
//红色
printf("\033[0;31;41mOO\033[m");
break;
case UN_SEACH:
//空格
printf(" ");
break;
default:
break;
}
}
printf("\n");
}
}
迷宫生成算法
参考jollysoul博客
链接: jollysoul.
本文采用深度优先算法
初始化一个迷宫
初始化后的数组打印后效果(101*101)
//初始化一个迷宫
void InitMaze(char(*MazeMap1)[RANDMAZEMAXCOL])
{
assert(MazeMap1);
//将所有空间初始化为墙
for (int i = 0; i < RANDMAZEMAXROW ; i += 1)
{
for (int j = 0; j < RANDMAZEMAXCOL ; j += 1)
{
MazeMap1[i][j] = WALL;
}
}
//初始化未探索空间
for (int i = 2; i < RANDMAZEMAXROW - 2; i += 2)
{
for (int j = 2; j < RANDMAZEMAXCOL - 2; j += 2)
{
MazeMap1[i][j] = UN_SEACH;
}
}
}
创造一个随机地图
创造效果
//创造一个随机地图(深度优先)
void CreateMaze(char(*MazeMap1)[RANDMAZEMAXCOL], PtrMazeStackHead Head1,int speed)
{
//判断输入合法
assert(MazeMap1);
assert(Head1);
assert(!Head1->size);
//最小行列
assert(RANDMAZEMAXROW > 10 || RANDMAZEMAXCOL > 10);
//行列必须为奇数
assert(RANDMAZEMAXROW % 2 && RANDMAZEMAXCOL && 2);
//设置起点
int nowrow = 2;
int nowcol = 2;
//记录方向
enum dir dir1;
//是否有,没有搜索过得位置
while (IsHaveUnsearch(MazeMap1))
{
//判断当前位置附近是否有没探索过得区域
if (IsNearHaveUnsearch(MazeMap1, nowrow, nowcol))
{
//随机个方向
dir1 = randmovedir(MazeMap1, nowrow, nowcol);
//当前地址压栈
push_Mazeelem(Head1, nowrow, nowcol);
//更具方向打开两个地点隔离的墙
switch (dir1)
{
case UP:
MazeMap1[nowrow-1][nowcol] = ROAD;
break;
case DOWN:
MazeMap1[nowrow+1][nowcol] = ROAD;
break;
case LEFT:
MazeMap1[nowrow][nowcol-1] = ROAD;
break;
case RIGHT:
MazeMap1[nowrow][nowcol+1] = ROAD;
break;
}
//将探索过得标记成路
MazeMap1[nowrow][nowcol] = ROAD;
#ifdef showCreat
ShowRandMaze(MazeMap1);
Sleep(speed);
system("cls");
#endif // showCreat
//根据方向移动
switch (dir1)
{
case UP:
nowrow-=2;
break;
case DOWN:
nowrow+=2;
break;
case LEFT:
nowcol-=2;
break;
case RIGHT:
nowcol+=2;
break;
}
}
else//判断当前位置附近没有可探索区域
{
//栈不为空
if (!IsStackEmpty(Head1))
{
//记录栈顶地址并且出栈
int tmp1 = -1;
int tmp2 = -1;
pop_Mazeelem(Head1, &tmp1, &tmp2);
//将当前位置更新为路
MazeMap1[nowrow][nowcol] = ROAD;
//将当前位置更新为栈顶元素
nowrow = tmp1;
nowcol = tmp2;
}
}
//栈为空时所有探索过了
if (IsStackEmpty(Head1))break;
}
//放入出口
MazeMap1[RANDMAZEMAXROW - 3][RANDMAZEMAXCOL - 3] = EXIT;
}
迷宫寻路算法
上方是迷宫
下方是寻路结果(红色为路径)(蓝色为多找的路径)
//寻找出口路径并显示寻找过程
void SerchMazeWay(char MazeMap1[RANDMAZEMAXROW][RANDMAZEMAXCOL], PtrMazeStackHead Head1, int speed)
{
//判断栈区是否存在且为空
assert(Head1);
assert(!(Head1->size));
//设置起始坐标
int nowrow = 2;
int nowcol = 2;
//第一个标量储存方位
enum dir dir1 = NO;
do
{
//获取当前坐标的情况
char brock = MazeMap1[nowrow][nowcol];
//如果是可以走的
if (brock == ROAD || brock == EXIT)
{
//如果是路
if (brock == ROAD)
{
//将这个路的坐标压栈
push_Mazeelem(Head1, nowrow, nowcol);
//将这个路的坐标给改为确定路线
MazeMap1[nowrow][nowcol] = REAL_WAY;
//展示当前行进位置
#ifdef showsearch
ShowRandMaze(MazeMap1);
Sleep(speed);
system("cls");
#endif // showsearch
}
if (brock == EXIT) //如果是出口就退出 栈区中存储确定的路线
{
ShowRandMaze(MazeMap1);
printf("找到了");
return;
}
else//如果不是出口
{
//默认向右走寻路
nowcol++;
}
}
else//如果是不能走的
{
//记录栈区顶部的第一个坐标
PtrMazeStackelem firstelem = Get_FirstMazeelem(Head1);
int firstrow = firstelem->row;
int firstcol = firstelem->col;
//当栈区不为空(为空时就没有出口)并且顶部的第一个坐标周边方向可以走
if (!IsStackEmpty(Head1) && (dir1 = Is_Randcanmove(MazeMap1, firstelem)) != NO)
{
//将坐标更新为栈顶坐标
nowrow = firstrow;
nowcol = firstcol;
switch (dir1)
{
case UP:
nowrow--;
break;
case DOWN:
nowrow++;
break;
case LEFT:
nowcol--;
break;
case RIGHT:
nowcol++;
break;
default:
break;
}
}
//当栈区不为空(为空时就没有出口)并且顶部的第一个坐标周边无方向可以走
if (!IsStackEmpty(Head1) && dir1 == NO)
{
while (!IsStackEmpty(Head1))
{
//记录栈区顶部的第一个坐标
firstelem = Get_FirstMazeelem(Head1);
//判断顶部的第一个坐标周边方向是否可以走
dir1 = Is_Randcanmove(MazeMap1, firstelem);
if (dir1 == NO)
{
//扔出栈顶坐标
pop_Mazeelem(Head1, &firstrow, &firstcol);
//将栈顶坐标标记为已经找过,并且一步
nowrow = firstrow;
nowcol = firstcol;
MazeMap1[nowrow][nowcol] = HAS_PASSED;
#ifdef showsearch
ShowRandMaze(MazeMap1);
Sleep(speed);
system("cls");
#endif // showsearch
}
else break;//可以走就退出
}
}
}
} while (!IsStackEmpty(Head1));
//此时栈区为空
ShowRandMaze(MazeMap1);
printf("无出口!");
return;
}
gitee文件获取
链接: gitee.
标签:nowcol,case,07,Head1,16,MazeMap1,break,nowrow,2021 来源: https://blog.csdn.net/qq_38962599/article/details/118817350