def solve(): global cont_solve, animation, drawn_spaces, checked file = "\n".join([ "".join([ "e" if s.end else ("s" if s.start else ("#" if s.wall else " ")) for s in row ]) for row in grid ]) with open("maze.txt", "w") as f: f.write(file) a = AStar(grid_w, grid_h, True, False) path, checked = a.solve() for row in grid: for cell in row: cell.path = False cell.checked = False if path is not None: cont_solve = True drawn_spaces = [] for p in path: grid[p.y][p.x].path = True for c in checked: try: grid[c.y][c.x].checked = True except Exception as e: print(e, c.x, c.y) else: print("NOT SOLVEABLE")
heuristic = manhattan elif config['a_star']['heuristic'] == "misplaced": heuristic = misplaced else: raise ValueError("Heuristic name invalid!") # Print initial and goal state print("Initial state:\n{}".format(init_state)) duplicate_check(init_state) print("Goal state:\n{}".format(goal_state)) duplicate_check(goal_state) print("="*50) # Test if A* problem is solvable can_solve = solvable(init_state, goal_state) print("="*50) if can_solve: print("PUZZLE IS SOLVABLE!") else: print( "WARNING: PUZZLE IS NOT SOLVABLE!\n" "Enter `c` to proceed.\n" "Doing so will search the entire state space!", "This will take a long time and is not advised...") set_trace() # Init and run A* solver print("="*50) a_star = AStar(init_state=init_state, goal_state=goal_state) a_star.solve(heuristic=heuristic)
class Board(pygame.Surface): def __init__(self, width, height): super().__init__((width, height), pygame.SRCALPHA) self.__width = width self.__height = height self.__grid = self.load_maze("data/maze.txt") cell_num_y = ["X" for _ in self.__grid].count("X") cell_num_x = self.__grid[1].count("X") # All cell positions self.cell_pos = [[ Cell(9 * j + (1 * (j + 1)), 9 * i + (1 * (i + 1)), 1) for j in range(cell_num_x) ] for i in range(cell_num_y)] # All horizontal walls self.hori_wall_pos = [[ Wall(10 * j + 1, 10 * i, 1, 2) for j in range(cell_num_x) ] for i in range(cell_num_y)] # All vertical walls self.vert_wall_pos = [[ Wall(10 * j, 10 * i + 1, 1, 1) for j in range(cell_num_x) ] for i in range(cell_num_y)] # All horizontal doors self.hori_door_pos = [[ Door(10 * (j // 2), 10 * (i // 2), 0 if self.__grid[i][j + 1] == "-" else 1, 2) for j in range(0, len(self.__grid[0]) - 1, 2) ] for i in range(0, len(self.__grid), 2)] # All vertical doors self.vert_door_pos = [[ Door(10 * (j // 2), 10 * (i // 2), 0 if self.__grid[i][j - 1] == "|" else 1, 1) for j in range(1, len(self.__grid[0]) + 1, 2) ] for i in range(1, len(self.__grid), 2)] self.maze = AStar(0, 0) path = self.maze.solve()[0] self.cell_colours = [[(255, 255, 255) if self.maze.grid[i][j] not in path else (0, 255, 0) for j in range(1, len(self.maze.grid[0]), 2)] for i in range(1, len(self.maze.grid), 2)] @property def grid(self): return self.__grid @grid.setter def grid(self, item): self.__grid = item @staticmethod def load_maze(fn: str) -> list: with open(fn) as f: return [i.replace("\n", "") for i in f.readlines()] def update(self) -> None: """ Update the board :return: None """ self.fill((0, 0, 0)) for hor in self.hori_wall_pos: for h in hor: pygame.draw.rect(self, (0, 0, 0), h) for vert in self.vert_wall_pos: for v in vert: pygame.draw.rect(self, (0, 0, 0), v) for door in self.hori_door_pos: for d in door: pygame.draw.rect(self, (255, 255, 255) if d.open_ else (0, 0, 0), d) for door in self.vert_door_pos: for d in door: pygame.draw.rect(self, (255, 255, 255) if d.open_ else (0, 0, 0), d) for row, cols in zip(self.cell_pos, self.cell_colours): for cell, col in zip(row, cols): pygame.draw.rect(self, col, cell)
def cover_xytable(self): total_distance = 0 flood_covered = [[False for y in col] for col in self.rockpoint] # return all manhattan neighbors def get_neighbors(loc): xx, yy = loc return filter(self.is_in_bounds, [ (xx - 1, yy), (xx, yy - 1), (xx + 1, yy), (xx, yy + 1), ]) S = [(self.radius + 1, self.radius + 1)] # start at 10,10 for funsies self.path = [(self.radius + 1, self.radius + 1, True)] # mark path as exploratory current_location = None while 0 < len(S): new_loc = S.pop() (x, y) = new_loc if current_location is not None: (x0, y0) = current_location # don't do all this twice if flood_covered[x][y]: continue flood_covered[x][y] = True # set up the path planner, from the new point back to the current point # AStar(cost_fn, is_goal_fn, h_fn, successors_fn) cost_fn = lambda _, __ : 1 h_fn = lambda (x, y) : abs(x - x0) + abs(y - y0) # manhattan distance is_goal_fn = lambda path : path == current_location successors_fn = lambda node : [n for n in get_neighbors(node) if (self.is_visited(n) or n == current_location or n == new_loc)] path_planner = AStar(cost_fn, is_goal_fn, h_fn, successors_fn, self.hack_draw_planned_path) # steps to get us to new location current_to_new_location = path_planner.solve(new_loc) if current_to_new_location is None: self.draw_pathplan_failure(current_location, new_loc) raise AssertionError("Couldn't go from " + str(current_location) + " to " + str(new_loc)) # actually visit points total_distance += len(current_to_new_location) - 2 self.path += [(xx, yy, False) for (xx, yy) in current_to_new_location[1:-1]] current_location = self.path[-1][:2] # only get neighbors of points with no displacement... otherwise dead end if not self.visit_point(x, y): continue # we've arrived current_location = new_loc total_distance += 1 # add new neighbors to the list of places we need to check for neighbor in get_neighbors(new_loc): xx, yy = neighbor if not flood_covered[xx][yy]: if self.is_ball_contained(xx, yy): S.append(neighbor) print "Total distance is", total_distance, print "which has % efficiency", round(100.0 * len(self.get_visited_list()) / total_distance, 1)