Pygame简单深度优先算法生成迷宫

学习路径计算之前需要一个场景,网上查了下迷宫生成方法花了点时间写了个简单的迷宫生成器
基本原理十分简单:
使用2维矩阵表示迷宫,每一个节点有四面墙,使用深度搜索,随机顺序向四个方向移动,,如果遇到已到节点则停止该方向,没有走过则把两个节点之间的墙消除掉。这样可以保证每一个节点都可以覆盖到而且每一个节点都会有一条路通向出口。

简单的算法有一个很明显的缺点:每一个节点只有一条固定的路,不会有多条路通向某个节点。


深度搜索使用递归十分简洁,不赘述。
具体实现比较容易受坑的地方是如何简洁实现上下左右随机移动,消除墙壁,并且不用一千个if:
首先是方向表示,这里使用了一个列表:
directions = [[0,-1],[1,0],[0,1],[-1,0]]
分别表示上右下左
对[0,1,2,3]使用random.shuffle()函数,然后对这个列表进行遍历可以实现随机获取上下左右矢量
每一个节点有四面墙壁,使用[0,0,0,0]表达,序列方向与上面direction相同。
在消除一个节点之间的墙壁的时候需要消除上一个墙壁对立面的节点
还是对方向进行操作direction[i]表达了方向矢量,在这里加号是右移,右移一位的时候是顺时针旋转45度,向左移1位则是旋转逆时针45度
数字i右移2位并投影到0-3上则可以实现方向对调。
简单来说就是进行右移并除余
每次搜索的时候如果遇到之前已访问节点则退出函数,函数中记录已覆盖节点,如果达到节点总数则直接退出
运行效果如下:
可以看到递归深度优先的算法的特点:在一条路走到最后之后会返回到上一个节点

import pygame as pg
import time
import randomclass Tile():def __init__(self,grid_size,screen_size,x,y): #主要是储存数据和绘制图形,与算法无关self.x,self.y = x,yself.connected = [0,0,0,0] # up,right,down,left 0 for not connectedself.grid_size = grid_sizeself.tile_size = [(screen_size[0]-100)/grid_size[0],(screen_size[1]-100)/grid_size[1]]self.rectangle = (self.x*self.tile_size[0]+50,self.y*self.tile_size[1]+50,self.tile_size[0],self.tile_size[1])self.points = [ [self.x*self.tile_size[0]+50,self.y*self.tile_size[1]+50],    #uppper left[self.x*self.tile_size[0]+50+self.tile_size[0],self.y*self.tile_size[1]+50],    #upper right[self.x*self.tile_size[0]+50+self.tile_size[0],self.y*self.tile_size[1]+50+self.tile_size[1]],    #lower right[self.x*self.tile_size[0]+50,self.y*self.tile_size[1]+50+self.tile_size[1]],    #lower left] self.visited = Falsedef draw(self,color = (255,253,150)): #x,y represents the tile coordinates  pg.draw.rect(screen,color,self.rectangle)   #绘制节点for i in range(4):  #绘制四面墙壁if not self.connected[i]:pg.draw.line(screen,(150,175,255),(self.points[i]),(self.points[((i+1)%4)]),5)def maze_gen(path):global tile_covered #覆盖节点数量,当覆盖节点数量到达网格数量则停止x,y = path[-1]if x < 0 or x >= grid_size[0] or y < 0 or y >= grid_size[1]:    #超出网格范围则退出print(f'index out of range at {x,y}')returnmatrix[y][x].draw()if matrix[y][x].visited:    #已访问节点则退出print(f'node already visited at {x,y}')returnelif tile_covered <= grid_size[0]*grid_size[1]: #覆盖节点数量未到达网格总数量tile_covered += 1matrix[y][x].visited = Truepath_choice = [0,1,2,3]random.shuffle(path_choice)directions = [[0,-1],[1,0],[0,1],[-1,0]] # up,right,down,left 0 for not connectedfor i in path_choice:x_,y_ = x+directions[i][0],y+directions[i][1]path.append([x_,y_])if maze_gen(path):matrix[y][x].connected[i] = 1 #walls of current nodematrix[y_][x_].connected[(i+2)%4] = 1#reverse the vector directionmatrix[y][x].draw()matrix[y_][x_].draw()path.pop(-1)pg.display.update()return Trueelse:print('all node visited')returnscreen_size = [800,800]
grid_size = [40,40]
exit = [10,10]
tile_covered = 0
run = Truescreen = pg.display.set_mode(screen_size)matrix = []
for y in range(grid_size[1]):   #创建二维矩阵,x,y代表坐标temp = []for x in range(grid_size[0]):tile = Tile(grid_size,screen_size,x,y)temp.append(tile)matrix.append(temp)pg.init()
path = [[0,0]]screen.fill((255,255,255))
maze_gen(path)pg.display.update()print('======== Generation Finished ========')
while run: #生称完毕之后不退出,使用循环for event in pg.event.get():if event.type == pg.QUIT:time.sleep(0.1)pg.quit()exit()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wait放弃对象锁_终于搞懂了sleep/wait/notify/notifyAll,真的是不容易

sleep/wait/notify/notifyAll分别有什么作用&#xff1f;它们的区别是什么&#xff1f;wait时为什么要放在循环里而不能直接用if&#xff1f;简介首先对几个相关的方法做个简单解释&#xff0c;Object中有几个用于线程同步的方法&#xff1a;wait、notify、notifyAll。public c…

Pygame 使用Djkstra广度搜索寻找迷宫(相对)最短路径

基于之前写的迷宫生成器实现了Djkstra算法搜索路径。 https://blog.csdn.net/ChillingKangaroo/article/details/122800431 Djkstra基于广度优先算法&#xff0c;与简单搜索不同的是Djkstra在访问每一个节点的时候会计算到该节点的最短路径以及上一个节点&#xff0c;如果有新…

python打乱list_超实用!每 30 秒学会一个 Python 小技巧,GitHub 标星 5300!

公众号关注 “GitHubDaily”设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01;很多学习 Python 的朋友在项目实战中会遇到不少功能实现上的问题&#xff0c;有些问题并不是很难的问题&#xff0c;或者已经有了很好的方法来解决。当然&#xff0c;孰能生巧&#xff0c;当…

(开源)Flask+Vue+Bootstrap3 人力资源用Web数据库

闲着没事写了一个轻量级web数据库&#xff0c;在网页端访问并操作SQL&#xff0c;可以进行Excel(xlsx)数据导入\导出&#xff0c;包含用户注册\登录\授权功能&#xff0c;密码有hash&#xff0c;授权目前比较简陋&#xff1a;后端使用了一个列表储存授权用户 已授权用户&#…

access找不到输入表或者dual_在Access窗体中显示指定路径的图片

↑↑↑点击上方图片&#xff0c;了解详情在Access中&#xff0c;如果把图形对象以OLE格式的字段保存&#xff0c;那么在窗体中可以直接显示出图片来。但是这样做有以下不足&#xff1a;一、需要将图片逐一插入到表中&#xff0c;工作量太大。二、使数据库文件变得庞大。三、相同…

LeetCode 168. Excel列表名称详解

刷到了这一道简单难度题 https://leetcode-cn.com/problems/excel-sheet-column-title/https://leetcode-cn.com/problems/excel-sheet-column-title/ 粗看就是一道进制转换题不过容易掉坑里。 首先略讲一下进制转换&#xff0c; 以701为例&#xff0c;该数字可以转换为以下…

可视化管理_RFID技术实施智能仓储管理可视化

仓储物流管理在各个行业都非常重要&#xff0c;RFID技术助力仓储物流信息管理提高供应链管理的透明度和库存周转率&#xff0c;这样有效减少缺货损失&#xff0c;提高企业内的仓储物流效率。仓库管理过程中&#xff0c;存在区域划分笼统&#xff0c;不容易辨识&#xff0c;货物…

(包含重力矢量)Pygame粒子模拟

半成品&#xff0c;目前速度不能修改&#xff0c;另外某些状况下路径会比较奇怪&#xff0c;因为没有速度计算&#xff0c;包含了重力矢量&#xff0c;可以修改重力方向 import pygame as pg import math import time import random import mathclass Particle(): #Tile is for…

小米蓝牙左右互联_解决不同品牌智能家居的兼容问题,小米米家智能多模网关发布...

如今智能家居种类可谓异常丰富&#xff0c;许多智能家居确实能让日常生活变得更加便捷。但是&#xff0c;相信许多智能家居爱好者都有一个烦恼&#xff0c;不同的品牌智能家居几乎不能实现交互&#xff0c;比如现在正使用Zigbee协议的智能家居&#xff0c;但新购置的智能家居却…

Pygame列表(链表)简单实现贪吃蛇

主要算法&#xff1a; 创建一个二维矩阵映射到屏幕上的像素&#xff0c;逻辑在该矩阵中实现 移动通过4个矢量完成&#xff0c;矢量储存在列表中按照 上右下左 的顺序排列&#xff08;顺时针90度&#xff09;&#xff0c; 当前矢量以0-3的数字表达&#xff0c;这样进行加二除…

Pygame 整活五子棋

很早之前写了一个类似的五子棋&#xff0c;没有做到pygame里面&#xff0c;闲着没事给整过来了&#xff0c;主要就是加了一个鼠标映射坐标。 表情被锤会变脸。 设置的0积分不知道能不能下载 https://download.csdn.net/download/ChillingKangaroo/82109145 代码不多&#x…

读进程和写进程同步设计_浅谈unix进程进程间通信IPC原理

什么是进程进程间通信进程间通信即为不同进程之间通信&#xff0c;进程同步是进程间通信的一种unix进程间通信的分类有哪些System V进程间通信方式包含&#xff1a;System V消息队列System V信号量System V共享内存UNIX进程间通信方式包含&#xff1a;匿名管道命名管道信号POSI…

(Ipython)Matplotlib 中将二叉树可视化

&#xff08;注意之前代码有错误目前已更新&#xff09; 最近学习黑红二叉树&#xff0c;我想如果把二叉树可视化在操作的时候如果出错会比较容易发现。 在网上搜了一圈只有比较简单的ascii 的代码。 自己用Ipython写了一个&#xff0c;比较适合学生。 PS&#xff1a;算法没…

其中一个页签慢_VBA实战技巧15:创建索引页

学习Excel技术&#xff0c;关注微信公众号&#xff1a;excelperfect在工作簿中有许多工作表时&#xff0c;我们可以创建一个单独的工作表当作索引页&#xff0c;在其中创建到每个工作表的链接&#xff0c;就像目录一样&#xff0c;不仅方便查看工作簿中的工作表名称&#xff0c…

Python使用OpenCV 卷积核 实现康威生命游戏

"Mozart, Beethoven, and Chopin never died. They simply became music." 康威生命游戏规则十分简单&#xff0c;简化后如下&#xff1a; 一个“细胞”&#xff08;或者说单元&#xff09;分为生或死两种状态&#xff0c; 如果活相邻细胞有2或3个活细胞 该细胞活…

verilog赋多位值_verilog赋值

我现在要用且只能用八位的拨片开关对两个四位变量t1l,t1h赋值&#xff0c;且这两个变量t1l,t1h是要输出的&#xff0c;所以我编了一下程序&#xff0c;先通过拨片开关对输入变量d0,d1赋值&#xff0c;然后将d0,d1的值赋给t1l,t1...我现在要用且只能用八位的拨片开关对两个四位变…

Python/OpenCV 使用傅里叶变换与高斯平滑分析轮廓轨迹

该方法基本思想是通过分析高低频信息检测出轮廓碰伤、运动轨迹突变等信息&#xff0c;在工业上应用可能比较广泛&#xff0c; 对各种不规则形状都能分析&#xff0c;不过对高频信息多的复杂形状可能不好区分形状与噪音。 在这个例子中讲使用一个有鼓包的鸡蛋 import numpy as…

实现mvcc_一文读懂 etcd 的 mvcc 实现

提到事务必谈 ACID 特性, 基于悲观锁的实现会有读写冲突问题&#xff0c;性能很低&#xff0c;为了解决这个问题&#xff0c;主流数据库大多采用版本控制 mvcc[1] 技术&#xff0c;比如 oracle, mysql, postgresql 等等。读可以不加锁&#xff0c;只需要读历史版本即可 (写写还…

Pygame 粒子物理:Numba实现同时渲染十万+像素

图中同时渲染了十万个像素&#xff0c;没有明显掉帧 我对Pygame的印象一直是慢的扣脚的&#xff0c;直到前段时间看到了一段MandelBrot代码&#xff08;源地址弄丢了&#xff09;其中使用了这个功能:pygame.surfarray.make_surface() 这里可以直接把numpy阵列转换为pygame.su…

“vector”: 不是“std”的成员_libcxx 的 std::function 源码分析

链接&#xff1a;functional。其中 std::function 的主体内容在 2100 多行。先来看 function 的头部。template<class _Rp, class ..._ArgTypes> class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>: public __function::__maybe_derive_from_unary_function…