Python 四大迷宫生成算法实现(5): 图形显示实现

匿名 (未验证) 提交于 2019-12-02 22:11:45

python迷宫生成算法:图形显示实现

迷宫图形显示简介

使用pygame做了一个4种迷宫算法的图形显示,如下图,有4个按钮,可以用鼠标点击按钮来切换使用哪种算法来生成迷宫。按任意键来生成迷宫,同时加入了A* 寻路算法,来表现4种算法生成迷宫的不同,红色点是起点和终点,绿色点是使用A*算法获取的从起点到终点的路线。

代码介绍

代码实现有4个文件

  • GameMap.py: 保存迷宫基本信息的地图类,在前面的迷宫算法介绍中有说明,这边独立成一个文件。
  • MazeGenerator.py: 这个是四种迷宫算法的实现代码,放在一个文件中。
  • AStarSearch.py: A* 算法的实现,在前面的A* 算法文章中有介绍。
  • GameSearch.py: 用pygame代码写的迷宫的图形显示
    前面三个文件都已经说过,这边主要讲下GameSearch.py

GameSearch.py

迷宫配置参数, REC_SIZE 每个迷宫单元的大小,REC_WIDTH 和 REC_HEIGHT是迷宫的宽度和长度,可以任意修改,但是安装迷宫生成算法的要求,必须是奇数。

REC_SIZE = 10 REC_WIDTH = 51 # must be odd number REC_HEIGHT = 51 # must be odd number BUTTON_HEIGHT = 30 BUTTON_WIDTH = 120 SCREEN_WIDTH = REC_WIDTH * REC_SIZE SCREEN_HEIGHT = REC_HEIGHT * REC_SIZE + BUTTON_HEIGHT 

算法按钮的实现, __init__函数设置按钮的位置和大小,click 和 unclick 函数设置点击按钮时的颜色变化。

class Button(): 	def __init__(self, screen, type, x, y): 		self.screen = screen 		self.width = BUTTON_WIDTH 		self.height = BUTTON_HEIGHT 		self.button_color = (128,128,128) 		self.text_color = [(0,255,0), (255,0,0)] 		self.font = pygame.font.SysFont(None, BUTTON_HEIGHT*2//3) 		 		self.rect = pygame.Rect(0, 0, self.width, self.height) 		self.rect.topleft = (x, y) 		self.type = type 		self.init_msg() 		 	def init_msg(self): 		self.msg_image = self.font.render(generator_types[self.type], True, self.text_color[0], self.button_color) 		self.msg_image_rect = self.msg_image.get_rect() 		self.msg_image_rect.center = self.rect.center 		 	def draw(self): 		self.screen.fill(self.button_color, self.rect) 		self.screen.blit(self.msg_image, self.msg_image_rect) 	 	def click(self, game): 		game.maze_type = self.type 		self.msg_image = self.font.render(generator_types[self.type], True, self.text_color[1], self.button_color) 	 	def unclick(self): 		self.msg_image = self.font.render(generator_types[self.type], True, self.text_color[0], self.button_color) 

Game类, __init__函数初始化map类,默认选择随机Prim算法,并添加算法按钮。generateMaze 函数每次键盘输入会执行一次操作,循环执行四个操作(1.生成迷宫,2.生成起点和终点,3.用A* 算法生成路径, 4.清空迷宫)。check_buttons 函数将迷宫算法设置为选中按钮的算法。

class Game(): 	def __init__(self): 		pygame.init() 		self.screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) 		self.clock = pygame.time.Clock() 		self.map = Map(REC_WIDTH, REC_HEIGHT) 		self.mode = 0 		self.maze_type = MAZE_GENERATOR_TYPE.RANDOM_PRIM 		self.buttons = [] 		self.buttons.append(Button(self.screen, MAZE_GENERATOR_TYPE.RECURSIVE_BACKTRACKER, 0, 0)) 		self.buttons.append(Button(self.screen, MAZE_GENERATOR_TYPE.RANDOM_PRIM, BUTTON_WIDTH + 10, 0)) 		self.buttons.append(Button(self.screen, MAZE_GENERATOR_TYPE.RECURSIVE_DIVISION, (BUTTON_WIDTH + 10) * 2, 0)) 		self.buttons.append(Button(self.screen, MAZE_GENERATOR_TYPE.UNION_FIND_SET, (BUTTON_WIDTH + 10) * 3, 0)) 		self.buttons[0].click(self)  	def play(self): 		self.clock.tick(30) 		 		pygame.draw.rect(self.screen, (255, 255, 255), pygame.Rect(0, 0, SCREEN_WIDTH, BUTTON_HEIGHT)) 		for button in self.buttons: 			button.draw()  		for y in range(self.map.height): 			for x in range(self.map.width): 				type = self.map.getType(x, y) 				if type == MAP_ENTRY_TYPE.MAP_EMPTY: 					color = (255, 255, 255) 				elif type == MAP_ENTRY_TYPE.MAP_BLOCK: 					color = (0, 0, 0) 				elif type == MAP_ENTRY_TYPE.MAP_TARGET: 					color = (255, 0, 0) 				else: 					color = (0, 255, 0) 				pygame.draw.rect(self.screen, color, pygame.Rect(REC_SIZE*x, REC_SIZE*y+BUTTON_HEIGHT, REC_SIZE, REC_SIZE)) 		 	def generateMaze(self): 		if self.mode >= 4: 			self.mode = 0 		if self.mode == 0: 			generateMap(self.map, self.maze_type) 		elif self.mode == 1: 			self.source = self.map.generatePos((1,1),(1, self.map.height-2)) 			self.dest = self.map.generatePos((self.map.width-2, self.map.width-2), (1, self.map.height-2)) 			self.map.setMap(self.source[0], self.source[1], MAP_ENTRY_TYPE.MAP_TARGET) 			self.map.setMap(self.dest[0], self.dest[1], MAP_ENTRY_TYPE.MAP_TARGET) 		elif self.mode == 2: 			AStarSearch(self.map, self.source, self.dest) 			self.map.setMap(self.source[0], self.source[1], MAP_ENTRY_TYPE.MAP_TARGET) 			self.map.setMap(self.dest[0], self.dest[1], MAP_ENTRY_TYPE.MAP_TARGET) 		else: 			self.map.resetMap(MAP_ENTRY_TYPE.MAP_EMPTY) 		self.mode += 1  def check_buttons(game, mouse_x, mouse_y): 	for button in game.buttons: 		if button.rect.collidepoint(mouse_x, mouse_y): 			button.click(game) 			for tmp in game.buttons: 				if tmp != button: 					tmp.unclick() 			break			 

主循环, 获取键盘和鼠标点击事件,这个主要是pygame相关的代码。

game = Game() while True: 	game.play() 	pygame.display.update() 	 	for event in pygame.event.get(): 		if event.type == pygame.QUIT: 			pygame.quit() 			exit() 		if event.type == pygame.KEYDOWN: 			game.generateMaze() 			break 		elif event.type == pygame.MOUSEBUTTONDOWN: 			mouse_x, mouse_y = pygame.mouse.get_pos() 			check_buttons(game, mouse_x, mouse_y) 

完整代码

完整实现代码的github链接 迷宫算法图形显示

编译环境
python3.7 + pygame1.9

文章来源: https://blog.csdn.net/marble_xu/article/details/89735353
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!