迷宫与寻路可视化(二)广度优先搜索构建迷宫(BFS算法)

效果展示

在这里插入图片描述

基本思想

不论是DFS,BFS还是RFS,这些算法生成的迷宫本质上是一个二维矩阵网络形式的生成树,也就是说其中没有回路,同时从右上角的起点到迷宫中的每一点都有且仅有一条路径,当然,到终点的路径也是唯一的。

在这里插入图片描述
这是一张用于生成迷宫的地图,左上角是淡黄色的是起点,右下角橙红色的是终点。黑色的是墙壁,我们在此基础上使用BFS算法从起点开始不断打通墙壁,直到在规则内无墙壁可以继续打通,则迷宫生成。下面来制定迷宫生成的基本规则:

  • 只遍历(偶数,偶数)坐标的墙壁,如果需要打通,则顺带打通两点之间带奇数坐标的墙壁。

🌟BFS算法

BFS在迷宫生成中的原理

从当前通路的末端遍历该层每一个可扩展点的每一条可能拓展路径进行扩展(遍历过程中的每一次选取都是随机的),如果该层遍历结束,就进行下一层的遍历。

第一层:
在这里插入图片描述

第二层:
在这里插入图片描述
第三层
在这里插入图片描述
第四层
在这里插入图片描述

函数

def BFScreatwall(chess_number):
	'''
	生成迷宫,有路为0,墙为1,输入棋盘大小,为奇数
	return:一个储存全局地图信息的二维数组,0为无墙,1为有墙
	'''
	wallcell=[]
	maze_creator_process=[]
	neighborcell=[[]]
	maincell=[]
	#初始状态下,迷宫内所有点都是墙壁,只有满足条件,节点才会由墙壁变成通路,而且节点和相邻选中非节点之间的阻碍打破
	wallcell=[[1]*chess_number for i in range(chess_number)]
	wallcell[start_posx][start_posy]=0
	maze_creator_process.append(deepcopy(wallcell))
	neighborcell[0].append(startpos)
	con=1	#循环旗帜
	while con:
		thislayer=1
		neighborcell.append([])
		layer=len(neighborcell)-2
		while thislayer:
			#对一层来说,先获得这一层所有格子的坐标,再获得下一层可能的所有格子坐标
			nextcell=[]
			x=[]
			y=[]
			#下面遍历该层所有格子的横纵坐标,得到下层目前所有符合要求的格子横纵坐标集合,因为每个格子有四个方向可以延伸,所以分上下左右四种情况进行讨论,如果超出范围或该位置格子已存在则不能向此方向延伸。
			for i in neighborcell[layer]:
				x.append(i[0])
				y.append(i[1])
				if x[-1]-2>=1 and wallcell[x[-1]-2][y[-1]] ==1 and wallcell[x[-1]-1][y[-1]] == 1 and wallcell[x[-1]-3][y[-1]]==1 and wallcell[x[-1]-2][y[-1]+1]==1 and wallcell[x[-1]-2][y[-1]-1]==1:
					nextcell.append([x[-1]-2,y[-1]])
				if x[-1]+2<=chess_number-2 and wallcell[x[-1]+2][y[-1]] ==1 and wallcell[x[-1]+1][y[-1]] == 1 and wallcell[x[-1]+3][y[-1]]==1 and wallcell[x[-1]+2][y[-1]+1]==1 and wallcell[x[-1]+2][y[-1]-1]==1:
					nextcell.append([x[-1]+2,y[-1]])
				if y[-1]-2>=1 and wallcell[x[-1]][y[-1]-2]==1 and wallcell[x[-1]][y[-1]-3] ==1 and wallcell[x[-1]][y[-1]-1] == 1 and wallcell[x[-1]-1][y[-1]-2]==1 and wallcell[x[-1]+1][y[-1]-2]==1:
					nextcell.append([x[-1],y[-1]-2])
				if y[-1]+2<=chess_number-2 and wallcell[x[-1]][y[-1]+2] ==1 and wallcell[x[-1]][y[-1]+1] == 1 and wallcell[x[-1]][y[-1]+3]==1 and wallcell[x[-1]-1][y[-1]+2]==1 and wallcell[x[-1]+1][y[-1]+2]==1:
					nextcell.append([x[-1],y[-1]+2])
			try:
				#随机选一个符合要求的邻居作为下一层真正的邻居
				num=random.randint(0,len(nextcell)-1)
				neighborcell[layer+1].append([nextcell[num][0],nextcell[num][1]])
				#邻居和改邻居与上一层之间的墙均需要被打通,往上下左右四个方向打通,所以分四种情况
				wallcell[nextcell[num][0]][nextcell[num][1]]=0
				for i in range(len(neighborcell[layer])):
					if nextcell[num]==[x[i]-2,y[i]]:
						wallcell[x[i]-1][y[i]]=0
						break
					elif nextcell[num]==[x[i]+2,y[i]]:
						wallcell[x[i]+1][y[i]]=0
						break
					elif nextcell[num]==[x[i],y[i]-2]:
						wallcell[x[i]][y[i]-1]=0
						break
					elif nextcell[num]==[x[i],y[i]+2]:
						wallcell[x[i]][y[i]+1]=0
						break
				maze_creator_process.append(deepcopy(wallcell))
			except:
				#这一层中已经不存在可能的探索路径
				thislayer=0
				#当所有的偶数格子(横纵坐标都是偶数)被打通,结束遍历
				odd1=0
				con=0
				for y in wallcell:
					if odd1%2==1:
						odd2=0
						for x in y: 
							if odd2%2==1:
								if x==1:
									con=1
									break
							odd2+=1
					if con==1:
						break
					odd1+=1
	return wallcell,maze_creator_process

完整源码下载链接

点此下载

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ace Cheney

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值