g_size = 10 background_color = color(80, 80, 220) runner = color(255, 50, 50) visited_color = color(220, 240, 240) done_color = color(100, 160, 250) def setup(): global cell, done, visit, run_cell, c_size size(600, 600) frameRate(20) smooth(4) strokeCap(ROUND) c_size = max(width / g_size, height / g_size) cell = [[None] * g_size for _ in range(g_size)] for i in range(g_size): for j in range(g_size): cell[i][j] = Cell(i, j) for i in range(g_size): for j in range(g_size): cell[i][j].add_neighbor() run_cell = cell[0][0] visit, done = [], [] visit.append(run_cell) def draw(): global run_cell background(background_color) for i in range(g_size): for j in range(g_size): cell[i][j].draw_cell() cell[i][j].draw_wall() if len(visit) < g_size * g_size: if run_cell.check_sides(): chosen = run_cell.pick_neighbor() done.append(run_cell) run_cell.stacked = True if chosen.i - run_cell.i == 1: run_cell.wall[1] = False chosen.wall[3] = False elif chosen.i - run_cell.i == -1: run_cell.wall[3] = False chosen.wall[1] = False elif chosen.j - run_cell.j == 1: run_cell.wall[2] = False chosen.wall[0] = False else: run_cell.wall[0] = False chosen.wall[2] = False run_cell.current = False run_cell = chosen run_cell.current = True run_cell.visited = True elif done: run_cell.current = False run_cell = done.pop() run_cell.stacked = False run_cell.current = True class Cell: def __init__(self, i, j): self.i = i self.j = j self.wall = [True, True, True, True] self.visited = False self.stacked = False self.current = False def pick_neighbor(self): from random import choice unvisited = [nb for nb in self.neighbor if nb.visited == False] return choice(unvisited) def add_neighbor(self): i, j = self.i, self.j neighbor = [] if i > 0: neighbor.append(cell[i - 1][j]) if i < g_size - 1: neighbor.append(cell[i + 1][j]) if j > 0: neighbor.append(cell[i][j - 1]) if j < g_size - 1: neighbor.append(cell[i][j + 1]) self.neighbor = neighbor def check_sides(self): for nb in self.neighbor: if not nb.visited: return True return False def draw_cell(self): s = c_size noStroke() noFill() if self.current: fill(runner) elif self.stacked: fill(done_color) elif self.visited: fill(visited_color) rect(self.j * s, self.i * s, s, s) def draw_wall(self): i, j = self.i, self.j wall = self.wall stroke(0) strokeWeight(5) if wall[0]: line(j * c_size, i * c_size, j * c_size, (i + 1) * c_size) if wall[1]: line(j * c_size, (i + 1) * c_size, (j + 1) * c_size, (i + 1) * c_size) if wall[2]: line((j + 1) * c_size, (i + 1) * c_size, (j + 1) * c_size, i * c_size) if wall[3]: line((j + 1) * c_size, i * c_size, j * c_size, i * c_size)