示例#1
0
class Map:
    def __init__(self):
        self.map = []
        self.finder = AStarFinder(diagonal_movement=DiagonalMovement.never)

    def load(self, path):
        im = Image.open(path)
        w, h = im.size
        v = list(
            map(lambda p: 1 if (p[0] + p[1] + p[2]) // 3 > 127 else 0,
                im.getdata()))
        self.grid = Grid(matrix=[v[i * w:(i + 1) * w] for i in range(h)])

    def width(self):
        return len(self.map[0])

    def height(self):
        return len(self.map)

    def find_path(self, a, b):
        start = self.grid.node(a[0], a[1])
        end = self.grid.node(b[0], b[1])
        path, runs = self.finder.find_path(start, end, self.grid)
        self.grid.cleanup()
        return path
def dtw_path(map_array):
    # Create grid using the map array
    grid = Grid(matrix=map_array)
    x_max, y_max = map_array.shape

    # Create grid points at start of each, and the end of each
    # node in (y,x) format
    start = grid.node(0, 0)
    end = grid.node(y_max - 1, x_max - 1)

    # Path find
    finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
    path_dtw, runs = finder.find_path(start, end, grid)

    # Return the path
    return path_dtw
示例#3
0
def optimal_path(mtrx, coords):
    # Create grid from matrix
    grid = Grid(matrix=mtrx)
    # Create starting point node from coordinates
    start = grid.node(coords[0][1], coords[0][0])
    # Create target point node from coordinates
    end = grid.node(coords[1][1], coords[1][0])
    # Initialize finder as instance of AStarFinder that allows for diagonal movement
    finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
    # Find optimal path and number of runs between starting point and target point
    path, runs = finder.find_path(start, end, grid)

    print('Number of runs: ', runs)
    print('Path length: ', len(path), '\n')

    return path
示例#4
0
def route(start, end, matrix) -> path:
    """
    Take a matrix of the level in the form wighted numbers, a start and stop point, and return a path between them.

    param: start: (x, y) location of the monster
    param: end: (x, y) location of the player
    param: matrix: a 2d list of the level. 0s are walls, numbers greater than 0 are weighted
    """

    grid = Grid(matrix=matrix)
    start = grid.node(start[0], start[1])
    end = grid.node(end[0], end[1])
    finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
    path, runs = finder.find_path(start, end, grid)

    return path
示例#5
0
    def __init__(self, map_id: int = 0):
        """

        Parameters
        ----------
        map_id: int
            Which version of the game to play. Legal values are 0 and 1. Default is 0.
            Corresponds to the hard-coded maps MAP0 and MAP1 defined in the same module.
        """
        if map_id == 0:
            used_map = MAP0
        elif map_id == 1:
            used_map = MAP1
        # if adding more values here, also adapt docstring above.
        else:
            raise NotImplementedError()

        # get arrays of walls and reward fields:
        self.map_walls, self.map_rewards = get_maps(used_map)
        self.rews_where = np.where(self.map_rewards > 0)
        # get list of coordinates for reward fields:
        self.rew_coords = get_rew_coords(self.map_rewards)
        # get number of rewards in map_id:
        self.num_rewards = len(self.rews_where[0])

        # calculate all possible paths, using the 'pathfinding' library.
        self.paths = {}
        matrix = np.swapaxes(np.abs(self.map_walls - 1.0), 0, 1).tolist()
        finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
        for i in range(self.num_rewards):
            self.paths[i] = {}
            for j in range(self.num_rewards):
                grid = Grid(matrix=matrix)
                start = grid.node(self.rews_where[0][i], self.rews_where[1][i])
                end = grid.node(self.rews_where[0][j], self.rews_where[1][j])
                path, _ = finder.find_path(start, end, grid)
                path = [[int(x[0]), int(x[1])] for x in path]
                self.paths[i][j] = path

        super(MazeWorld, self).__init__()

        # set observation space and action space:
        self.observation_space = MultiBinary(self.num_rewards * 2)
        self.action_space = Discrete(self.num_rewards)

        self.current_state = None
        self.terminated = True
示例#6
0
def find_path(matrix, start_x, start_y, end_x, end_y, tile_size, map_height):
    """
    Creates a path from a matrix of barriers, a start position,
    a desired end position, the size of tiles used in a map,
    and the map's height (in tiles).
    """

    # TODO: Get map height from matrix instead of it being a parameter

    grid = Grid(matrix=matrix)

    start_x = clamp(start_x, 0, start_x)
    start_y = clamp(start_y, 0, start_y)
    end_x = clamp(end_x, 0, end_x)
    end_y = clamp(end_y, 0, end_y)

    print(len(matrix))
    print((int(start_x / tile_size), map_height - int(start_y / tile_size),
           (int(end_x / tile_size), map_height - int(end_y / tile_size))))

    # For some reason the y value is inverted. Probably has to do with the grid
    # Hence map_height - ...,

    # TODO: Figure out why bottom of the map causes IndexError

    try:
        start = grid.node(int(start_x / tile_size),
                          map_height - int(start_y / tile_size) - 1)

        end = grid.node(int(end_x / tile_size),
                        map_height - int(end_y / tile_size))

        finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
        path, runs = finder.find_path(start, end, grid)
    except IndexError:
        print("Out of range.")
        path = []

    # Again, subtracting by the tile height otherwise the path is flipped
    path_resized = [(position[0] * tile_size,
                     (map_height - position[1]) * tile_size)
                    for position in path]

    # print('operations:', runs, 'path length:', len(path))
    # print(grid.grid_str(path=path, start=start, end=end))

    return path_resized
示例#7
0
    def update(self):
        # definitions for later calculations
        xgrid = (self.rect.x + self.width - 1)// 20  
        ygrid = (self.rect.y + self.height - 1) // 20
        centrex = self.rect.x + self.width // 2
        centrey = self.rect.y + self.height // 2

        #pathfinding logic

        ## if the target square has been reached sets the next one        
        if (self.targetx == centrex) and (self.targety == centrey):
            if ((pacman.rect.x // 20 > 0) and (pacman.rect.y // 20 > 0) and (pacman.rect.x // 20 + 1  <= maxsizex - 1 ) and (pacman.rect.y  // 20 + 1 <= maxsizey -1 )):   
                start = self.grid.node(ygrid, xgrid)
                end = self.grid.node((pacman.rect.y + pacman.rect.height // 2) //  20, (pacman.rect.x + pacman.rect.width // 2) // 20)
                finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
                #self.grid.cleanup()
                path, runs = finder.find_path(start, end, self.grid)
                self.grid.cleanup()
                if len(path) <= 1:
                    oneblock = True
                else:
                    oneblock = False
                    self.targetx = (int(path[1][1]) * 20 + 10)
                    self.targety = (int(path[1][0]) * 20 + 10)
                #print(path)
                #print('operations:', runs, 'path length:', len(path))
                #print(self.grid.grid_str(path=path, start=start, end=end))
        ## moves the enemy to the target square
        else:
            speedmultiplyer = 0
            xdir = 0
            ydir = 0
            if centrex < self.targetx:
                speedmultiplyer += 1
                xdir = 1
            elif centrex > self.targetx:
                speedmultiplyer += 1
                xdir = -1
            elif centrey < self.targety:
                speedmultiplyer += 1
                ydir = 1
            elif centrey > self.targety:
                speedmultiplyer += 1
                ydir = -1
            self.rect.x += xdir * enemymovespeed / speedmultiplyer
            self.rect.y += ydir * enemymovespeed / speedmultiplyer
示例#8
0
文件: ai.py 项目: ironsmile/tank4eta
 def __init__(self, world):
     self.world = world
     self.map = world.map
     self.pathfinder = AStarFinder(
         diagonal_movement=DiagonalMovement.never,
         time_limit=0.006
     )
     self.path_cache_duration = 1000
示例#9
0
def find_path(board, start, end, trim_tip=False, prune_tip=False):
    tip_stack = board.agent_snake.tip_stack()
    head_distance = board.pt_distance(start, end)
    if prune_tip or trim_tip and head_distance > tip_stack:
        logger.debug('Trimming tip of snake with {} tips stacked and {} away.'.format(tip_stack, head_distance))
        board_c = deepcopy(board)
        board_c[end.y][end.x] = None
        grid = Grid(matrix=board_c)
    else:
        grid = Grid(matrix=board)

    start_pt = grid.node(start.x, start.y)
    end_pt = grid.node(end.x, end.y)

    finder = AStarFinder()
    path, _ = finder.find_path(start_pt, end_pt, grid)
    return path
示例#10
0
def doPF(im):
    startX, startY = pickPoint(im)
    endX, endY = pickPoint(im)
    print(startX, startY, " -> ", endX, endY)

    matrix = makePathMatrix(im)

    grid = Grid(matrix=matrix)

    start = grid.node(startX, startY)
    end = grid.node(endX, endY)

    finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
    path, runs = finder.find_path(start, end, grid)

    print('operations:', runs, 'path length:', len(path))
    return path
示例#11
0
def findPath(start,
             end):  # Function that queries the pathfinding library for path
    global pathMatrix

    grid = Grid(matrix=pathMatrix)

    start = grid.node(start[0], start[1])
    end = grid.node(end[0], end[1])

    finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
    path, runs = finder.find_path(start, end, grid)

    print('operations:', runs, 'path length:', len(path))
    print(grid.grid_str(path=path, start=start, end=end))
    print(path)

    return path
def create_grid_and_find_path(matrix, start, end, time_limit, wrap=False):
    grid = Grid(matrix=matrix, wrap=wrap)

    start = grid.node(start.x, start.y)
    end = grid.node(end.x, end.y)

    # finder = AStarFinder(diagonal_movement=DiagonalMovement.never, heuristic='world_wrap')
    finder = AStarFinder(diagonal_movement=DiagonalMovement.never,
                         time_limit=time_limit,
                         heuristic='world_wrap')

    path, runs = finder.find_path(start, end, grid)

    return path


# test()
def getPath(start, end):

    maze = [[0 for x in range(len(pathfinding_grid[0]))]
            for y in range(len(pathfinding_grid))]

    for x in pathfinding_grid:
        for e in x:
            maze[e.ex][e.ey] = e.difficulty

    if nodeFromCords(end[0]) > len(maze) - 1:
        print("target out of bounds")
        return []
    if nodeFromCords(end[1]) > len(maze[0]) - 1:
        print("out of bounds")
        return []

    #find the closest node to the real world cords.
    if pathfinding_grid[nodeFromCords(end[0])][nodeFromCords(
            end[1])].difficulty == 0:
        print("BAD TARGET POSITION")
        return []

    grid = Grid(matrix=maze)

    start_node = grid.node(nodeFromCords(start[1]), nodeFromCords(start[0]))
    end_node = grid.node(nodeFromCords(end[1]), nodeFromCords(end[0]))

    #This accepts weights. So 0 is wall, 1+ is increasingly harder to traverse.
    finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
    path, runs = finder.find_path(start_node, end_node, grid)

    print('operations:', runs, 'path length:', len(path))
    #print(grid.grid_str(path=path, start=start, end=end))

    world_path = []

    if path != None:
        for e in path:
            world_path.append((e[0] / npm, e[1] / npm))
        #remove the first element in the list as that is the approx robot position.
        if len(world_path) > 1:
            world_path.pop(0)
            world_path[-1] = (end[1], end[0])

    return world_path
示例#14
0
 def __init__(self):
     # in the end, `self.terrain_grid` will be a 2D array of values where zeros are obstacles
     #       and all values greater than zero are edge weights for all edges connected to that node
     self.terrain_grid = []
     with open("./resources/terrain.txt") as input:
         rows = input.readlines()
         # loop through entire terrain file and convert all chars to integers
         for row in rows:
             terrain_grid_row = []
             for col in row:
                 if col.isdigit():
                     terrain_grid_row.append(int(col))
             self.terrain_grid.append(terrain_grid_row)
     # instantiate the Grid object using the newly converted terrain_grid
     #       The pathfinding library requires this special object to work
     self.grid = Grid(matrix=self.terrain_grid)
     # define the A* pathfinding algorithm as the one we use. Another option is Dijkstra's
     self.finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
示例#15
0
 def pathfinder(img_array, startpoint, endpoint):
     matrix = img_array
     grid = Grid(matrix=matrix)
     start = grid.node(startpoint[0], startpoint[1])
     end = grid.node(endpoint[0], endpoint[1])
     finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
     path, runs = finder.find_path(start, end, grid)
     grid_str = grid.grid_str(path=path, start=start, end=end)
     print('operations:', runs, 'path length:', len(path))
     print(grid_str)
     img_array2 = img_array
     for node in path:
         col = node[0]
         row = node[1]
         img_array2[row][col] = 4
     img_array2[startpoint[1]][startpoint[0]] = 2
     img_array2[endpoint[1]][endpoint[0]] = 3
     return img_array2
    def path_finder(self, x0, y0, x1, y1):
        """
        Description
        -----------
        Finds a path between two points and returns a list of coordinates along the path
        Currently only checks for road-compatible paths by avoiding mountains and going on land when possible

        Params
        --------
        x0,y0,x1,y1 - coordinates for two points to connect
        """
        # Generate pathfinding grid

        matrix = [[0] * len(self.grid) for i in range(len(self.grid))]

        for column in self.grid:
            for cell in column:
                if cell.cell_type in [
                        CellTypes.land.value.LAND_3,
                        CellTypes.land.value.LAND_4,
                        CellTypes.land.value.LAND_5
                ]:
                    matIn = 0  # obstacles
                elif self.check_if_water(cell) or cell.cell_type in [
                        CellTypes.land.value.SAND_0,
                        CellTypes.land.value.RIVER_BANK
                ]:
                    matIn = 5  # water, only cross this if necessary
                elif cell.cell_type in [CellTypes.road.value.ROAD_DIRT]:
                    matIn = 1  # use existing roads when possible
                else:
                    matIn = 2  # free spaces
                matrix[cell.y][cell.x] = matIn

        pathGrid = Grid(matrix=matrix)

        # Find a path
        start = pathGrid.node(x0, y0)
        end = pathGrid.node(x1, y1)
        finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
        path, runs = finder.find_path(start, end, pathGrid)

        # Return the path
        return path
示例#17
0
def extract_skeleton_trace(img, roi_grid_size):
    skel = skeletonize(img)
    skel = skel.astype(np.float32)

    kernel = np.float32([[1, 1, 1], [1, 10, 1], [1, 1, 1]])

    output = ndimage.convolve(skel, kernel, mode='constant', cval=0.0)
    rr, cc = np.where(output == 11)

    endpoints = [(x, y) for x, y in zip(rr, cc)]
    low_resolution_endpoints = find_low_resolution_endpoints(
        img, roi_grid_size)

    used_endpoints = []
    for lre in low_resolution_endpoints:
        used_endpoints.append(
            sorted(endpoints,
                   key=lambda x: (x[0] - lre[0])**2 + (x[1] - lre[1])**2)[0])
    print(f'Used endpoints are: {used_endpoints}')

    finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
    path = []

    for s, e in zip(used_endpoints, used_endpoints[1:]):
        path += [s] * (roi_grid_size + 1)
        grid = Grid(matrix=skel.T)
        path += finder.find_path(grid.node(*s), grid.node(*e), grid)[0][1:-1]
    path += [used_endpoints[-1]] * (roi_grid_size + 1)
    path = path[0::roi_grid_size + 1]
    path = np.array(path)

    rr, cc = np.split(path, 2, axis=-1)

    ep_frame = np.zeros(img.shape)
    ep_frame[rr, cc] = 1

    kernel = np.ones((roi_grid_size, roi_grid_size))
    ep_frame = ndimage.convolve(ep_frame, kernel, mode='constant', cval=0.0)

    plt.imshow(np.stack([ep_frame, img, np.zeros(img.shape)], axis=-1))
    plt.xlabel('X')
    plt.ylabel('Y')

    return path
示例#18
0
def findPath(from_v, to_v):
    x_f = int(from_v.x)
    y_f = int(from_v.y)
    x_t = int(to_v.x)
    y_t = int(to_v.y)
    oldPathFrom = pathMatrix[y_f][x_f]
    oldPathTo = pathMatrix[y_t][x_t]
    pathMatrix[y_f][x_f] = 1
    pathMatrix[y_t][x_t] = 1
    gridPath = Grid(matrix=pathMatrix)
    start_p = gridPath.node(x_f, y_f)
    end = gridPath.node(x_t, y_t)
    finder = AStarFinder(
        diagonal_movement=DiagonalMovement.if_at_most_one_obstacle)
    path, runs = finder.find_path(start_p, end, gridPath)
    print(gridPath.grid_str(start=start_p, end=end, path=path))
    pathMatrix[y_f][x_f] = oldPathFrom
    pathMatrix[y_t][x_t] = oldPathTo
    return path
示例#19
0
    def findPath(self, startCoord, endCoord):
        matrix = (self.map == 0).T.astype(int)
        # note here that the matrix is transposed
        matrix[startCoord[1], startCoord[0]] = 1
        matrix[endCoord[1], endCoord[0]] = 1
        # print(matrix)
        grid = Grid(matrix=matrix.tolist())

        start = grid.node(startCoord[0], startCoord[1])
        end = grid.node(endCoord[0], endCoord[1])

        finder = AStarFinder(diagonal_movement=DiagonalMovement.never)

        path, runs = finder.find_path(start, end, grid)
        # print('operations:', runs, 'path length:', len(path))
        # print(grid.grid_str(path=path, start=start, end=end))

        p = myPath(startCoord, endCoord, len(path), path)
        return p
示例#20
0
    def path_find(self, start, end):
        grid = Grid(matrix=self.mapn)

        start_node = grid.node(start[0], start[1])
        end_node = grid.node(end[0], end[1])

        path, runs = AStarFinder(
            diagonal_movement=DiagonalMovement.never).find_path(
                start_node, end_node, grid)
        return path
示例#21
0
    def find_path_single_world(
        cls, world: CoordinateGrid, start_x_y: Tuple[float, float],
        end_x_y: Tuple[float,
                       float]) -> Union[List[Tuple[float, float]], None]:
        """
      world: the world split up in a grid with open cells and obstacle cells
      start: the (x, y) coordinates of the starting point in inches (IMPORTANT: Not row and column)
      end: the (x, y) coordinates of the ending point in inches (IMPORTANT: Not row and column)
    """
        start = world.get_nearest_tile(start_x_y)
        end = world.get_nearest_tile(end_x_y)

        finder = AStarFinder(
            diagonal_movement=DiagonalMovement.only_when_no_obstacle)
        path, runs = finder.find_path(start, end, world)
        if len(path) == 0:
            print("Warning unable to find PATH!!!!")
            return None
        return world.col_row_to_x_y_coordinates(path)[1:] + [end_x_y]
示例#22
0
    def Steps(self, obstacleClass=(Rock, Dirt, Ant)):
        matrix = []

        for i in range(len(self.maps[0])):
            matrix.append([])
            for j in range(len(self.maps[0][0])):
                matrix.append(0 if any(
                    [isinstance(m[i][j], obstacleClass)
                     for m in self.maps]) else 1)

        grid = Grid(matrix=matrix)

        start = grid.node(self.start.x, self.start.y)
        end = grid.node(self.dest.x, self.dest.y)

        finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
        path, runs = finder.find_path(start, end, grid)

        return [Point(n.x, n.y) for n in path]
def create_hallways(Map, regions):
    # Crea caminos que unan todas las regiones, sin ciclos
    # (MaxST con cada region como un nodo y su camino una arista)
    # print(f'len regions {len(regions)}')

    # Crear el objeto AStarFinder()
    finder = AStarFinder()

    first_region = regions[0]
    regions_visited = [first_region]
    regions_unresolved = regions[1:]

    # hallways = []

    Map_ones = np.ones((len(Map), len(Map[0])), dtype=int)

    while regions_unresolved:
        grid = Grid(matrix=Map_ones)

        region_u = regions_visited.pop()
        region_v = regions_unresolved.pop()

        regions_visited.append(region_v)

        # Hasta aqui tenemos la region u y la region v, queremos hallar un camino que las una
        #  Escogemos cualquier casilla de u y cualquiera de v y encontramos el camino minimo
        # que las una, con 'finder.find_path'.

        _u = region_u[0]
        _v = region_v[0]
        # Guardar las casillas u, v como nodos
        u = grid.node(_u[0], _u[1])
        v = grid.node(_v[0], _v[1])

        path, _ = finder.find_path(u, v, grid)

        # hallways.append(path)

        # Actualizar el mapa con los nuevos caminos
        for _grid in path:
            x = _grid[0]
            y = _grid[1]
            Map[y][x] = 0
def is_playable(start_end: Dict, room_matrix: List[List[int]], print_path: bool=False) -> bool:
    # TODO: invesgate
    # if len(start_end) < 2:
    #     playable = True
    #     return playable

    all_start_end = []
    for k in start_end:
        all_start_end = all_start_end + start_end[k]

    grid = Grid(matrix=room_matrix)
    comb = list(combinations(all_start_end, 2))
    playable = True
    # random.shuffle(comb)

    for _start, _end in comb:
        # print(_start, _end)
        # hardcode here
        
        # if (_start in start_end["D"] and _end in start_end["D"]) or (_start in start_end["S"] and _end in start_end["S"]):
        #     abs_dis = abs(_start[0] - _end[0]) + abs(_start[1] - _end[1])
        #     if abs_dis < 4:
        #         continue
        
        
        start = grid.node(_start[1], _start[0])
        end = grid.node(_end[1], _end[0])

        finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
        path, runs = finder.find_path(start, end, grid)

        if print_path and len(path) > 0:
            print('operations:', runs, 'path length:', len(path))
            print(grid.grid_str(path=path, start=start, end=end))
        
        grid.cleanup()

        if len(path) == 0:
            playable = False
            break

    return playable
示例#25
0
    def calc_path(data,q,grid):

        print('initiation')
        units={}
        for i in data:
            finder = AStarFinder(diagonal_movement=DiagonalMovement.never)



            table=Grid(matrix=grid)


            start=table.node(data[i][0][0],data[i][0][1])
            end=table.node(data[i][1][0],data[i][1][1])

            path, runs = finder.find_path(start, end, table)
            #units.append([i,path])
            units[i]=path
            
        q.put(units)
示例#26
0
def pathfind(blocks, less=False):
    matrix = np.ones((SIZE_X, SIZE_Y))
    for i in blocks:
        matrix[i[0]][i[1]] = 0

    matrix[0][10] = 1
    matrix[0][9] = 1
    matrix[19][10] = 1
    matrix[19][9] = 1

    grid = Grid(matrix=matrix)
    start = grid.node(10, 0)
    end = grid.node(10, 19)
    if less:
        finder = AStarFinder(diagonal_movement=1)
    else:
        finder = AStarFinder(diagonal_movement=2)
    (path, runs) = finder.find_path(start, end, grid)

    return path
示例#27
0
def path(start, end, tmx, layers=None):
    # Create matrix for A* to read
    if not layers:
        layers = [0, 1]
    matrix = [[0] * tmx.width for row in range(0, tmx.height)]
    for layer in layers:
        for row in range(0, tmx.height):
            for column in range(0, tmx.width):
                tile = tmx.get_tile_properties(column, row, layer)
                if tile:
                    if tile['wall'] == 'true':
                        matrix[column][row] = 1

    # Calculate path and return list of tiles along route
    grid = Grid(matrix=matrix)
    start = grid.node(*start)  # format (30, 30)
    end = grid.node(*end)
    finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
    path, runs = finder.find_path(start, end, grid)
    return path
示例#28
0
    def generate(self):

        while True:

            self.maze = np.zeros([self.height, self.width])

            for i in range(self.height):
                for j in range(self.width):
                    if np.random.rand() <= self.obstacle_occupancy_prob:
                        self.maze[i][j] = 1

            temp_maze = 1 - copy.deepcopy(self.maze)

            grid = Grid(matrix=temp_maze)

            start = grid.node(self.agent_pose[0], self.agent_pose[1])
            end = grid.node(self.target_pose[0], self.target_pose[1])

            finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
            path, runs = finder.find_path(start, end, grid)

            if len(path) > 0: break

        self.maze = 3 * self.maze
        self.maze[self.agent_pose[0]][self.agent_pose[1]] = 1
        self.maze[self.target_pose[0]][self.target_pose[1]] = 2

        self.top_bottom_wall = 3 * np.ones([1, self.maze.shape[1]])

        self.maze = np.vstack(
            (self.top_bottom_wall, self.maze, self.top_bottom_wall))

        self.left_right_wall = 3 * np.ones([self.maze.shape[0], 1])

        self.maze = np.hstack(
            (self.left_right_wall, self.maze, self.left_right_wall))

        self.target_pose = [self.target_pose[0] + 1, self.target_pose[1] + 1]
        self.agent_pose = [self.agent_pose[0] + 1, self.agent_pose[1] + 1]

        return self.maze, self.agent_pose, self.target_pose, path
示例#29
0
def bfs(matrix, start, obstacles, target):
    new_matrix = []
    for i, row in enumerate(matrix):
        new_matrix.append([])
        for j, col in enumerate(row):
            if matrix[i][j] in obstacles:
                new_matrix[i].append(-1)
            else:
                new_matrix[i].append(1)

    grid = Grid(matrix=new_matrix)

    start = grid.node(start.x, start.y)
    end = grid.node(target.x, target.y)

    finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
    path, runs = finder.find_path(start, end, grid)
    #  print('operations:', runs, 'path length:', len(path))
    #  print(grid.grid_str(path=path, start=start, end=end))

    return list(map(lambda p: Point(p[0], p[1]), path))
示例#30
0
    def __init__(self, source: Union[str, TextIO]):
        """
        Reads a new map from a file or a string
        :param source: the file-like object or string describing the map (not a filename!)
        """
        if isinstance(source, str):
            input_string = source
        else:
            input_string = source.read()
        lines = input_string.splitlines()
        width, height, nCustomers, self.replyOffices = tuple(map(int,lines[0].split(' ')))
        self.customers = []
        for line in lines[1:1 + nCustomers]:
            x, y, reward = map(int,line.split(' '))
            self.customers.append(Map.Customer((x,y),reward))
        cost_matrix = []
        for line in lines[nCustomers + 1:] :
            cost_matrix.append([costs[char] for char in line])

        self.grid = Grid(width, height, cost_matrix)
        self.finder = AStarFinder()
示例#31
0
def create_waypoints(matrix, y_end, x_end):
    coords = [[0, 0], [3.5, 2.5], [3.5, 10.5], [3.5, 22.5], [10.5, 22.5],
              [20, 22.5], [34.5, 22.5], [34.5, 12], [34.5, 2.5], [19.5, 2.5],
              [19.5, 10.5]]

    reversed_test_maze = reverse.reverseZeroOne(matrix)
    grid = Grid(matrix=reversed_test_maze)

    start = grid.node(0, 0)
    end = grid.node(y_end, x_end)

    finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
    path, runs = finder.find_path(start, end, grid)

    print(grid.grid_str(path=path, start=start, end=end))

    for i in range(len(path)):
        (x, y) = path[i]
        path[i] = (y + 0.5, x + 0.5)

    return path
示例#32
0
文件: ai.py 项目: ironsmile/tank4eta
class ZombieDriver (Random):
    '''
    The ZombieDriver AI would follow the player relentlessly around without any
    thought or self preservation mechanism!
    '''

    fire_chance = 3
    moving_chance = 80
    turning_chance = 5

    def __init__(self, world):
        self.world = world
        self.map = world.map
        self.pathfinder = AStarFinder(
            diagonal_movement=DiagonalMovement.never,
            time_limit=0.006
        )
        self.path_cache_duration = 1000

    def tick(self, deltat, enemies):
        interesting_objects = []

        for player in self.world.players:
            if player.tank is None:
                continue
            interesting_objects.append((player.tank.rect, 1))

        for flag in self.world.un_flags:
            interesting_objects.append((flag.rect, 1.5))

        for enemy in enemies:
            self.process_enemy(enemy, deltat, interesting_objects)
            self.fire_at_will(enemy, deltat, interesting_objects)

    def process_enemy(self, enemy, deltat, interesting_objects):
        enemy.update_path_duration(deltat)
        own_coords = enemy.rect
        own_grid_pos = self.map.world_to_grid_coords(own_coords.centerx, own_coords.centery)

        if enemy.path_duration <= self.path_cache_duration:
            self.continue_path(enemy, own_grid_pos)
            return

        heat_obj = None
        heat_weight = 0
        for obj, weight in interesting_objects:
            dist = math.sqrt(
                abs(own_coords.centerx - obj.centerx) ** 2 +
                abs(own_coords.centery - obj.centery) ** 2
            )
            obj_weight = (1 / dist) * weight
            if obj_weight > heat_weight:
                heat_weight = obj_weight
                heat_obj = obj

        if heat_obj is None:
            logging.error("ZombieDriver AI finds nothing interesting on the map! How can that be!?")
            self.do_random_thing(enemy)
            return

        hobjx, hobjy = heat_obj.centerx, heat_obj.centery
        hobj_grid_pos = self.map.world_to_grid_coords(hobjx, hobjy)

        if hobj_grid_pos == enemy.current_target:
            enemy.reset_path_duration()
            self.continue_path(enemy, own_grid_pos)
            return

        # WTF!? You have to rebiuld the *whole* grid every time find_path is called!
        # Definately change to a better library or write A* myself.
        self.map.build_grid()

        pf_start = self.map.grid.node(*own_grid_pos)
        pf_end = self.map.grid.node(*hobj_grid_pos)

        path, runs = self.pathfinder.find_path(
            pf_start,
            pf_end,
            self.map.grid
        )

        enemy.set_current_path(path)
        self.continue_path(enemy, own_grid_pos)

    def fire_at_will(self, enemy, deltat, interesting_objects):
        if len(enemy.bullets) >= enemy.max_bullets:
            return
        for obj, weight in interesting_objects:
            if not enemy.is_facing(self.map, obj):
                continue

            firing_roll = random.randint(0, 100)
            if firing_roll < self.fire_chance:
                enemy.fire()

    def continue_path(self, enemy, grid_pos):
        next_node = enemy.get_path_next(grid_pos)

        if next_node is None:
            self.do_random_thing(enemy)
            return

        direction = self.map.grid_direction(grid_pos, next_node)

        if direction == DIRECTION_NONE:
            logging.error("For some reason the calculate direction returned NONE after pathfinding")
            self.do_random_thing(enemy)
        else:
            enemy.move(direction)