起因

我想要写一个项目叫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. 更改DataFrame列顺序

    使用pandas进行数据分析的时候,有时会由于各种需求添加了一些列.可是列的顺序并不能符合自己的期望.这个时候就需要对于列的顺序进行调整. import numpy as np import pand ...

  2. 脚本之一键部署nexus

    NEXUS_URL="https://download.sonatype.com/nexus/3/nexus-3.39.0-01-unix.tar.gz" #NEXUS_URL=& ...

  3. 19_Vue如何监测到对象类型数据发生改变的?

    数据更新 关于监视 我们之前讲过,我们在data当中配置的属性,最终会挂载在vue实例身上,而data这个配置项,最终也会在vue身上成为一个新的属性 == _data 当我们在页面DOM当中,去使用 ...

  4. 【转】Linux文件权限

    转载一篇写得非常详细的linux文件权限,方便自己查阅! 转载来源:https://www.cnblogs.com/keyi/p/8124841.html ---------------------- ...

  5. Java代码审计sql注入

    java_sec_code 该项目也可以叫做Java Vulnerability Code(Java漏洞代码). 每个漏洞类型代码默认存在安全漏洞(除非本身不存在漏洞),相关修复代码在注释里.具体可查 ...

  6. python中的super()是什么?

    技术场景:python中的super,名为超类,可以简单的理解为执行父类的__init__函数.由于在python中不论是一对一的继承,还是一子类继承多个父类,都会涉及到执行的先后顺序的问题.那么本文 ...

  7. Stream流使用

    Stream流的使用 转换为流的操作 map转换为stream流 Map map = new HashMap(); Set<Map.Entry<String,Integer>> ...

  8. layui的switch监听事件无用

    像layui的这种表单事件是属于表单,而不是表格,所以操作是layui.form.on监听事件,而不是用layui.table.on table = layui.table , form = layu ...

  9. 1.1 大数据简介-hadoop-最全最完整的保姆级的java大数据学习资料

    目录 1 hadoop-最全最完整的保姆级的java大数据学习资料 1.1 大数据简介 1.1.1 大数据的定义 1.1.2 大数据的特点 1.1.3 大数据的应用场景 1.1.4 大数据的发展趋势及 ...

  10. 【实时数仓】Day00:数据流程、课程内容、框架结构、知识点总结

    一.数据流程 1.离线数仓 2.实时数仓 二.课程内容 1.数据采集层(ODS) 2.DWD层与DIM层数据准备 3.DWM层业务实现 4.DWS层业务实现 5.ClickHouse 6.数据可视化接 ...