其他分享
首页 > 其他分享> > 2021-07-16

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