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

基于之前写的迷宫生成器实现了Djkstra算法搜索路径。

https://blog.csdn.net/ChillingKangaroo/article/details/122800431


Djkstra基于广度优先算法,与简单搜索不同的是Djkstra在访问每一个节点的时候会计算到该节点的最短路径以及上一个节点,如果有新的路径比之前的路径更短,储存的上一个路径点则会被替换掉。在完成计算之后只需要取终点的数据然后就可以沿记录找到已搜索范围中最短的路径。
因为我之前迷宫基于深度优先生成,另外因为路径没有权重(走一格的距离都是相同的)所以其实Djkstra不太能发挥出来,实现中没有使用优先级序列,不过算法还是有效的。

实现用了python的链表,动态添加很方便,在没有找到终点的时候循环,每次循环查找列表中节点的四个方向,如果没有访问过则添加到新列表中,循环结尾再把新列表值给查找列表,在查找到终点时就停止。

实现效果如下,绿色表示djkstra查找范围,蓝色表示最短路径,使用40x40矩阵测试

import pygame as pg
import time
import randomclass Tile(): #Tile is for generating mazedef __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 = Falseself.color = (255,253,150)def draw(self,color = None): #x,y represents the tile coordinates  color = self.color if not color else colorpg.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)class Node():def __init__(self):self.visited = Falseself.last_node = Noneself.steps = Nonedef maze_gen(path):global tile_coveredx,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}')returnif matrix[y][x].visited:print(f'node already visited at {x,y}')returnelif tile_covered <= grid_size[0]*grid_size[1]:tile_covered += 1print(x,y)matrix[y][x].visited = Truepath_choice = [0,1,2,3]random.shuffle(path_choice)for i in path_choice:x_,y_ = x+directions[i][0],y+directions[i][1]path.append([x_,y_])if maze_gen(path):  # tile is not visitedmatrix[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()pg.display.update()path.pop(-1)return Trueelse:print('all node visited')returndef djkstra():end_point = (grid_size[0]-1,grid_size[1]-1)x,y = start_pointmatrix[y][x].draw((255,0,0))matrix[end_point[0]][end_point[1]].draw((255,0,0))pg.display.update()border = [[0,0]]steps = 0while True:steps += 1new_border = []for x,y in border:if (x,y) == end_point:print('exit found')return end_pointfor i in range(4):if matrix[y][x].connected[i]: #if there is a waynext_x,next_y = directions[i][0]+x,directions[i][1]+yif found_path[next_y][next_x].visited == False:new_border.append([next_x,next_y])matrix[next_y][next_x].draw((0,255,0))pg.display.update()if found_path[next_y][next_x].last_node == None:found_path[next_y][next_x].last_node = (x,y)elif steps < found_path[next_y][next_x].steps:found_path[next_y][next_x].last_node = (x,y)print(f'setting {x,y} to visited')found_path[y][x].visited = Trueborder = new_borderif new_border == []:print('No exit point found')returndef draw_path(end_point):if not end_point:returnelse:x,y = end_pointwhile [x,y] != start_point:print(f'going though node {x,y}')matrix[y][x].draw((0,0,255))print(f'{(x,y)} == {start_point}:')print((x,y) == start_point)x,y = found_path[y][x].last_nodepg.display.update()screen_size = [800,800]
grid_size = [40,40]tile_covered = 0
run = Truescreen = pg.display.set_mode(screen_size)matrix = []
directions = [[0,-1],[1,0],[0,1],[-1,0]] # up,right,down,left 0 for not connected
found_path = [[Node() for x in range(grid_size[0])] for y in range(grid_size[1])]for y in range(grid_size[1]):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]]
start_point = [0,0]screen.fill((255,255,255))
maze_gen(path)pg.display.update()print('======== Generation Finished ========')end_point = djkstra()
draw_path(end_point)while run:for event in pg.event.get():if event.type == pg.QUIT:run = Falsepg.quit()

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

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

相关文章

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…

python验证身份证号码大全_身份证号码处理技巧大全

身份证号码处理技巧大全&#xff0c;汇总了常用的身份证号码处理六大技巧&#xff1a;不需要复杂的公式&#xff0c;点点鼠标即可完成&#xff0c;简单快捷&#xff0c;下面将详细介绍六大功能的具体用法。(文章最后有工具和演示文件的下载地址&#xff0c;可以下载下来同步操作…

语言print如何实现连续输出_【每日一题】如何实现一个高效的单向链表逆序输出?...

今后&#xff0c;动力节点Java学院将每天为大家带来一道大厂面试真题&#xff0c;这些面试题都是大厂技术专家们结合多年的工作、面试经验总结提炼而成的面试真题。通过这些面试题&#xff0c;还可以间接地了解技术大牛们出题思路与考察要点。建议大家收藏并分享给更多需要的人…