def wall_follower(maze): """Each time we have a pool of possible directions, we start by analysing the one of the left of current one. """ cell_stack = [(maze[(0, 0)], EAST)] while True: (cell, curr_dir) = cell_stack.pop() if cell.end: break curr_dir = (curr_dir - 1) # let's consider first our left for dir in xrange(curr_dir, curr_dir + DIRECTIONS): dir = (dir % DIRECTIONS) if cell.directions[dir]: neighbor = cell.neighbors[dir] neighbor.active = True cell.directions[dir] = False neighbor.directions[opposite_direction(dir)] = False cell_stack.append((cell, curr_dir)) cell_stack.append((neighbor, dir)) maze.modified = [neighbor.coords] break else: cell.active = False cell.backward = True maze.modified = [cell.coords] yield True yield False
def recursive_backtracker(maze): """Pick up a a random cell and mark it as a visited. Then look for neighbors which have not been visited yet, knock down the walls in between and set the new cell as the current one. Add the old cell and the new one to the cell stack and repeat the steps by extracting a cell from the stack untill all the cells of the grid have been visited. """ (rows, columns) = maze.size total = rows * columns cell = maze.random() cell.carved = True carved = 1 cell_stack = [cell] while carved < total: cell = cell_stack.pop() neighborhood = cell.neighbors directions = range(len(neighborhood)) shuffle(directions) for dir in directions: neighbor = neighborhood[dir] if neighbor and not neighbor.carved: cell.knock_down(dir) neighbor.knock_down(opposite_direction(dir)) neighbor.carved = True carved += 1 cell_stack.append(cell) cell_stack.append(neighbor) maze.modified = [cell.coords, neighbor.coords] yield True break yield False
def depth_first(maze): """Pick up the start cell and then look for open directions, choose one randomly, and add the current cell together with the neighbor one to a cell stack. Then pop a cell from the stack and repeat the steps untill the end cell is found. """ cell_stack = [maze[(0, 0)]] while True: cell = cell_stack.pop() if cell.end: break directions = cell.open_directions() shuffle(directions) for dir in directions: neighbor = cell.neighbors[dir] neighbor.active = True cell.directions[dir] = False neighbor.directions[opposite_direction(dir)] = False cell_stack.append(cell) cell_stack.append(neighbor) maze.modified = [neighbor.coords] break else: cell.active = False cell.backward = True maze.modified = [cell.coords] yield True yield False
def prim(maze): """Pick up a random cell, mark it as visited, and add its walls inside a list of walls. Extract a random wall from the list: if the cell on the opposite has not been yet visited, knock down the wall, mark the the new cell as visited, and add its walls to the wall list. Repeat the process untill all the cells have been visited. """ (rows, columns) = maze.size cell = maze.random() cell.carved = True wall_stack = [(cell, dir) for dir in cell.intact_walls()] while wall_stack: i = randint(0, len(wall_stack) - 1) (cell, dir) = wall_stack.pop(i) neighbor = cell.neighbors[dir] if neighbor and not neighbor.carved: cell.knock_down(dir) neighbor.knock_down(opposite_direction(dir)) neighbor.carved = True wall_stack += \ [(neighbor, dir) for dir in neighbor.intact_walls()] maze.modified = [cell.coords, neighbor.coords] yield True yield False