def paint_wave_route(self, start): if self.wave is None: print("warning: wave pulse is missing.") return if self.wave.item(start) < 0: print("warning: cannot start from wall", start) return # print("showing route from", start) # self.screen.fill(BLACK) pos = start finish = self.route_rq[1] while pos != finish: # paint current cell self.paint_cell(pos, WAVES_PALETTE[PATH_MARK]) # pick the next cell neighbours = [(self.wave.item(nb_pos), nb_pos) for nb_pos in [ Position(pos.row, pos.col + 1), Position(pos.row - 1, pos.col), Position(pos.row, pos.col - 1), Position(pos.row + 1, pos.col), ] if is_inside(nb_pos, self.wave) and self.wave.item(nb_pos) >= 0] heapq.heapify(neighbours) _, pos = heapq.heappop(neighbours) # paint last cell self.paint_cell(pos, WAVES_PALETTE[PATH_MARK])
def free_neighbours(maze, node, visited): neighbours = [ pos for pos in [ Position(node.row - 1, node.col), Position(node.row, node.col - 1), Position(node.row + 1, node.col), Position(node.row, node.col + 1), ] if is_inside(pos, maze) and pos not in visited and maze.item(pos) == 0 ] return neighbours
def on_mouse_motion(self, event): if not self.live_routing: return x, y = event.pos col = (x - LEFT_OFFSET - PADDING // 2) // PADDED_CELL row = (y - TOP_OFFSET - PADDING // 2) // PADDED_CELL pos = Position(row, col) if not is_inside(pos, self.maze): return self.paint_maze() self.paint_wave_route(pos)
def on_click(self, event): x, y = event.pos col = (x - LEFT_OFFSET - PADDING // 2) // PADDED_CELL row = (y - TOP_OFFSET - PADDING // 2) // PADDED_CELL pos = Position(row, col) if not is_inside(pos, self.maze): return if event.button == 1: self.route_rq = (pos, self.route_rq[1]) self.find_a_route() elif event.button == 3: self.route_rq = (self.route_rq[0], pos) self.wave = propagate_wave(self.maze, pos)
def cross_neighbours_x(maze, node, goal, visited): goal_value = maze[goal] neighbours = [ (distance_heuristic(left=pos, right=goal), pos) for pos in [ Position(node.row - 1, node.col), Position(node.row, node.col - 1), Position(node.row + 1, node.col), Position(node.row, node.col + 1), ] if is_inside(pos, maze) and pos not in visited and maze.item(pos) in {0, goal_value} ] return neighbours
def new_neighbours(maze, seen, node, target): pin_value = maze[target] neighbours = [ (pos, m_distance(left=pos, right=target)) for pos in [ Position(node.row - 1, node.col), Position(node.row, node.col - 1), Position(node.row + 1, node.col), Position(node.row, node.col + 1), ] if is_inside(pos, maze) and pos not in seen and maze.item(pos) in {0, pin_value} ] return neighbours
def box_neighbour_values(maze, node): rows, cols = maze.shape nb = [ maze.item(pos) for pos in [ # top row, left to right Position(node.row - 1, node.col - 1), Position(node.row - 1, node.col), Position(node.row - 1, node.col + 1), Position(node.row, node.col + 1), # right node # bottom row, right to left Position(node.row + 1, node.col + 1), Position(node.row + 1, node.col), Position(node.row + 1, node.col - 1), Position(node.row, node.col - 1), # left node ] if is_inside(pos, maze) ] return nb