Example #1
0
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")
Example #2
0
        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)
Example #3
0
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)