python迷宫小游戏简单代码,python 走迷宫代码
本文主要介绍Python迷宫生成器的详细代码,对于大家来说非常详细,对于大家的学习或者工作都有一定的参考价值。有需要的朋友可以参考一下。
迷宫作为一种古老的智力游戏,千百年来散发着迷人的魅力。然而,手工设计迷宫费时费力,所以我们有必要制作一个程序:迷宫生成器…
好吧,我再也编不出来了。不过从上面的文字可以看出,我们这次的主题是用Python实现一个迷宫生成器。
先展示效果图:
让我们首先分析所需的库:
既然是生成器,那么每次生成的迷宫都是一模一样显然没有意义。因此,我们不可避免地使用随机数(随机库)。迷宫是一定要画的,所以要有一个GUI库或者绘图库。这里我用的是Pygame(Tkinter Tkinter或者Turtle其实也可以,但毕竟Pygame更方便)。有了Pygame,Sys似乎也是需要的(用来退出程序,但不实际用的话好像也不疼)。然后是Tkinter.filedialog,主要用于询问保存路径(生成的迷宫必须保存)。当然,加上一个带时间的定时器,似乎是锦上添花。
所以,有:
#编码:utf-8
导入上下文库
with context lib . redirect _ stdout(None):
导入pygame
随机导入
导入系统
导入时间
从tkinter.filedialog对话框导入*
这里需要使用Contextlib来防止Pygame被输出,因为在导入PyGame时会输出很多版本信息等内容(影响美感)。
接下来,我们需要询问一些参数:
A=int(input(列数:))
B=int(输入(行数:))
L=int(输入( size:))
Saveit=input (save:)
然后,是时候运行生成迷宫的程序了。同时,我们有必要记录下时间(相当于启动了一个计时器):
打印(建筑.)
e=time.time()
然后迷宫正式生成。在介绍这部分代码之前,我们需要了解一下算法:
第一步是生成由迷宫单元(白色方块)和墙壁(黑格)组成的网格。一行中的迷宫单元数就是迷宫中的列数,一列中的迷宫寻找单元数就是迷宫中的行数。将左上角的迷宫单元作为起点,右下角的迷宫单元作为终点,打破起点左侧和终点右侧的墙壁,如图:
第二步是参观每个迷宫单元。将起点标记为当前迷宫单元,当存在未访问的迷宫单元时(所有曾经是当前迷宫单元的迷宫单元都被视为已访问),重复:
将周围未参观过的迷宫单元添加到表格中;如果表格中有迷宫单元:将当前迷宫单元堆叠(可以理解为将其添加到一个名为stack的表格中);从表格中随机选择一个迷宫单元;打破当前迷宫单元和所选迷宫单元之间的墙;将所选择的迷宫单元标记为当前迷宫单元;如果表中没有迷宫单元:栈顶的迷宫单元出栈(可以理解为获取并删除栈中最后一个元素);将退出的迷宫单元设置为当前迷宫单元;在循环的最后,会出现和文章开头的效果图一样的结果。
接下来,我们将把文字算法转换成Python代码。
首先,程序不知道图片,它知道数据。所以我们需要建立一个二维列表,用一串数据来表示当前图像。当然,我们可以顺便一起完成第一步的设置:
list=[]
aa=0
需要=[]
对于范围(2*a 1):内的j
如果aa==0:
aa=1
alistone=[]
对于范围(2*b 1):内的I
alistone.append(1)
alist.append(alistone)
else:
aa=0
alistone=[]
bb=0
对于范围(2*b 1):内的I
如果bb==0:
bb=1
alistone.append(1)
else:
bb = 0
need.append((j,i))
alistone.append(0)
alist.append(alistone)
alist[0][1]=0
alist[-1][-2]=0
可以看到,除此以外我们还建立了一个列表need,里面存储了所有的迷宫单元。它的作用就是判断迷宫单元是否被访问,每次访问都会将迷宫单元从表格中删除,当表格中没有迷宫单元时,就说明所有迷宫单元都被访问了。
x=1y=1
need.remove((1, 1))
listing=[]
while len(need)>0:
aroundit=[]
try:
if x-2<0:
print(1+"1")
alist[x-2][y]=0
if (x-2,y) in need:
aroundit.append("alist[x-1][y],x=(0,x-2)")
except:
while False:
print()
try:
alist[x+2][y]=0
if (x+2,y) in need:
aroundit.append("alist[x+1][y],x=(0,x+2)")
except:
while False:
print()
try:
alist[x][y+2]=0
if (x,y+2) in need:
aroundit.append("alist[x][y+1],y=(0,y+2)")
except:
while False:
print()
try:
if y-2<0:
print(1+"1")
alist[x][y-2]=0
if (x,y-2) in need:
aroundit.append("alist[x][y-1],y=(0,y-2)")
except:
while False:
print()
if len(aroundit)>0:
listing.append((x,y))
exec(random.choice(aroundit))
need.remove((x, y))
else:
x,y=listing[-1]
listing.pop()
而这些内容,就是第二步。其算法我已经解释过,唯一一个微小的不同是,在此处我们并没有在列表中加入相邻迷宫单元的坐标,而是将其对应的破墙和标记为当前迷宫单元的代码以字符串的形式存储在表格中,并在随机选择出某个迷宫单元所对应的字符串后,使用exec将其转换为代码并运行(这可以节省一些代码)。
print("完成!用时{}秒".format(time.time()-e))
打印完生成迷宫的用时后,我们需要将表格中的数据转化为图像了。当然,在此之前,我们要先确定图片保存的位置。
if saveit=="1":ccc = askdirectory()
h=""
bbbbb=1
while True:
try:
open("{}/{}×{}迷宫{}.png".format(ccc,a,b,h),"r")
h="({})".format(bbbbb)
except:
break
bbbbb+=1
由于使用时有可能选择不保存图片,因此要先判断你的选择是保存还是不保存。这里字符1表示保存(输入其他,自然就是不保存了)。然后我们需要让你选择保存路径(askdirectory()询问的是文件路径,不需要选择文件名)。然后,我们要确定文件名称:a×b迷宫.png。这里需要判断指定路径是否存在此名称的文件,如果存在,则我们需要在后面加上序号。总而言之,通过这串代码,我们已经将迷宫的路径+文件名确定了。
pygame.init()icon=pygame.image.load("迷宫.png")
pygame.display.set_icon(icon)
screen=pygame.display.Info()
screen = pygame.display.set_mode((l*(2*a+1),l*(2*b+1)))
pygame.display.set_caption(迷宫)
screen.fill("white")
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
for i in range(2*a+1):
for j in range(2*b+1):
if alist[i][j]==0:
screen.blit(c, (i*l, j*l))
elif alist[i][j]==1:
screen.blit(d, (i*l, j*l))
pygame.display.flip()
if saveit=="1":
pygame.image.save(screen, "{}/{}×{}迷宫{}.png".format(ccc, a, b, h))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
代码中使用的图片迷宫.png(名称不太对,下载以后要重新命名一下):
这里主要是Pygame的基本设置,并将表格内容图像化。每一个数字代表一个方块,而数字的值则决定了方块的颜色,数字在表格中的位置决定了方块的位置。就这样,我们呢将表格完全转化成了图像。当然,我们还需要用pygame.image.save()函数将图像保存为图片文件。
这样,这个生成器似乎完成了。
它运行良好,但当迷宫比较复杂时,暴露出一个问题(下图是100×100的迷宫):
由于正确路径过于曲折,在复杂度较高时,这个迷宫的难度会变得极高!
难度高,在某方面上讲,的确是好事。但当你向你的朋友们展示这个迷宫时,如果你自己也无法得出正确的路径,这不是很扫兴吗?
因此,一个寻路算法变得非常有必要。
寻路算法的大体思路:
在生成的迷宫中,白格为路,黑格为墙。将起点设置为当前位置,重复执行直到终点成为当前位置:
- 将当前位置标记为正确路径;
- 将周围未标记的路加入一个表格;
- 如果表格不空:
- 将当前位置入栈;
- 从表格中随机选择一条路,并将其设为当前位置;
- 如果表格是空的:
- 栈顶的路出栈;
- 将其设为当前位置;
通过这个算法,我们可以试出正确的路径(如图):
代码的实现:
x2=0y2=1
listing2=[]
while not(alist[-1][-2]==2):
alist[x2][y2]=3
around2=[]
try:
if x2-1<0:
print(1+"1")
if alist[x2-1][y2]==0:
around2.append("x2=x2-1")
except:
while False:
print()
try:
if alist[x2+1][y2]==0:
around2.append("x2=x2+1")
except:
while False:
print()
try:
if alist[x2][y2+1]==0:
around2.append("y2=y2+1")
except:
while False:
print()
try:
if y2-1<0:
print(1+"1")
if alist[x2][y2-1]==0:
around2.append("y2=y2-1")
except:
while False:
print()
if len(around2)>0:
listing2.append((x2,y2))
exec(random.choice(around2))
else:
alist[x2][y2]=2
x2,y2=listing2[-1]
listing2.pop()
alist[-1][-2]=3
for i in range(len(alist)):
for j in range(len(alist[0])):
if alist[i][j]==2:
alist[i][j]=0
同时,图像绘制的过程也要作出一些改动,以显示正确路径:
if saveit=="1":ccc = askdirectory()
h=""
bbbbb=1
while True:
try:
open("{}/{}×{}迷宫{}.png".format(ccc,a,b,h),"r")
open("{}/{}×{}迷宫(正确线路){}.png".format(ccc,a,b,h),"r")
h="({})".format(bbbbb)
except:
break
bbbbb+=1
pygame.init()
icon=pygame.image.load("迷宫.png")
pygame.display.set_icon(icon)
screen=pygame.display.Info()
screen = pygame.display.set_mode((l*(2*a+1),l*(2*b+1)))
pygame.display.set_caption(迷宫)
screen.fill("white")
if saveit=="1":
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=white)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.image.save(screen, "{}/{}×{}迷宫{}.png".format(ccc, a, b, h))
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=red)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.image.save(screen, "{}/{}×{}迷宫(正确线路){}.png".format(ccc, a, b, h))
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=white)
for i in range(2*a+1):
for j in range(2*b+1):
if alist[i][j]==0:
screen.blit(c, (i*l, j*l))
elif alist[i][j]==1:
screen.blit(d, (i*l, j*l))
else:
screen.blit(f,(i*l, j*l))
pygame.display.flip()
aaaaaaa = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if aaaaaaa == 1:
aaaaaaa = 0
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=white)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.display.flip()
else:
aaaaaaa = 1
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=red)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.display.flip()
通过这些改动,显示正确路径的效果就实现了。生成完成以后,窗口上显示的是没有正确路径的迷宫,而点击窗口后,正确的路径就会显示(再次点击隐藏)。
刚刚那张100×100的迷宫,其正确路径是:
可以看出,本文中所用的算法生成的迷宫,其正确路径还是非常曲折的(难度很高)。你何不将其发给你的朋友,让其破解一下呢?
完整的代码:
#coding:utf-8import contextlib
with contextlib.redirect_stdout(None):
import pygame
import random
import sys
import time
from tkinter.filedialog import *
a=int(input("列数:"))
b=int(input("行数:"))
l=int(input("大小:"))
saveit=input("是否保存:")
print("生成中...")
e = time.time()
alist = []
aa=0
need=[]
for j in range(2*a+1):
if aa==0:
aa = 1
alistone = []
for i in range(2*b+1):
alistone.append(1)
alist.append(alistone)
else:
aa=0
alistone = []
bb=0
for i in range(2*b+1):
if bb==0:
bb=1
alistone.append(1)
else:
bb = 0
need.append((j,i))
alistone.append(0)
alist.append(alistone)
alist[0][1]=0
alist[-1][-2]=0
x=1
y=1
need.remove((1, 1))
listing=[]
while len(need)>0:
aroundit=[]
try:
if x-2<0:
print(1+"1")
alist[x-2][y]=0
if (x-2,y) in need:
aroundit.append("alist[x-1][y],x=(0,x-2)")
except:
while False:
print()
try:
alist[x+2][y]=0
if (x+2,y) in need:
aroundit.append("alist[x+1][y],x=(0,x+2)")
except:
while False:
print()
try:
alist[x][y+2]=0
if (x,y+2) in need:
aroundit.append("alist[x][y+1],y=(0,y+2)")
except:
while False:
print()
try:
if y-2<0:
print(1+"1")
alist[x][y-2]=0
if (x,y-2) in need:
aroundit.append("alist[x][y-1],y=(0,y-2)")
except:
while False:
print()
if len(aroundit)>0:
listing.append((x,y))
exec(random.choice(aroundit))
need.remove((x, y))
else:
x,y=listing[-1]
listing.pop()
x2=0
y2=1
listing2=[]
while not(alist[-1][-2]==2):
alist[x2][y2]=3
around2=[]
try:
if x2-1<0:
print(1+"1")
if alist[x2-1][y2]==0:
around2.append("x2=x2-1")
except:
while False:
print()
try:
if alist[x2+1][y2]==0:
around2.append("x2=x2+1")
except:
while False:
print()
try:
if alist[x2][y2+1]==0:
around2.append("y2=y2+1")
except:
while False:
print()
try:
if y2-1<0:
print(1+"1")
if alist[x2][y2-1]==0:
around2.append("y2=y2-1")
except:
while False:
print()
if len(around2)>0:
listing2.append((x2,y2))
exec(random.choice(around2))
else:
alist[x2][y2]=2
x2,y2=listing2[-1]
listing2.pop()
alist[-1][-2]=3
for i in range(len(alist)):
for j in range(len(alist[0])):
if alist[i][j]==2:
alist[i][j]=0
print("完成!用时{}秒".format(time.time()-e))
if saveit=="1":
ccc = askdirectory()
h=""
bbbbb=1
while True:
try:
open("{}/{}×{}迷宫{}.png".format(ccc,a,b,h),"r")
open("{}/{}×{}迷宫(正确线路){}.png".format(ccc,a,b,h),"r")
h="({})".format(bbbbb)
except:
break
bbbbb+=1
pygame.init()
icon=pygame.image.load("迷宫.png")
pygame.display.set_icon(icon)
screen=pygame.display.Info()
screen = pygame.display.set_mode((l*(2*a+1),l*(2*b+1)))
pygame.display.set_caption(迷宫)
screen.fill("white")
if saveit=="1":
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=white)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.image.save(screen, "{}/{}×{}迷宫{}.png".format(ccc, a, b, h))
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=red)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.image.save(screen, "{}/{}×{}迷宫(正确线路){}.png".format(ccc, a, b, h))
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=white)
for i in range(2*a+1):
for j in range(2*b+1):
if alist[i][j]==0:
screen.blit(c, (i*l, j*l))
elif alist[i][j]==1:
screen.blit(d, (i*l, j*l))
else:
screen.blit(f,(i*l, j*l))
pygame.display.flip()
aaaaaaa = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if aaaaaaa == 1:
aaaaaaa = 0
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=white)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.display.flip()
else:
aaaaaaa = 1
c = pygame.Surface((l, l), flags=pygame.HWSURFACE)
c.fill(color=white)
d = pygame.Surface((l, l), flags=pygame.HWSURFACE)
d.fill(color=black)
f = pygame.Surface((l, l), flags=pygame.HWSURFACE)
f.fill(color=red)
for i in range(2 * a + 1):
for j in range(2 * b + 1):
if alist[i][j] == 0:
screen.blit(c, (i * l, j * l))
elif alist[i][j] == 1:
screen.blit(d, (i * l, j * l))
else:
screen.blit(f, (i * l, j * l))
pygame.display.flip()
代码的结束,对于程序也许仅仅只是开始;学习的暂时告一段落,从不影响生活的继续。生命无止境,贵在一颗永远向上的心。
到此这篇关于Python迷宫生成器的文章就介绍到这了,更多相关Python迷宫生成器内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。