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的Django框架下使用django-tagging的教程
May 30 Python
Python 模拟登陆的两种实现方法
Aug 10 Python
Mac中Python 3环境下安装scrapy的方法教程
Oct 26 Python
python模块之paramiko实例代码
Jan 31 Python
Python下载网络文本数据到本地内存的四种实现方法示例
Feb 05 Python
Python中Numpy包的安装与使用方法简明教程
Jul 03 Python
Python 获取主机ip与hostname的方法
Dec 17 Python
python实现石头剪刀布程序
Jan 20 Python
Python 生成器,迭代,yield关键字,send()传参给yield语句操作示例
Oct 12 Python
python sorted方法和列表使用解析
Nov 18 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
python基于selenium爬取斗鱼弹幕
Feb 20 Python
python中opencv实现图片文本倾斜校正
Jun 11 #Python
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
Python-OpenCV实现图像缺陷检测的实例
Python中OpenCV实现简单车牌字符切割
Python排序算法之插入排序及其优化方案详解
Python下opencv库的安装过程及问题汇总
Jun 11 #Python
Python实现信息轰炸工具(再也不怕说不过别人了)
You might like
《魔兽世界》惊魂幻象将获得调整
2020/03/08 其他游戏
一步一步学习PHP(6) 面向对象
2010/02/16 PHP
array_multisort实现PHP多维数组排序示例讲解
2011/01/04 PHP
php join函数应用
2011/05/04 PHP
浅谈discuz密码加密的方式
2014/05/22 PHP
WordPress中用于获取文章作者与分类信息的方法整理
2015/12/17 PHP
php生成验证码,缩略图及水印图的类分享
2016/04/07 PHP
PHP中Cookie的使用详解(简单易懂)
2017/04/28 PHP
tp5(thinkPHP5)操作mongoDB数据库的方法
2018/01/20 PHP
php多进程应用场景实例详解
2019/07/22 PHP
js中判断文本框是否为空的两种方法
2011/07/31 Javascript
js模拟滚动条(横向竖向)
2013/02/22 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
2014/06/05 Javascript
JavaScript用JQuery呼叫Server端方法示例代码
2014/09/03 Javascript
jquery使用slideDown实现模块缓慢拉出效果的方法
2015/03/27 Javascript
基于jQuery实现的菜单切换效果
2015/10/16 Javascript
jQuery Easyui datagrid editor为combobox时指定数据源实例
2016/12/19 Javascript
JS使用cookie实现只出现一次的广告代码效果
2017/04/22 Javascript
vue.js评论发布信息可插入QQ表情功能
2017/08/08 Javascript
小程序tab页无法传递参数的方法
2018/08/03 Javascript
vue使用echarts图表的详细方法
2018/10/22 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
[45:25]完美世界DOTA2联赛循环赛 PXG vs IO 第一场 11.06
2020/11/09 DOTA
Python ftp上传文件
2016/02/13 Python
详解Python进程间通信之命名管道
2017/08/28 Python
Python删除Java源文件中全部注释的实现方法
2017/08/30 Python
python全栈开发语法总结
2020/11/22 Python
用HTML5制作视频拼图的教程
2015/05/13 HTML / CSS
西班牙三叶草药房:Farmacias Trébol
2019/05/03 全球购物
电子专业推荐信范文
2013/11/18 职场文书
总经理司机职责
2014/02/02 职场文书
教师校本培训方案
2014/02/26 职场文书
支部书记四风问题自我剖析材料
2014/09/29 职场文书
2014年党的群众路线整改措施思想汇报
2014/10/12 职场文书
C3 线性化算法与 MRO之Python中的多继承
2021/10/05 Python
Java十分钟精通进阶适配器模式
2022/04/06 Java/Android