# Pygame simple depth first algorithm generates maze

Posted by JADASDesigner on Sun, 06 Feb 2022 21:22:56 +0100

Before learning path calculation, we need a scene. We checked the maze generation method online and spent some time writing a simple maze generator
The basic principle is very simple:
The 2-dimensional matrix is used to represent the maze. Each node has four walls. The depth search is used to move in four directions randomly. If the node is reached, the direction will be stopped, and the wall between the two nodes will be eliminated. This can ensure that each node can be covered, and each node will have a way to the exit.

A simple algorithm has an obvious disadvantage: each node has only one fixed path, and there will be no multiple paths to a node.

The use of recursion in deep search is very concise and will not be repeated.
Specifically, where it is easy to suffer from pits, how to simply move up, down, left and right randomly, eliminate walls, and do not need a thousand if:
The first is the direction representation, which uses a list:
directions = [[0,-1],[1,0],[0,1],[-1,0]]
They represent upper right lower left respectively
Use random for [0,1,2,3] Shuffle () function, and then traverse the list to obtain the upper, lower, left and right vectors at random
Each node has four walls, expressed by [0,0,0,0], and the sequence direction is the same as the above direction.
When eliminating the wall between one node, you need to eliminate the node on the opposite side of the previous wall
Or operate on the direction. direction[i] expresses the direction vector. Here, the plus sign is to move to the right, rotate 45 degrees clockwise when moving one bit to the right, and rotate 45 degrees counterclockwise when moving one bit to the left
If the number i is shifted 2 bits to the right and projected onto 0-3, the direction can be changed.
Simply put, it is to move right and divide the remainder
During each search, if a node that has been accessed before is encountered, exit the function. The covered nodes are recorded in the function. If the total number of nodes is reached, exit directly
The operation effect is as follows:
We can see the characteristics of the recursive depth first algorithm: it will return to the previous node after the end of a road

```import pygame as pg
import time
import random

class Tile():
def __init__(self,grid_size,screen_size,x,y): #It mainly stores data and draws graphics, which has nothing to do with the algorithm
self.x,self.y = x,y
self.connected = [0,0,0,0] # up,right,down,left 0 for not connected
self.grid_size = grid_size
self.tile_size = [(screen_size[0]-100)/grid_size[0],(screen_size[1]-100)/grid_size[1]]
self.rectangle = (self.x*self.tile_size[0]+50,self.y*self.tile_size[1]+50,self.tile_size[0],self.tile_size[1])
self.points = [ [self.x*self.tile_size[0]+50,self.y*self.tile_size[1]+50],    #uppper left
[self.x*self.tile_size[0]+50+self.tile_size[0],self.y*self.tile_size[1]+50],    #upper right
[self.x*self.tile_size[0]+50+self.tile_size[0],self.y*self.tile_size[1]+50+self.tile_size[1]],    #lower right
[self.x*self.tile_size[0]+50,self.y*self.tile_size[1]+50+self.tile_size[1]],    #lower left
]
self.visited = False

def draw(self,color = (255,253,150)): #x,y represents the tile coordinates
pg.draw.rect(screen,color,self.rectangle)   #Draw node
for i in range(4):  #Draw four walls
if not self.connected[i]:
pg.draw.line(screen,(150,175,255),(self.points[i]),(self.points[((i+1)%4)]),5)

def maze_gen(path):
global tile_covered #Number of overlay nodes. When the number of overlay nodes reaches the number of grids, it will stop
x,y = path[-1]
if x < 0 or x >= grid_size[0] or y < 0 or y >= grid_size[1]:    #Exit if out of grid range
print(f'index out of range at {x,y}')
return
matrix[y][x].draw()
if matrix[y][x].visited:    #Exit if the node has been accessed
print(f'node already visited at {x,y}')
return
elif tile_covered <= grid_size[0]*grid_size[1]: #The number of overlay nodes does not reach the total number of grids
tile_covered += 1
matrix[y][x].visited = True
path_choice = [0,1,2,3]
random.shuffle(path_choice)
directions = [[0,-1],[1,0],[0,1],[-1,0]] # up,right,down,left 0 for not connected

for i in path_choice:
x_,y_ = x+directions[i][0],y+directions[i][1]
path.append([x_,y_])
if maze_gen(path):
matrix[y][x].connected[i] = 1 #walls of current node
matrix[y_][x_].connected[(i+2)%4] = 1#reverse the vector direction
matrix[y][x].draw()
matrix[y_][x_].draw()

path.pop(-1)
pg.display.update()

return True

else:
print('all node visited')
return

screen_size = [800,800]
grid_size = [40,40]
exit = [10,10]
tile_covered = 0
run = True

screen = pg.display.set_mode(screen_size)

matrix = []
for y in range(grid_size[1]):   #Create a two-dimensional matrix, where x and Y represent coordinates
temp = []
for x in range(grid_size[0]):
tile = Tile(grid_size,screen_size,x,y)
temp.append(tile)
matrix.append(temp)

pg.init()
path = [[0,0]]

screen.fill((255,255,255))
maze_gen(path)

pg.display.update()

print('======== Generation Finished ========')
while run: #Do not exit after weighing, use the cycle
for event in pg.event.get():
if event.type == pg.QUIT:
time.sleep(0.1)
pg.quit()
exit()```

Topics: Algorithm pygame