• Python Prim 算法 生成迷宫 通过Pygame可视化


    前两篇文章,我们使用Prim算法生成了文章,这一次,我们要用Pygame将迷宫的完整生成过程可视化


    首先导入模块,这里我们要用到pygame,随机库,sys,time用于减缓速度,threading用于生成迷宫的另一个线程

    1. import pygame
    2. from pygame.locals import *
    3. import random as rd
    4. import sys
    5. import time
    6. import threading

    我们用类和对象的形式实现,定义Game类,初始化函数中设置窗口,a和b表示迷宫大小,lineWidth是迷宫墙壁画在窗口中的粗细,创建一个线程,指向createMaze(createMaze的代码下方会补充),然后启动线程

    1. class Game:
    2. def __init__(self):
    3. pygame.init()
    4. self.W,self.H=900,900
    5. self.screen=pygame.display.set_mode((self.W,self.H))
    6. self.a,self.b=28,39
    7. self.lineWidth=5
    8. thread=threading.Thread(target=self.createMaze,args=(self.a,self.b))
    9. thread.start()

    创建listen函数,用于监听事件

    1. def listen(self):
    2. for event in pygame.event.get():
    3. if event.type==QUIT:
    4. sys.exit()

    接下来是创建迷宫的代码,在上一篇遍历墙生成迷宫的时候,我们已经将代码完整写出来了,只要修改一小部分内容即可,要修改的地方如下:

    在函数参数中添加self

    def createMaze(self,a,b):

    然后,把函数中的maze全部改为self.maze,直接存入类变量中

    这里不再展示代码,需要算法代码的可以查看我的上一篇文章:

    Python Prim 算法 生成迷宫_Leleprogrammer的博客-CSDN博客Python Prim算法 通过遍历墙来生成迷宫,快来看看吧!https://blog.csdn.net/leleprogrammer/article/details/125472436?spm=1001.2014.3001.5501或者是在文末的最终代码中复制,要学习算法原理的,查看上一篇文章即可

    接下来,draw函数,用于绘制迷宫,这里代码不会太难,就不做太多讲解

    1. def draw(self):
    2. self.screen.fill((255,255,255))
    3. for (n,face),is_wall in self.maze.items():
    4. if is_wall:
    5. y=n//self.a
    6. x=n%self.a
    7. absX=x*self.width
    8. absY=y*self.height
    9. if face=="u":
    10. pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX+self.width,absY),self.lineWidth)
    11. if face=="d":
    12. pygame.draw.line(self.screen,(0,0,0),(absX,absY+self.height),(absX+self.width,absY+self.height),self.lineWidth)
    13. if face=="l":
    14. pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX,absY+self.height),self.lineWidth)
    15. if face=="r":
    16. pygame.draw.line(self.screen,(0,0,0),(absX+self.width,absY),(absX+self.width,absY+self.height),self.lineWidth)

    然后是run函数,主循环

    1. def run(self):
    2. while True:
    3. self.listen()
    4. self.draw()
    5. self.refreshWindow()
    6. pygame.display.update()

    用于显示文字的函数,这里没有用到,可以不加上,这里加上去是为了后续利用此框架编写游戏,这里还是把这个显示文字的函数给大家

    1. @staticmethod
    2. def print_text(name,size,text,color):
    3. font=pygame.font.SysFont(name,size)
    4. image=font.render(text,True,color)
    5. return image

    最后,添加这段启动的代码

    1. if __name__ == '__main__':
    2. game=Game()
    3. game.run()

    这样就好啦!

    最终代码(可供参考)

    1. import pygame
    2. from pygame.locals import *
    3. import random as rd
    4. import sys
    5. import time
    6. import threading
    7. class Game:
    8. def __init__(self):
    9. pygame.init()
    10. self.W,self.H=900,900
    11. self.screen=pygame.display.set_mode((self.W,self.H))
    12. pygame.display.set_caption("Find the Way")
    13. self.a,self.b=28,39
    14. self.lineWidth=5
    15. thread=threading.Thread(target=self.createMaze,args=(self.a,self.b))
    16. thread.start()
    17. def listen(self):
    18. for event in pygame.event.get():
    19. if event.type==QUIT:
    20. sys.exit()
    21. def createMaze(self,a,b):
    22. self.maze={}
    23. for n in range(a*b):
    24. for face in ["u","d","l","r"]:
    25. self.maze[(n,face)]=1
    26. history=[]
    27. walls=[]
    28. block=rd.choice(list(self.maze.keys()))[0]
    29. history.append(block)
    30. for face in ["u","d","l","r"]:
    31. walls.append((block,face))
    32. while len(walls)!=0:
    33. time.sleep(0.001)
    34. wall=rd.choice(walls)
    35. twoBlocks=[wall[0]]
    36. faces=[wall[1]]
    37. if wall[1]=="u":
    38. if wall[0]-a<0:
    39. twoBlocks.append(None)
    40. else:
    41. twoBlocks.append(wall[0]-a)
    42. faces.append("d")
    43. elif wall[1]=="r":
    44. if (wall[0]+1)%a!=0:
    45. twoBlocks.append(wall[0]+1)
    46. faces.append("l")
    47. else:
    48. twoBlocks.append(None)
    49. elif wall[1]=="l":
    50. if wall[0]%a!=0:
    51. twoBlocks.append(wall[0]-1)
    52. faces.append("r")
    53. else:
    54. twoBlocks.append(None)
    55. elif wall[1]=="d":
    56. if wall[0]+a>len(self.maze)/4-1:
    57. twoBlocks.append(None)
    58. else:
    59. twoBlocks.append(wall[0]+a)
    60. faces.append("u")
    61. ins=[]
    62. infaces=[]
    63. for i,oneBlock in enumerate(twoBlocks):
    64. if oneBlock in history:
    65. ins.append(oneBlock)
    66. infaces.append(faces[i])
    67. if len(ins)==1:
    68. mirrorFace=None
    69. if infaces[0]=="u":
    70. mirrorFace="d"
    71. elif infaces[0]=="d":
    72. mirrorFace="u"
    73. elif infaces[0]=="r":
    74. mirrorFace="l"
    75. elif infaces[0]=="l":
    76. mirrorFace="r"
    77. if not (None in twoBlocks):
    78. self.maze[(ins[0],infaces[0])]=0
    79. other=None
    80. if ins[0]==twoBlocks[0]:
    81. other=twoBlocks[1]
    82. else:
    83. other=twoBlocks[0]
    84. self.maze[(other,mirrorFace)]=0
    85. walls.remove(wall)
    86. history.append(other)
    87. for face in ["u","l","r","d"]:
    88. if self.maze.get((other,face))==1 and not ((other,face) in walls):
    89. walls.append((other,face))
    90. else:
    91. walls.remove(wall)
    92. continue
    93. elif len(ins)==2:
    94. walls.remove(wall)
    95. def draw(self):
    96. self.screen.fill((255,255,255))
    97. for (n,face),is_wall in self.maze.items():
    98. if is_wall:
    99. y=n//self.a
    100. x=n%self.a
    101. absX=x*self.width
    102. absY=y*self.height
    103. if face=="u":
    104. pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX+self.width,absY),self.lineWidth)
    105. if face=="d":
    106. pygame.draw.line(self.screen,(0,0,0),(absX,absY+self.height),(absX+self.width,absY+self.height),self.lineWidth)
    107. if face=="l":
    108. pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX,absY+self.height),self.lineWidth)
    109. if face=="r":
    110. pygame.draw.line(self.screen,(0,0,0),(absX+self.width,absY),(absX+self.width,absY+self.height),self.lineWidth)
    111. def run(self):
    112. while True:
    113. self.listen()
    114. self.draw()
    115. self.refreshWindow()
    116. pygame.display.update()
    117. if __name__ == '__main__':
    118. game=Game()
    119. game.run()

    本次的教学到这里也就结束啦!喜欢我的文章的,别忘了多多点赞关注支持哦!谢谢~

  • 相关阅读:
    模拟卷Leetcode【普通】341. 扁平化嵌套列表迭代器
    JUC_Volatile简述
    adb对安卓app进行抓包(ip连接设备)
    Maven笔记---超详细
    开源的容器运行时项目 Podman
    配置git-ssh
    在CentOS7下安装Oracle11教程
    算法3:链表实现队列
    gwas数据根据eaf Z 和N 求beta和se
    活动预约报名小程序已优化点与待优化点
  • 原文地址:https://blog.csdn.net/leleprogrammer/article/details/125472897