起因

我想要写一个项目叫python迷宫游戏,需求是玩家能和机器对抗率先走出迷宫,至少要有两个等级的电脑。

慢慢来,首先迷宫游戏需要有一个迷宫并展示出来,这便是这篇博客的目的

假设迷宫使用0表示点,1表示墙,那么下面的代码主要使用深度优先搜索遍历所有的0

不过在下面的代码并不是这样的,比如在下面的代码(0, 0)表示点,两个点(0, 0)(0, 1)的连线表示墙,这是因为plt.plot([x1, x2], [y1, y2], color="black")可以轻易画出两个点之间的连线

下面我会介绍我的每一块代码,首先导入需要的库

import sys
import matplotlib.pyplot as plt
from random import randint

sys.setrecursionlimit(height * width)是设置栈的最大深度防止递归写错占用太多内存

self.visited用来记录哪个点已经遍历了

self.edges用来记录要用到的墙,在一开始初始化时会把每个点与他周围的所有点连接生成墙的列表初始化,之后会利用规则删掉不需要的墙,然后就是成品地图了使用plt绘制即可

class Maze(object):
def __init__(self, height, width):
sys.setrecursionlimit(height * width)
self.HEIGHT = height #设置迷宫高
self.WIDTH = width #设置迷宫宽
self.visited = []
self.edges = set() # 这个方法用来初始化点的列表
def initVisitedList(self):
for y in range(self.HEIGHT):
line = []
for x in range(self.WIDTH):
line.append(False)
self.visited.append(line)

下面两个方法用来初始化墙的列表,尝试把(0, 0)带入get_edges(self,x, y)很容易就能知道是初始化点旁边的哪4条边

	def get_edges(self,x, y):
result = []
result.append((x, y, x, y + 1))
result.append((x + 1, y, x + 1, y + 1))
result.append((x, y, x + 1, y))
result.append((x, y + 1, x + 1, y + 1))
return result def initEdgeList(self):
for x in range(self.WIDTH):
for y in range(self.HEIGHT):
cellEdges = self.get_edges(x, y)
for edge in cellEdges:
self.edges.add(edge)

这三个方法是为下面的一个方法准备的,看不懂可以先往下看

shuffle(self, dX, dY)目的是随机指定点往哪一边走(墙)

isValidPosition(self,x, y)用来判断点是否在self.visited

getCommonEdge()用来判断应该删除哪一条边

	def shuffle(self, dX, dY):
for t in range(4):
i = randint(0, 3)
j = randint(0, 3)
dX[i], dX[j] = dX[j], dX[i]
dY[i], dY[j] = dY[j], dY[i] def isValidPosition(self,x, y):
if x < 0 or x >= self.WIDTH:
return False
elif y < 0 or y >= self.HEIGHT:
return False
else:
return True def getCommonEdge(self, cell1_x, cell1_y, cell2_x, cell2_y):
edges1 = self.get_edges(cell1_x, cell1_y)
edges2 = set(self.get_edges(cell2_x, cell2_y))
for edge in edges1:
if edge in edges2:
return edge
return None

这个是最主要的逻辑,它用来得到成品的迷宫地图。它的输入DFS(self, X, Y, edgeList, visited)应该是这样的self.DFS(0, 0, self.edges, self.visited)self.edges是初始化后的边,self.visited是初始化后用来记录某个点是否被遍历过的列表

dX``dY共同代表了一个点上下左右4个方向,比如(1, 1)带入代码后的结果是(1, 0)``(1, 2)``(0, 1)``(2, 1)

	def DFS(self, X, Y, edgeList, visited):
dX = [0, 0, -1, 1]
dY = [-1, 1, 0, 0]
self.shuffle(dX, dY)
for i in range(len(dX)):
nextX = X + dX[i]
nextY = Y + dY[i]
if self.isValidPosition(nextX, nextY):
if not visited[nextY][nextX]:
visited[nextY][nextX] = True
# 删除某一条线
commonEdge = self.getCommonEdge(X, Y, nextX, nextY)
if commonEdge in edgeList:
edgeList.remove(commonEdge)
# 使用深度优先搜索遍历每一个点
self.DFS(nextX, nextY, edgeList, visited)

drawLine(self,x1, y1, x2, y2)方法带入下面的逻辑就可以画出迷宫图像了其中self.edges是经过DFS方法后得到的删除掉一些边后的列表

	def drawLine(self,x1, y1, x2, y2):
plt.plot([x1, x2], [y1, y2], color="black")
for edge in self.edges:
self.drawLine(edge[0], edge[1], edge[2], edge[3])

我使用了generate_maze(self)整合了前面所有的方法以画出图片,这里只展示部分代码,因为我担心老师说我是抄的,完整的代码在这里plt_generate_maze

其实DFS得到的并不是完全的成品,它没有出口和入口,这一点也是在generate_maze中删掉两条线来完成的

	def generate_maze(self):
plt.axis('equal')
plt.title('Maze')
#删除的代码部分在这里 plt.show()

在之后只要调用类设置迷宫宽高,再调用generate_maze方法就可以了

假如宽设置为60,高设置为40,迷宫图是这样的。

python利用matplotlib生成迷宫的更多相关文章

  1. python 利用matplotlib中imshow()函数绘图

    matplotlib 是python最著名的2D绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中.通过简单的绘图语 ...

  2. Python利用PIL生成随机验证码图片

    安装pillow: pip install pillow PIL中的Image等模块提供了创建图片,制作图片的功能,大致的步骤就是我们利用random生成6个随机字符串,然后利用PIL将字符串绘制城图 ...

  3. Python调用matplotlib实现交互式数据可视化图表案例

    交互式的数据可视化图表是 New IT 新技术的一个应用方向,在过去,用户要在网页上查看数据,基本的实现方式就是在页面上显示一个表格出来,的而且确,用表格的方式来展示数据,显示的数据量会比较大,但是, ...

  4. python中利用matplotlib绘图可视化知识归纳

    python中利用matplotlib绘图可视化知识归纳: (1)matplotlib图标正常显示中文 import matplotlib.pyplot as plt plt.rcParams['fo ...

  5. python基础一 ------利用生成器生成一个可迭代对象

    #利用生成器生成一个可迭代对象#需求:生成可迭代对象,输出指定范围内的素数,利用生成器产生一个可迭代对象#生成器:本身是可迭代的,只是 yield 好比return返回,yield返回后函数冻结状态, ...

  6. python利用决策树进行特征选择

    python利用决策树进行特征选择(注释部分为绘图功能),最后输出特征排序: import numpy as np import tflearn from tflearn.layers.core im ...

  7. 获取博客积分排名,存入数据库,读取数据进行绘图(python,selenium,matplotlib)

    该脚本的目的:获取博客的排名和积分,将抓取时间,排名,积分存入数据库,然后把最近的积分和排名信息进行绘图,查看积分或者排名的变化情况. 整个脚本的流程:是利用python3来编写,利用selnium获 ...

  8. canvas——随机生成迷宫

    先上图. 效果 代码 随机生成迷宫要求任意两点都能够找到相同的路径,也就是说,迷宫是一个连通图.随机生成迷宫可以使用普里姆算法.广度优先算法.深度优先算法等实现.这里将使用普里姆算法通过生成最小数的方 ...

  9. matplotlib 生成 eps 插入到 tex

    matplotlib 生成 eps 插入到 tex matplotlib 生成 eps,就可以插入到 tex 中,而且是矢量图,放大不失真. 而且因为图中的元素都是嵌入到 pdf 中,所以图中的文字也 ...

  10. Mac上实现Python用HTMLTestRunner生成html测试报告

    一.导入HTMLTestRunnerNew文件 首先,我们要知道如果要利用HTMLTestRunnerNew生成测试报告的话,就需要对其进行导入: HTMLTestRunnerNew下载地址:链接:h ...

随机推荐

  1. 45.限流Throttling及源码解析

    什么是限流? 限流类似于权限机制,它也决定是否接受当前请求,用于控制客户端在某段时间内允许向API发出请求的次数,也就是频率 假设有客户端(比如爬虫程序)短时间发起大量请求,超过了服务器能够处理的能力 ...

  2. DevOps | 如何快速提升团队软件开发成熟度,快速提升研发效能?

    今天一个小伙伴问我,如何「快速提升」一个团队的软件开发成熟度?我犯难了.我个人理解一个团队的软件开发成熟度涉及的东西很多,但最简单最直接的方法就是发钱涨工资,可是估计很多公司不愿意,那就只有扣了. 快 ...

  3. 五、Python操作redis

    五.Python操作redis 一.python对redis基本操作 (1)连接redis # 方式1 import redis r = redis.Redis(host='127.0.0.1', p ...

  4. ahk_more

    ;20:47 2022/5/8 #NoEnv #Warn #SingleInstance Force ;设工作目录为桌面 SetWorkingDir %A_Desktop% ;托盘提示必须放在热键前面 ...

  5. go如何编写命令行(cli)程序

    创建一个命令行程序 问题 如何使用golang创建可以在命令行当中传递参数的程序?go如何带参数执行程序? 比如我们期望使用hello -version来查看hello程序的版本号码.或者输入hell ...

  6. (GCC) gcc编译选项 -Wl, -start-group,whole-archive,-Wl, Bstatic

    1. start-group 编译选项 假设程序x依赖三个静态库:libX1.a.libX2.a和libX3.a,而libX2.a又依赖libX1.a,libX3.a依赖libX2.a和libX1.a ...

  7. Devexpress 图表显示数据标签

    dev的图标功能非常强大其中有一些设置可以更好的展现出数据 设置Series的标签 series.LabelsVisibility = DevExpress.Utils.DefaultBoolean. ...

  8. ArcObjects SDK开发 010 FeatureLayer

    1.FeatureLayer的结构 FeatureLayer是我们开发的时候用的最多的API之一,其实现的接口以及关联的其他API也非常多.下面我们就用一张图来整体看下FeatureLayer有哪些常 ...

  9. Django基础笔记3(form组件)

    From组件 from django.forms import Form, fields class loginForm(Form): # 设置规则 username = fields.CharFie ...

  10. @Transactional注解事务失效的几种场景及原因

    1. 介紹 在业务开发的许多场景中,我们会使用到通过事务去控制多个操作的一致性.比较多的就是通过声明式事务,即使用 @Transactional 注解修饰方法的形式.但在使用过程中,要足够了解事务失效 ...