├── README.md └── maze-generator.py /README.md: -------------------------------------------------------------------------------- 1 | # Maze Generator 2 | ![Image](https://www.picturepaste.ca/images/2020/05/31/Capture.png) 3 | ## Purpose 4 | To visualize the recursive backtracking algorithm. 5 | -------------------------------------------------------------------------------- /maze-generator.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import random 3 | import time 4 | 5 | 6 | def cwrap(x): 7 | q,r = divmod(x,255) 8 | if q%2: 9 | return 255-r 10 | else: 11 | return r 12 | 13 | 14 | def removeWalls(a, b): 15 | x = a.x-b.x 16 | y = a.y-b.y 17 | 18 | #Top right bottom left 19 | if(x == -1):#remove right wall of A and left wall of b 20 | a.walls[1] = False 21 | b.walls[3] = False 22 | if(x==1):#Remove left wall of A and right wall of b 23 | a.walls[3] = False 24 | b.walls[1] = False 25 | if(y == -1):#Remove bottom wall of A and top wall of b 26 | a.walls[2] = False 27 | b.walls[0] = False 28 | if(y == 1):#Remove top wall of A and bottom wall of b 29 | a.walls[0] = False 30 | b.walls[2] = False 31 | 32 | 33 | 34 | class Cell(): 35 | def __init__(self, x, y,w, gameDisplay, grid, cols, rows): 36 | self.cols = cols 37 | self.rows = rows 38 | self.x = x 39 | self.y = y 40 | self.w = w 41 | self.gameDisplay = gameDisplay 42 | self.walls = [True, True, True, True] #Top, right, bottom, left 43 | self.visited = False 44 | 45 | 46 | 47 | def show(self): 48 | x_pos = self.x*self.w 49 | y_pos = self.y*self.w 50 | 51 | if(self.visited): 52 | col = (cwrap(self.x * 30), 53 | cwrap(self.y * -10), 54 | cwrap(self.y * 40)) 55 | pygame.draw.rect(gameDisplay,col,(x_pos,y_pos,w,w)) 56 | #pygame.draw.rect(gameDisplay,(255,255,255),(x_pos,y_pos,w,w), 1) 57 | if (self.walls[0]): 58 | #Top 59 | pygame.draw.line(gameDisplay, (255,255,255), (x_pos, y_pos), (x_pos+w, y_pos), 1) 60 | if (self.walls[1]): 61 | #Right 62 | pygame.draw.line(gameDisplay, (255, 255,255), (x_pos+w, y_pos), (x_pos+w, y_pos+w), 1) 63 | if (self.walls[2]): 64 | #Bottom 65 | pygame.draw.line(gameDisplay, (255, 255,255), (x_pos, y_pos+w), (x_pos+w, y_pos+w), 1) 66 | if (self.walls[3]): 67 | #Left 68 | pygame.draw.line(gameDisplay, (255, 255,255), (x_pos, y_pos), (x_pos, y_pos+w), 1) 69 | 70 | 71 | 72 | def checkNeighbours(self): 73 | neighbours = [] 74 | if(self.index(self.x, self.y-1)!= -1): 75 | top = grid[self.index(self.x, self.y-1)] 76 | 77 | if not top.visited : 78 | neighbours.append(top) 79 | 80 | if(self.index(self.x+1, self.y)!= -1): 81 | right = grid[self.index(self.x+1, self.y)] 82 | 83 | if not right.visited: 84 | neighbours.append(right) 85 | 86 | if(self.index(self.x, self.y+1)!= -1): 87 | bottom = grid[self.index(self.x, self.y+1)] 88 | 89 | if not bottom.visited: 90 | neighbours.append(bottom) 91 | 92 | if(self.index(self.x-1, self.y)!= -1): 93 | left = grid[self.index(self.x-1, self.y)] 94 | 95 | if not left.visited: 96 | neighbours.append(left) 97 | 98 | #print(top, self.index(self.x, self.y-1)) 99 | if(neighbours): 100 | return neighbours[random.randint(0, len(neighbours)-1)] 101 | else: 102 | return None 103 | 104 | 105 | 106 | def index(self, x, y): 107 | if(x<0 or y<0 or x>self.cols-1 or y>self.rows-1): 108 | return -1 109 | 110 | else: 111 | return (x+y*self.cols) 112 | 113 | def highlight(self): 114 | x_pos = self.x*self.w 115 | y_pos = self.y*self.w 116 | 117 | pygame.draw.rect(gameDisplay,(96,50,158),(x_pos,y_pos,w,w)) 118 | 119 | 120 | if __name__ == "__main__": 121 | pygame.init() 122 | WIDTH = 600 123 | HEIGHT = 600 124 | 125 | w = 10 126 | cols = int(WIDTH/w) 127 | rows = int(HEIGHT/w) 128 | grid = [] 129 | stack = [] 130 | 131 | gameDisplay = pygame.display.set_mode((WIDTH,HEIGHT)) 132 | pygame.display.set_caption("Recursive Backtracker Maze Generator") 133 | 134 | for i in range(rows): 135 | for j in range(cols): 136 | grid.append(Cell(j, i, w, gameDisplay, grid, cols, rows)) 137 | 138 | 139 | current = grid[0] 140 | 141 | clock = pygame.time.Clock() 142 | 143 | exit = False 144 | time.sleep(10) 145 | 146 | while not exit: 147 | for i in range(len(grid)): 148 | grid[i].show() 149 | 150 | #Step 1 151 | current.visited = True 152 | current.highlight() 153 | 154 | next = current.checkNeighbours() 155 | 156 | if (next != None): 157 | next.visited = True 158 | #Step 2 159 | stack.append(current) 160 | 161 | #Step 3 162 | removeWalls(current, next) 163 | 164 | 165 | #Step 4 166 | current = next 167 | 168 | 169 | elif (len(stack)>0): 170 | current = stack.pop() 171 | 172 | 173 | 174 | for event in pygame.event.get(): 175 | if event.type == pygame.QUIT: 176 | exit = True 177 | 178 | pygame.display.update() 179 | gameDisplay.fill((0,0,0)) 180 | clock.tick(60) 181 | pygame.quit() 182 | quit() 183 | 184 | 185 | 186 | 187 | --------------------------------------------------------------------------------