Esempio n. 1
0
    def getPath(self, start, end):
        query = {}
        query["sx"] = start[0]
        query["sy"] = start[1]
        query["ex"] = end[0]
        query["ey"] = end[1]
        cursor = mongo.db.paths.find(query)
        
        if cursor.count() > 0:
            path = cursor[0]["path"]
        else:
            came_from, cost_so_far = astar.a_star_search(self.grid, start, end)
            path = [end]
            e = end
            try: 
                while( e != start ):
                    e = came_from[e]
                    path.append(e)
                path.append(start)
            except KeyError:
                #Some paths may be impossible
                path = [end, start]
            finally:
                path.reverse()

            query["path"] = path
            mongo.db.paths.insert(query)

        return path
Esempio n. 2
0
def new_level(player, player_loc, depth, dim):
    ''' Generate a new level.
    Args:
        player <Player>: The actor controlled by the player.
        loc <Point>: The location of the player on the last level. (Assumption: dim is constant?)
        depth <int>: The number of the floor, starting from 1.
        dim <int>: The number of rows & columns to generate.
    Returns:
        map<Point, Cell>: A map from locations to the cells therein.
    '''

    for i in range(100):
        # generate terrain
        cells = gen_room(dim)

        # place the player
        assert player_loc in cells
        cells[player_loc] = CL_FLOOR()
        cells[player_loc].actor = player

        # place the stairs out
        stairs_loc = Point(int(dim/2), 1 if depth % 2 else dim - 2) # opposite the player, alternating
        cells[stairs_loc] = CL_STAIR()
        
        # place enemies
        add_enemies(player, player_loc, cells, depth)

        # sanity check
        path = a_star_search(cells, player_loc, stairs_loc, lambda cell: not cell.solid)
        if path:
            return cells
        # otherwise, generate a new level
        # TODO: would be nice to log this somehow

    raise RuntimeError("Couldn't generate a valid level!")
Esempio n. 3
0
def add_enemies(player, player_loc, cells, depth):
    ''' Generate enemies and place them on the level.
        Args:
            player (Player): The character controlled by the player.
            player_loc (Point): The location of the player.
            cells (map<Point, Cell>): A map of cells' locations to the contents of hte cells.
            depth (int): The depth of the level.
    '''
    assert player_loc != None
    assert player_loc in cells

    # spawn 1 mongoose per depth
    for i in range(depth):
        for i in range(10000): # eventually bail

            # repeatedly choose random cells
            loc, cell = choice(list(cells.items()))
            # discard ones that already have terrain or other actors
            if cell.is_full():
                continue
            # also discard those which can't get to the player, or which are too close
            to_player = a_star_search(cells, loc, player_loc, lambda cell: not cell.solid)
            if not to_player or len(to_player) < 4:
                continue

            # actually place an enemy
            cell.actor = Ghost()
            break
Esempio n. 4
0
    def move_toward_player(self, area):
        ''' Attempt to move toward the player.
        Args:
            area (Area): The area the ghost is in.
        Returns:
            bool: whether the ghost successfully moved.
        '''
        # TODO: deduplicate with mongoose code
        
        player = area.get_player()
        player_loc = area.find_actor(player)
        assert player_loc != None

        cur_loc = area.find_actor(self)
        assert cur_loc != None

        def passable_metric(cell):
            ''' Can the cell be pathed through? '''
            if cell.actor and not cell.actor.is_mobile():
                return False # don't path through fixed creatures
            return True

        # attempt to move toward the player
        path = a_star_search(area.cells, cur_loc, player_loc, passable_metric)
        # TODO: improve performance when the player is unreachable
        if path:
            return self.attempt_move(path[0] - cur_loc, area, None)
        return False
Esempio n. 5
0
    def getPlan(self, request):
        if self.map is None:
            rospy.logwarn(
                "Plan requested before map was made available! Please try again later!"
            )
            return GetPlanResponse()

        w = self.map.info.width
        h = self.map.info.height
        d = self.map.data

        res = self.map.info.resolution

        o = self.map.info.origin.position

        rospy.loginfo("Map metadata: {}".format(self.map.info))

        rospy.loginfo("Origin of occupancy grid: ({},{})".format(o.x, o.y))

        gx = int(float(request.goal.pose.position.x - o.x) / res)
        gy = int(float(request.goal.pose.position.y - o.y) / res)
        sx = int(float(request.start.pose.position.x - o.x) / res)
        sy = int(float(request.start.pose.position.y - o.y) / res)

        rospy.loginfo(
            "Planning path from ({},{}) to ({},{}) across {} points with resolution {}"
            .format(sx, sy, gx, gy, w * h, res))

        grid = [[0 for i in range(w)] for j in range(h)]

        num_ones = 0
        num_zeros = 0

        for r in range(h):
            for c in range(w):
                v = d[r * w + c]
                grid[r][
                    c] = 1 if v > self.occupied_threshold * 100 or v < 0 else 0
                if grid[r][c] == 1:
                    num_ones += 1
                else:
                    num_zeros += 1

        rospy.loginfo("Thresholding complete! {} ones, {} zeros.".format(
            num_ones, num_zeros))
        rospy.loginfo("value at goal: {}".format(grid[sy][sx]))
        traj = a_star_search(grid, (sx, sy), (gx, gy))

        if traj is None:
            rospy.logwarn("No valid path found to goal! Returning")
            return GetPlanResponse()

        traj = [[pt[0] * res, pt[1] * res] for pt in traj]

        rospy.loginfo("...Found path of length {} points".format(len(traj)))

        response = GetPlanResponse()
        response.plan = traj2path(traj)
        return response
Esempio n. 6
0
def debug_astar(area, scr):
    player = [actor for actor in area.all_actors() if actor.is_player()][0]
    mongoosen = [actor for actor in area.all_actors() if actor.cur_glyph() == 'o']
    if not mongoosen:
        return

    mongoose = mongoosen[0]
    mongoose_loc = area.find_actor(mongoose)
    player_loc = area.find_actor(player)
    from astar import a_star_search
    path = a_star_search(area.cells, mongoose_loc, player_loc) or []
    for p in path:
        scr.addstr(p.y, p.x, '*'.encode('utf-8'))
Esempio n. 7
0
def main():
    """main program

    :param argv[1]: Start city
    :param argv[2]: Dest city
    :param argv[3]: Heuristique
    :returns: List of the cities to go through

    Correct syntax:
    python app.py start_city dest_city heuristique

    Concrete example :
    python app.py Copenhagen Lisbon h0

    List of available heuristiques:
        h0 -> 0
        h1 -> abs(city1.x-city2.x)
        h2 -> abs(city1.y-city2.y)
        h3 -> math.sqrt((c1.x-c2.x)**2+(c1.y-c2.y)**2)
        h4 -> h1(c1,c2)+h2(c1,c2)

    Notes: Cities' names are case insensitive
    Dependencies:
        positions.txt - Contains a list of all cities
        connections.txt - Contains a list of all connections between cities
    """
    import sys
    if len(sys.argv) != 4:
        print("Invalid use!")
        print(main.__doc__)
        exit(-1)

    cities = load_config()

    start_city = check_city(cities, sys.argv[1])
    dest_city = check_city(cities, sys.argv[2])
    heuristique = check_heuristique(MapHeuristic, sys.argv[3])

    (cities, total_length,
     nb_iteration) = a_star_search(start_city, dest_city, heuristique)
    print('RESULT :')
    print(' -> '.join([city.name for city in cities]))
    print(f"Total Length : {total_length}")
    print(f"Nb iterations : {nb_iteration}")
Esempio n. 8
0
    def walkToRedCell(self, grid, pos):

        gridFind = astar.GridWithWeights(len(grid), len(grid[0]))
        new = []
        for i in range(0, len(grid)):
            for j in range(0, len(grid[0])):
                if grid[i][j].flag == 1:
                    new.append((i, j))

        gridFind.weights = {loc: 5 for loc in new}
        gridFind.walls = new
        end = (self.ideal[0], self.ideal[1])
        start = (pos[0], pos[1])
        came, cost = astar.a_star_search(gridFind, start, end)
        path = astar.reconstruct_path(came, start, end)
        self.path = path
        # print(path)
        # astar.draw_grid(gridFind, width=2, path=astar.reconstruct_path(came, start=start, goal=end))
        return path
Esempio n. 9
0
def main():
    # Cross Configuration
    root = board.translate_input_to_array(['--000--',
                                           '--0X0--',
                                           '00XXX00',
                                           '000X000',
                                           '000X000',
                                           '--000--',
                                           '--000--'])

    # Plus Configuration
    # root = board.translate_input_to_array(['--000--',
    #                                        '--0X0--',
    #                                        '000X000',
    #                                        '0XXXXX0',
    #                                        '000X000',
    #                                        '--0X0--',
    #                                        '--000--'])

    # Fireplace Configuration
    # root = board.translate_input_to_array(['--XXX--',
    #                                        '--XXX--',
    #                                        '00XXX00',
    #                                        '00X0X00',
    #                                        '0000000',
    #                                        '--000--',
    #                                        '--000--'])

    # Up Configuration
    # root = board.translate_input_to_array(['--0X0--',
    #                                        '--XXX--',
    #                                        '0XXXXX0',
    #                                        '000X000',
    #                                        '000X000',
    #                                        '--XXX--',
    #                                        '--XXX--'])

    # Pyramid Configuration
    # root = board.translate_input_to_array(['--000--',
    #                                        '--0X0--',
    #                                        '00XXX00',
    #                                        '0XXXXX0',
    #                                        'XXXXXXX',
    #                                        '--000--',
    #                                        '--000--'])

    # Diamond Configuration
    # root = board.translate_input_to_array(['--0X0--',
    #                                        '--XXX--',
    #                                        '0XXXXX0',
    #                                        'XXX0XXX',
    #                                        '0XXXXX0',
    #                                        '--XXX--',
    #                                        '--0X0--'])

    # Goal Configuration
    goal = board.translate_input_to_array(['--000--',
                                           '--000--',
                                           '0000000',
                                           '000X000',
                                           '0000000',
                                           '--000--',
                                           '--000--'])

    hp = hpy()
    before = hp.heap()
    start_time = time.time()
    count, parent = astar.a_star_search(root, goal)
    end_time = time.time()
    after = hp.heap()
    answer = astar.backtrack(parent, root, goal)
    leftover = after - before

    print "A* Search: Total Manhattan distance heuristic"
    print "Total number of nodes expanded: %d" % count
    print "Answer depth: %d" % len([move for move, _ in answer])
    print "Moves: %s" % [move for move, _ in answer]
    print "Time: %d seconds" % (end_time - start_time)
    # print leftover
    print "---\n"


    before = hp.heap()
    start_time = time.time()
    count, parent = astar.a_star_search(root, goal, simple=True)
    end_time = time.time()
    after = hp.heap()
    answer = astar.backtrack(parent, root, goal)
    leftover = after - before

    print "A* Search: Number of pegs heuristic"
    print "Total number of nodes expanded: %d" % count
    print "Answer depth: %d" % len([move for move, _ in answer])
    print "Moves: %s" % [move for move, _ in answer]
    print "Time: %d seconds" % (end_time - start_time)
    # print leftover
    print "---\n"

    before = hp.heap()
    start_time = time.time()
    depth, count = pruned_ids.iterative_deepening_search(root, goal)
    end_time = time.time()
    after = hp.heap()
    leftover = after - before

    moves = pruned_ids.solution_moves[::-1]
    print "Pruned Iterative Deepening Search:"
    print "Total number of nodes expanded: %d" % count
    print "Answer depth: %d" % depth
    print "Moves: %s" % moves
    print "Time: %d seconds" % (end_time - start_time)
    # print leftover
    print "---\n"

    before = hp.heap()
    start_time = time.time()
    depth, count = ids.iterative_deepening_search(root, goal)
    end_time = time.time()
    after = hp.heap()
    leftover = after - before

    moves = ids.solution_moves[::-1]
    print "Iterative Deepening Search:"
    print "Total number of nodes expanded: %d" % count
    print "Answer depth: %d" % depth
    print "Moves: %s" % moves
    print "Time: %d seconds" % (end_time - start_time)
    # print leftover
    print "---\n"