Python实现随机生成迷宫并自动寻路


Posted in Python onJune 13, 2021

Python深搜版:

核心在于带随机的深搜(见代码第23到27行,其实也可以用22行代替这几行代码,你可以试着把第24行的数字4改大或者改小,即调整随机程度)

import os
import random
from queue import Queue
import numpy
import colorama
from colorama import Fore, Back, Style
import sys   

from bmpEditor import bmp

colorama.init()


# numpy.random.seed(1)
_xy = [0,2,0,-2,0]
size = 31
sys.setrecursionlimit(100000000)

road = set()
def dfs(curr_pos):
	road.add(curr_pos)
	# for i in numpy.random.permutation(4):
	p = [0,1,2,3]
	for i in range(4):
		l = random.randint(0,3)
		r = random.randint(0,3)
		p[l], p[r] = p[r], p[l]
	for i in p:
		next_pos = (curr_pos[0] + _xy[i], curr_pos[1] + _xy[i+1])
		if (0<=next_pos[0]<size and
			0<=next_pos[1]<size and
			next_pos not in road ):
			
			road.add(((curr_pos[0] + next_pos[0])/2, (curr_pos[1] + next_pos[1])/2))
			dfs(next_pos)

dfs((0,0))

q = Queue()
q.put((0,0))
ans_road = set()
def dfs_getans(curr_pos):
	# print(curr_pos)
	ans_road.add(curr_pos)
	if (size-1, size-1) in ans_road:
		return
	for i in range(4):
		next_pos = (curr_pos[0] + _xy[i]//2, curr_pos[1] + _xy[i+1]//2)
		if (0<=next_pos[0]<size and
			0<=next_pos[1]<size and
			next_pos in road and
			next_pos not in ans_road and
			(size-1, size-1) not in ans_road):
			
			dfs_getans(next_pos)
	if (size-1, size-1) not in ans_road:
		ans_road.remove(curr_pos)

dfs_getans((0,0))

for i in range(size):
	for j in range(size):
		print((Back.WHITE + ' ') if (i,j) in road else (Back.BLACK + ' '), end=' ')
	print()


wall_width = 2
cell_size = 6
image = bmp((size+3)*cell_size-wall_width, (size+3)*cell_size-wall_width, 0x000000)
for i in range(size+3):
	for j in range(size+3):
		if (i-1, j-1) in road:
			image.paint_rect(i*cell_size, j*cell_size, cell_size*2-wall_width, cell_size*2-wall_width, 0xffffff)

file_name = "%dmaze.bmp"%size
image.save_image(file_name)
os.system(file_name)

for p in ans_road:
	# image.paint_rect(p[0]+1, p[1]+1)
	image.paint_rect((
		p[0]+1)*cell_size + (cell_size - wall_width)//2,
		(p[1]+1)*cell_size + (cell_size - wall_width)//2,
		cell_size, cell_size,
		0xff0000
	)

file_name = "%dans.bmp"%size
image.save_image(file_name)
os.system(file_name)

效果

3131:

Python实现随机生成迷宫并自动寻路

Python实现随机生成迷宫并自动寻路

8181:

Python实现随机生成迷宫并自动寻路

Python实现随机生成迷宫并自动寻路

坐标系有翻转,控制台中的左上角对应图片中的左下角

其中bmpEditor不是官方库,代码地址(文件名为bmpEditor.py,和这以上代码放同一个路径下即可)

Python 广搜版

在队列的基础上把队列中的元素顺序打乱(第24行)

import os
import random
from queue import Queue
import numpy
import colorama
from colorama import Fore, Back, Style
import sys   
import random   

from bmpEditor import bmp
colorama.init()


numpy.random.seed(1)
_xy = [0,2,0,-2,0]
size = 59
sys.setrecursionlimit(size*size//4+size)

q = []
q.append((0,0))
road = set()
road.add((0,0))
while len(q) != 0:
	random.shuffle(q)
	curr_pos = q.pop()
	# print(curr_pos)
	for i in range(4):
		next_pos = (curr_pos[0] + _xy[i], curr_pos[1] + _xy[i+1])
		if (	0<=next_pos[0]<size and
				0<=next_pos[1]<size and
				next_pos not in road ):
			road.add( ((curr_pos[0] + next_pos[0])//2, (curr_pos[1] + next_pos[1])//2) )
			q.append(next_pos)
			road.add(next_pos)

ans_road = set()
def dfs_getans(curr_pos):
	ans_road.add(curr_pos)
	if (size-1, size-1) in ans_road:
		return
	for i in range(4):
		next_pos = (curr_pos[0] + _xy[i]//2, curr_pos[1] + _xy[i+1]//2)
		if (	0<=next_pos[0]<size and
				0<=next_pos[1]<size and
				next_pos in road and
				next_pos not in ans_road and
				(size-1, size-1) not in ans_road):
			dfs_getans(next_pos)
	if (size-1, size-1) not in ans_road:
		ans_road.remove(curr_pos)

dfs_getans((0,0))
print(len(ans_road))

for i in range(0, size):
	for j in range(0, size):
		print((Back.WHITE + ' ') if (i,j) in road else (Back.BLACK + ' '), end=' ')
	print()
wall_width = 1
cell_size = 5
image = bmp((size+3)*cell_size-wall_width, (size+3)*cell_size-wall_width, 0x000000)
for i in range(size+3):
	for j in range(size+3):
		if (i-1, j-1) in road:
			image.paint_rect(i*cell_size, j*cell_size, cell_size*2-wall_width, cell_size*2-wall_width, 0xffffff)

file_name = "%dmaze.bmp"%size
image.save_image(file_name)
os.system(file_name)

for p in ans_road:
	# image.paint_rect(p[0]+1, p[1]+1)
	image.paint_rect((
		p[0]+1)*cell_size + (cell_size - wall_width)//2,
		(p[1]+1)*cell_size + (cell_size - wall_width)//2,
		cell_size, cell_size,
		0xff0000
	)

file_name = "%dans.bmp"%size
image.save_image(file_name)
os.system(file_name)

效果:

Python实现随机生成迷宫并自动寻路

Python实现随机生成迷宫并自动寻路

相比深度优先的,这种迷宫会更加“直”一些

lua版:

大体上是深搜,加了一定的随机性使得搜索过程中有一定概率暂时放弃当前路径。见表stop_points,(第7行、第74行及其后面的repeat循环)

local _xy = {0,2,0,-2,0}
local size = 41
local base = size+1
local road = {}

stop_points = {}
function dfs(curr_x, curr_y)
	road[curr_x*base+curr_y] = true
	if math.random(1,10) <= 3 then
		stop_points[curr_x*base+curr_y] = true
		return
	end
	-- os.execute("cls")
	-- print_map()
	local permutation = {1,2,3,4}
	for i=1, 4 do
		local l = math.random(1,4)
		local r = math.random(1,4)
		permutation[l], permutation[r] = permutation[r], permutation[l]
	end

	for i=1, 4 do
		local next_x = curr_x+_xy[permutation[i]]
		local next_y = curr_y+_xy[permutation[i]+1]
		if  next_x>=1 and next_x<=size and
			next_y>=1 and next_y<=size and
			road[next_x*base+next_y] == nil then

			local mid_x = math.floor((curr_x+next_x)/2)
			local mid_y = math.floor((curr_y+next_y)/2)
			road[mid_x*base+mid_y] = true
			dfs(next_x, next_y)
		end
	end
end

local ans_geted = false
local parent = {}
function get_ans(curr_x, curr_y)
	-- print(curr_x, curr_y)
	for i=1, 4 do
		next_x =  (curr_x + math.floor(_xy[i])/2 )
		next_y =  (curr_y + math.floor(_xy[i+1])/2 )
		-- print(next_x, next_y)
		if  next_x >= 1 and next_x <= size and
			next_y >= 1 and next_y <= size and
			road[next_x*base+next_y] and
			parent[next_x*base+next_y]==nil
		then
			parent[next_x*base+next_y] = curr_x*base+curr_y
			get_ans(next_x, next_y)
		end
	end

end

local ans_road = {}
function print_map()
	for i=0, size+1 do
		local line = ""
		for j=0, size+1 do
			if ans_road [i*base+j] then
				line = line..".."
			elseif road[i*base+j]==true then
				line = line.."  "
			else
				line = line.."HH"
			end
		end
		print(line)
	end
end

stop_points[1*base+1] = true

-- create maze
repeat
	local has_point = false
	for v,_ in pairs(stop_points) do
		has_point = true
		stop_points[v] = nil
		dfs(math.floor(v/base), v%base)
		break
	end
	-- print(has_point)
until not has_point


get_ans(1,1)
parent[1*base+1] = nil
print("")
-- for k,v in pairs(parent) do
-- 	print(string.format("[%d,%d]->[%d,%d]", math.floor(k/base), k%base, math.floor(v/base), v%base))
-- end
print("")
local x = size
local y = size
repeat
	-- print(x,y)
	ans_road[x*base+y] = true
	local v = parent[x*base+y]
	x = math.floor(v/base)
	y = v%base
until --[[(x==1 and y== 1)]] not parent[x*base+y]
ans_road[1*base+1] = true

print_map()

效果:

4141:

Python实现随机生成迷宫并自动寻路

8989

Python实现随机生成迷宫并自动寻路

到此这篇关于Python实现随机生成迷宫并自动寻路的文章就介绍到这了,更多相关Python生成迷宫并自动寻路内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 调用VC++的动态链接库(DLL)
Sep 06 Python
Python深入学习之对象的属性
Aug 31 Python
python操作mysql数据库
Mar 05 Python
详解pyenv下使用python matplotlib模块的问题解决
Nov 29 Python
Python Web框架之Django框架Model基础详解
Aug 16 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
Jan 14 Python
python爬虫模块URL管理器模块用法解析
Feb 03 Python
Python 面向对象部分知识点小结
Mar 09 Python
python json.dumps中文乱码问题解决
Apr 01 Python
基于Python共轭梯度法与最速下降法之间的对比
Apr 02 Python
Python实现Telnet自动连接检测密码的示例
Apr 16 Python
Python中的协程(Coroutine)操作模块(greenlet、gevent)
May 30 Python
python中opencv实现图片文本倾斜校正
Jun 11 #Python
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
Python-OpenCV实现图像缺陷检测的实例
Python中OpenCV实现简单车牌字符切割
Python排序算法之插入排序及其优化方案详解
Python下opencv库的安装过程及问题汇总
Jun 11 #Python
Python实现信息轰炸工具(再也不怕说不过别人了)
You might like
用PHP产生动态的影像图
2006/10/09 PHP
让PHP支持页面回退的两种方法
2008/01/10 PHP
深入理解curl类,可用于模拟get,post和curl下载
2013/06/08 PHP
PHP APC缓存配置、使用详解
2014/03/06 PHP
PHP实现WebService的简单示例和实现步骤
2015/03/27 PHP
php将数组存储为文本文件方法汇总
2015/10/28 PHP
php使用curl通过代理获取数据的实现方法
2016/05/16 PHP
CI框架出现mysql数据库连接资源无法释放的解决方法
2016/05/17 PHP
JQuery的read函数与js的onload不同方式实现
2013/03/18 Javascript
javascript日期对象格式化为字符串的实现方法
2014/01/14 Javascript
使用百度地图api实现根据地址查询经纬度
2014/12/11 Javascript
javascript里使用php代码实例
2014/12/13 Javascript
jQuery中wrapAll()方法用法实例
2015/01/16 Javascript
javascript十六进制及二进制转化的方法
2015/05/06 Javascript
Jquery中使用show()与hide()方法动画显示和隐藏图片
2015/10/08 Javascript
jQuery EasyUI学习教程之datagrid点击列表头排序
2016/07/09 Javascript
Vue CLI3中使用compass normalize的方法
2019/05/30 Javascript
[48:00]EG vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.26
2018/08/29 DOTA
[58:35]OG vs EG 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
使用Python判断质数(素数)的简单方法讲解
2016/05/05 Python
python在ubuntu中的几种安装方法(小结)
2017/12/08 Python
Python 通配符删除文件的实例
2018/04/24 Python
在Python中关于使用os模块遍历目录的实现方法
2019/01/03 Python
python3 批量获取对应端口服务的实例
2019/07/25 Python
html5模拟平抛运动(模拟小球平抛运动过程)
2013/07/25 HTML / CSS
关于canvas绘制模糊问题的解决方法
2019/09/24 HTML / CSS
HTML5录音实践总结(Preact)
2020/05/07 HTML / CSS
俄罗斯首家面向中国消费者的一站式购物网站:Wruru
2020/05/08 全球购物
2014年十一国庆向国旗敬礼寄语
2014/04/11 职场文书
给朋友的道歉短信
2015/05/12 职场文书
太行山上观后感
2015/06/05 职场文书
2016年教师政治思想表现评语
2015/12/02 职场文书
大学生社区义工服务心得体会
2016/01/22 职场文书
《走遍天下书为侣》教学反思
2016/02/22 职场文书
Anaconda配置各版本Pytorch的实现
2021/08/07 Python
《游戏王:大师决斗》新活动上线 若无符合卡组可免费租用
2022/04/13 其他游戏