コード例 #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
コード例 #2
0
def is_playable(start_end: List, room_matrix: List[List[int]], print_path: bool=False) -> bool:
    if len(start_end) < 2:
        playable = True

        return playable

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

    for _start, _end in comb:
        # print(_start, _end)
        abs_dis = abs(_start[0] - _end[0]) + abs(_start[1] - _end[1])
        if abs_dis < 2:
            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:
            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
コード例 #3
0
ファイル: ghost.py プロジェクト: leowrites/Pacman-playable
 def find_path(self, grid, final):
     x = self.location[0]
     y = self.location[1]
     start = grid.node(x, y)
     end = grid.node(final[0], final[1])
     finder = AStarFinder()
     self.path, runs = finder.find_path(start, end, grid)
     Grid.cleanup(grid)
コード例 #4
0
 def get_good_place(self, places):
     grid = Grid(matrix=self._matrix)
     self._grid = grid
     path_list = []
     for place in places:
         path = self.get_path(place, grid)
         grid.cleanup()
         if path:
             path_list.append(path)
     return path_list
コード例 #5
0
    def get_other_player_path(self, afk_players):
        grid = Grid(matrix=self._matrix)
        self._grid = grid
        pnt = grid.node(self._me.get_x(), self._me.get_y())
        pnt.walkable = True

        if not afk_players:
            return None

        for bomber in afk_players:

            if self._victim and self._victim == bomber:
                continue
            path = self.get_path(bomber, grid)
            if path:
                #logger.debug(grid.grid_str(path=path,start=pnt))
                return path
            grid.cleanup()
        return None
コード例 #6
0
ファイル: pathfinder.py プロジェクト: Kimescha/Quoridor
    def find_path(self, player, show=False):
        """Return True if the player can finish"""
        x, y = self.pos_player_in_grid(player)
        grid = Grid(matrix=self.matrix)
        if player.orient == "north":
            x_end = self.side - 1
            for y_end in range(0, self.side, 2):
                start = grid.node(y, x)
                end = grid.node(y_end, x_end)
                path, runs = self.finder.find_path(start, end, grid)
                if path != []:
                    if show:
                        print(grid.grid_str(path=path, start=start, end=end))
                    return True
                grid.cleanup()

        elif player.orient == "east":
            y_end = 0
            for x_end in range(0, self.side, 2):
                start = grid.node(y, x)
                end = grid.node(y_end, x_end)
                path, runs = self.finder.find_path(start, end, grid)
                if path != []:
                    if show:
                        print(grid.grid_str(path=path, start=start, end=end))
                    return True
                grid.cleanup()

        elif player.orient == "south":
            x_end = 0
            for y_end in range(0, self.side, 2):
                start = grid.node(y, x)
                end = grid.node(y_end, x_end)
                path, runs = self.finder.find_path(start, end, grid)
                if path != []:
                    if show:
                        print(grid.grid_str(path=path, start=start, end=end))
                    return True
                grid.cleanup()

        elif player.orient == "west":
            y_end = self.side - 1
            for x_end in range(0, self.side, 2):
                start = grid.node(y, x)
                end = grid.node(y_end, x_end)
                path, runs = self.finder.find_path(start, end, grid)
                if path != []:
                    if show:
                        print(grid.grid_str(path=path, start=start, end=end))
                    return True
                grid.cleanup()

        return False
コード例 #7
0
ファイル: Obstacle.py プロジェクト: Pirhomega/SLIR-MWSU
class Obstacle_Grid():
    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)

    def find_shortest_path(self, location, destination):
        """
        Purpose:    create a list of spots in a 2D grid that define the shortest path
                    between two spots
        Input:      Starting location (`location`) and Ending location (`destination`)
        Output:     A list of spots/locations in the 2D grid
        """
        self.grid.cleanup()
        self.start = self.grid.node(location[1], location[0])
        self.end = self.grid.node(destination[1], destination[0])
        path_list, _ = self.finder.find_path(self.start, self.end, self.grid)
        return path_list

    def print_path_to_file(self, path_list):
        """
        Purpose:    Test function that prints the terrain with the shortest path between two nodes
                    to the console
        Input:      List of spots in terrain grid that define the shortest path between
                    two nodes.
        Output:     None
        """
        print(
            self.grid.grid_str(path=path_list, start=self.start, end=self.end))
コード例 #8
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
コード例 #9
0
ファイル: 15.py プロジェクト: GaimeWolves/advent-of-code-2018
 def move(self, caves, allies, enemies):
     possiblesquares = []
     for enemy in enemies:
         if len(enemy.getadjacent(caves, allies, enemies)) > 0:
             possiblesquares.append(
                 enemy.getadjacent(caves, allies, enemies))
     if len(possiblesquares) > 0:
         grid = Grid(matrix=createGrid(caves, allies, enemies))
         finder = BreadthFirstFinder(
             diagonal_movement=DiagonalMovement.never)
         start = grid.node(self.x, self.y)
         minimum = None
         for i, squares in enumerate(possiblesquares):
             for square in squares:
                 end = grid.node(square[0], square[1])
                 path, runs = finder.find_path(start, end, grid)
                 #if self.x == 3 and self.y == 1:
                 #print(grid.grid_str(path=path, start=start, end=end))
                 if len(path) == 0:
                     continue
                 if minimum == None or len(path) < minimum[0] or (
                         len(path) == minimum[0]
                         and square[2] < minimum[2]):
                     minimum = [
                         len(path), path[1], square[2], square[0], square[1]
                     ]
                 grid.cleanup()
             grid.cleanup()
         if minimum != None:
             selected = None
             end = grid.node(minimum[3], minimum[4])
             for mysquare in self.getadjacent(caves, allies, enemies):
                 start = grid.node(mysquare[0], mysquare[1])
                 path, runs = finder.find_path(start, end, grid)
                 #print(grid.grid_str(path=path, start=start, end=end))
                 if len(path) == 0:
                     continue
                 if selected == None or len(path) < selected[0] or (
                         len(path) == selected[0]
                         and mysquare[2] < selected[2]):
                     selected = [
                         len(path), path[0], mysquare[2], mysquare[0],
                         mysquare[1]
                     ]
                 grid.cleanup()
             self.x = selected[3]
             self.y = selected[4]
             if any(self.y + 1 == e.y and self.x == e.x
                    for e in enemies) or any(
                        self.y - 1 == e.y and self.x == e.x
                        for e in enemies) or any(
                            self.y == e.y and self.x + 1 == e.x
                            for e in enemies) or any(
                                self.y == e.y and self.x - 1 == e.x
                                for e in enemies):
                 enemies = self.attack(caves, allies, enemies)
     return enemies
コード例 #10
0
class Player(pygame.sprite.Sprite):
    def __init__(self, group, startPosition, tilemap, startSprite):
        self.sprite = stopSprites[startSprite]
        self.image = pygame.image.load(baseDir + self.sprite)
        self.rect = self.image.get_rect(center=-startPosition)

        self.cartesianPos = pygame.math.Vector2(startPosition.x,
                                                startPosition.y)
        self.isoMov = pygame.math.Vector2(startPosition.x, startPosition.y)
        self.isoReal = pygame.math.Vector2(startPosition.x, startPosition.y)
        self.destination = pygame.math.Vector2(startPosition.x,
                                               startPosition.y)

        self.canInteract = True
        self.useDepth = True

        self.mapData = tilemap.map
        self.grid = Grid(matrix=tilemap.map)

        self.finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
        self.path = 0
        self.actualPath = 0
        self.moving = False

        self.dX = 0
        self.dY = 0

        ## ANIMATION
        self.lastDir = startSprite
        self.walkCount = 0
        self.animationSpeed = 29
        self.lastUpdate = 0

        self.standUp = False

        self.tilemap = tilemap

        pygame.sprite.Sprite.__init__(self, group)

    def cartesianToIsometric(self, cartesian):
        self.isoMov = pygame.math.Vector2(
            (cartesian.x - cartesian.y) + self.tilemap.tileSize.x / 2 + 12,
            (cartesian.x + cartesian.y) / 2 + self.tilemap.tileSize.y * 4 +
            200)
        self.isoReal = pygame.math.Vector2(cartesian.x / 128,
                                           -cartesian.y / 128)

    def getAnimation(self):
        ## UP
        if (self.dY == -1 and self.dX == 0):
            if (self.walkCount < len(runFront)):
                self.image = pygame.image.load(baseDir + "Running5/" +
                                               runFront[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 0
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 2

        ## DOWN
        elif (self.dY == 1 and self.dX == 0):
            if (self.walkCount < len(runBack)):
                self.image = pygame.image.load(baseDir + "Running1/" +
                                               runBack[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 1
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 2

        ## LEFT
        elif (self.dX == -1 and self.dY == 0):
            if (self.walkCount < len(runLeft)):
                self.image = pygame.image.load(baseDir + "Running7/" +
                                               runLeft[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 2
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 2

        ## RIGHT
        elif (self.dX == 1 and self.dY == 0):
            if (self.walkCount < len(runRight)):
                self.image = pygame.image.load(baseDir + "Running3/" +
                                               runRight[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 3
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 2

        ## RIGHT-DOWN
        elif (self.dX == 1 and self.dY == 1):
            if (self.walkCount < len(runRightBack)):
                self.image = pygame.image.load(baseDir + "Running2/" +
                                               runRightBack[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 6
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 0

        ## RIGHT-UP
        elif (self.dX == 1 and self.dY == -1):
            if (self.walkCount < len(runRightUp)):
                self.image = pygame.image.load(baseDir + "Running4/" +
                                               runRightUp[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 7
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 0

        ## LEFT-DOWN
        elif (self.dX == -1 and self.dY == 1):
            if (self.walkCount < len(runLeftBack)):
                self.image = pygame.image.load(baseDir + "Running8/" +
                                               runLeftBack[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 4
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 2

        ## LEFT-UP
        elif (self.dX == -1 and self.dY == -1):
            if (self.walkCount < len(runLeftUp)):
                self.image = pygame.image.load(baseDir + "Running6/" +
                                               runLeftUp[self.walkCount])
                if pygame.time.get_ticks(
                ) - self.lastUpdate > self.animationSpeed:
                    self.lastDir = 5
                    self.walkCount += 1
                    self.lastUpdate = pygame.time.get_ticks()
            else:
                self.elapsed = 0
                self.walkCount = 2

        elif (self.standUp == True):
            if (self.walkCount < 185):
                self.image = pygame.image.load(baseDir + "StandingUP/" +
                                               standingUP[self.walkCount])
                #self.lastDir = 5
                self.walkCount += 1
                self.lastUpdate = pygame.time.get_ticks()
            else:
                self.standUp = False

        elif (self.dY == 0 and self.dX == 0):
            self.standUp = False
            self.image = pygame.image.load(baseDir + stopSprites[self.lastDir])

    def checkPosition(self):
        if (self.moving == True):
            if (self.isoReal.x == self.destination.x
                    and -self.isoReal.y == self.destination.y):
                self.dX = 0
                self.dY = 0
                self.actualPath += 1
                self.moving = False
                self.goToPosition()

            elif (self.isoReal.x == self.destination.x):
                self.dX = 0

            elif (-self.isoReal.y == self.destination.y):
                self.dY = 0

    def goToPosition(self):
        if (self.actualPath < len(self.path)):
            if (self.moving == False):
                self.destination = pygame.math.Vector2(
                    self.path[self.actualPath][0],
                    -self.path[self.actualPath][1])
                ## CHECK X
                if (self.isoReal.x > self.destination.x):
                    self.dX = -1
                elif (self.isoReal.x < self.destination.x):
                    self.dX = 1
                else:
                    self.dX = 0

                ## CHECK Y
                if (-self.isoReal.y > self.destination.y):
                    self.dY = -1
                elif (-self.isoReal.y < self.destination.y):
                    self.dY = 1
                else:
                    self.dY = 0

                self.moving = True
        else:
            self.path = 0
            self.actualPath = 0

    def ProcessInputs(self, isoClickPos):
        if (self.canInteract == True):
            if (isoClickPos.x >= 0 and isoClickPos.x <= 9
                    and isoClickPos.y >= 0 and isoClickPos.y <= 9):
                if (self.actualPath == 0):
                    mouseClick = pygame.mouse.get_pressed()
                    if mouseClick[0] == 1:
                        start = self.grid.node(int(self.isoReal.x),
                                               int(self.isoReal.y))
                        end = self.grid.node(int(isoClickPos.x),
                                             int(isoClickPos.y))
                        self.path = self.finder.find_path(
                            start, end, self.grid)[0]
                        #print(self.grid.grid_str(path=self.path, start=start, end=end))
                        self.goToPosition()
                        self.grid.cleanup()

    def Update(self, camera, surface):
        self.checkPosition()

        if (self.moving == True):
            walkingSound.play()
        else:
            walkingSound.stop()

        self.cartesianPos.x += self.dX * 4
        self.cartesianPos.y += self.dY * 4

        self.cartesianToIsometric(self.cartesianPos)

        self.getAnimation()
        self.rect.center = pygame.Vector2(self.isoMov.x, self.isoMov.y)
コード例 #11
0
def MouvePlayer(event):
    global startr
    for i in range(0, len(mmatrix)):
        for j in range(0, len(mmatrix[i])):
            if mmatrix[i][j] == "P":
                mmatrix[i][j] = 1
                startr = [j, i]

    grid = Grid(matrix=mmatrix)
    start = grid.node(startr[0], startr[1])
    Targetx = event.x
    Targety = event.y
    #Arrondi le x du clic
    XChanged = str(Targetx)
    if Targetx >= 100:
        XChanged = XChanged[1] + XChanged[2]
    XChanged = int(XChanged)
    if XChanged >= 50:
        TargetxArrondi = Targetx + (50 - XChanged)
    else:
        TargetxArrondi = Targetx - XChanged

    #Arrondi le y du clic
    YChanged = str(Targety)
    if Targety >= 100:
        YChanged = YChanged[1] + YChanged[2]
    YChanged = int(YChanged)
    if YChanged >= 50:
        TargetyArrondi = Targety + (50 - YChanged)
    else:
        TargetyArrondi = Targety - YChanged
    #print(TargetyArrondi) : The coords of your click
    end = grid.node(int(TargetxArrondi / 50), int(TargetyArrondi / 50))
    finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
    path, runs = finder.find_path(start, end, grid)
    if len(path) == 0:
        print("C'est un cul de sac")
        #I tryed to play a song, but it doesn't work :/
        os.system('start Nope.mp3')
    else:
        PlayerPosition = startr
        #print(path) : Write the path the algorithm gonna use ! Pretty cool right ?
        Speed = 50
        for mouvement in range(0, len(path)):
            oldP = PlayerPosition
            thenext = path[mouvement]
            colorcase = FindWhatToSeen(mmatrix[thenext[1]][thenext[0]])
            oldcasePriority = mmatrix[thenext[1]][thenext[0]]
            PlayerPosition = path[mouvement]
            mmatrix[PlayerPosition[1]][PlayerPosition[0]] = "P"
            mmatrix[oldP[1]][oldP[0]] = oldcasePriority
            c.coords(Player, PlayerPosition[0] * 50, PlayerPosition[1] * 50,
                     PlayerPosition[0] * 50 + 50, PlayerPosition[1] * 50 + 50)
            c.update()
            c.tag_raise(Player)
            Factor = 1
            if colorcase == "blue":
                Factor = oldcasePriority * 10
            c.after(Speed * Factor)
            #Change the speed with the Factor : In progress
    Grid.cleanup(grid)
コード例 #12
0
                        path_founds[a1] = [
                            path_founds[a1][0] + 1,
                            max(path_founds[a1][1], step_level)
                        ]
                        if not a2 in path_founds:
                            path_founds[a2] = [0, 0]
                        path_founds[a2] = [
                            path_founds[a2][0] + 1,
                            max(path_founds[a2][1], step_level)
                        ]
                        print('Current path founds for ' + str(a1) + ' = ' +
                              str(path_founds[a1][0]) + ' with step_level ' +
                              str(path_founds[a1][1]))
                        print('Current path founds for ' + str(a2) + ' = ' +
                              str(path_founds[a2][0]) + ' with step_level ' +
                              str(path_founds[a2][1]))
                    grid.cleanup()

            step_level += 1

    with open(scen_file_path + '/Paths/' + str(kind) + '.json',
              mode='w',
              encoding='utf-8') as fout:
        fout.write(
            json.dumps(kind_paths,
                       indent=0,
                       separators=(',', ':'),
                       ensure_ascii=False,
                       sort_keys=True))
コード例 #13
0
class MainAgent(Agent):
    """
    Klasa główna z której dziedziczą potem poszczególne typy jednostek

    Arg:
    id (int): unikalny id agenta
    model : model w którym agent będzie działać
    """
    def __init__(self, id, model):
        super().__init__(id, model)
        self.pos = None
        self.health = 100
        self.attack = 10
        self.defence = 0.25
        self.cost = 0
        self.model = model
        self.color = "red"
        self.type = 'I'
        self.timer = True
        self.help_grid = []
        self.Grid = Grid(matrix=self.help_grid)

    def update_path(self, enemy):
        """
        Aktualizuje plansze przeszkód widzianych przez agenta
        :param enemy: Agent który ma być widziany nie jako przeszkoda
        :return:
        """

        self.help_grid.clear()
        temp = []
        for i in range(self.model.height):
            temp.clear()
            for j in range(self.model.width):
                if self.model.grid.is_cell_empty(
                    (j, i)) or self.pos == (j, i) or enemy.pos == (j, i):
                    temp.append(1)
                else:
                    temp.append(0)
            self.help_grid.append(temp[:])
        self.Grid = Grid(matrix=self.help_grid)

    def get_pos(self):
        """
        Getter pozycji
        :return: zwraca pozycję
        """

        return self.pos

    def get_cost(self):
        """
        Getter kosztu
        :return: zwraca koszt
        """
        return self.cost

    def get_dmg(self):
        """
        Getter obrażeń
        :return: zwraca atak jednostki
        """

        return self.attack

    def get_hp(self):
        """
        getter życia
        :return: zwraca aktualne życie agenta
        """

        return self.health

    def get_color(self):
        """
        getter koloru
        :return: zwraca kolor agenta
        """

        return self.color

    def set_hp(self, hp):
        """
        ustawia życie agenta
        :param hp: nowe życie agenta
        :return:
        """

        self.health = hp

    def set_color(self, color):
        """
        ustawia kolor agenta
        :param color: nowy kolor agenta
        :return:
        """

        self.color = color

    def scout(self, n):
        """
        Szuka w zasiegu (n) przeciwników
        :param n: zasięg
        :return: zwraca listę przeciwników
        """

        field = self.model.grid.get_neighbors(
            self.pos,  # Pozycja jednostki
            True,  # True=Moore neighborhood False=Von Neumann neighborhood
            False,  # Srodek
            n  # Promien
        )
        opponents = []
        for a in field:
            if a.get_color() == self.get_color() or a.get_color() == '#000000':
                pass
            else:
                opponents.append(a)
        return opponents

    def nearest_fields(self, n):
        """
        sprawdza pola na które agent może przejść w zasięgu
        :param n: zasięg
        :return: zwraca listę krotek
        """
        fields_around = self.model.grid.get_neighborhood(
            self.pos, True, False, n)
        return fields_around

    # def advanced_scout(self,pos):

    def move(self):
        """
        Metoda poruszająca agenta
        Kiedy nikogo nie widzi porusza się losowo
        Jak widzi to idzie w jego stronę najszybszą ścieżką
        :return:
        """

        others = self.scout(18)

        if len(others) < 1:
            self.model.grid.move_agent(
                self, self.random.choice(self.nearest_fields(1)))
        else:
            nemesis = self.random.choice(others)
            self.update_path(nemesis)

            start = self.Grid.node(self.pos[0], self.pos[1])
            end = self.Grid.node(nemesis.pos[0], nemesis.pos[1])

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

            if len(path) > 0:
                if self.model.grid.is_cell_empty((path[1][0], path[1][1])):
                    self.model.grid.move_agent(self, (path[1][0], path[1][1]))
            else:
                print("im stuck")
            self.Grid.cleanup()

    def attack_opponent(self):
        """
        Szuka w swojej okolicy przeciwników i atakuje ich
        :return:
        """

        opponents = self.scout(1)

        if len(opponents) > 0:
            other = self.random.choice(opponents)
            other.hurt_me(self.get_dmg())

    def hurt_me(self, dmg):
        """
        Zadaje obrażenia agentowi
        :param dmg: ilośc obrażeń
        :return:
        """
        hit = random.randint(1, 100) / 100
        if hit > self.defence:
            hp = self.get_hp()
            hp -= dmg
            self.set_hp(hp)
            self.check_dead()

    def step(self):
        """
        Co ma robić podczas wywołania przez scheduler modelu
        :return:
        """

        neighbors = self.scout(1)

        if len(neighbors) < 1 & self.timer:
            self.move()
            self.timer = not self.timer
        else:
            self.attack_opponent()
            self.timer = not self.timer

    def check_dead(self):
        """
        Sprawdza czy agent jest martwy,
        Jak jest to usuwa go z modelu
        :return:
        """

        if self.get_hp() <= 0:
            self.model.grid.remove_agent(self)
            self.model.schedule.remove(self)
コード例 #14
0
class CellularAutomata():
    def __init__(self,
                 player,
                 manager_dict,
                 debug=False,
                 consecutive_moves_no_shot=1,
                 risk_007=0.1,
                 mode="kamikaze"):
        ################MODE
        #KAMIKAZE
        #Trova il path minimo e va dritto alla bandiera,
        #cambia il path solo se si trova bloccato
        #007
        #Trova il path minimo controllando anche la posizione degli avversari
        #preferisce cammini più sicuri per raggiungere la bandiera
        #cambia sempre il path a seconda degli avversari
        #Ha una percentuale di rischio impostabile
        #TODO: gestire il caso di 007 come impostore
        ################
        self.finished = False
        self.debug = debug
        self.already_shoot = []
        self.last_shot = False
        self.grid_cellular_map = Grid()
        self.consecutive_moves_no_shot = consecutive_moves_no_shot
        self.path = []
        self.mode = mode
        self.risk_007 = risk_007

        self.manager_dict = manager_dict

        self.game_interface = player
        self.visual = VisualComponent(player)
        self.flag_symbol = self.visual.getFlag()
        self.loyality = self.visual.getLoyality()
        self.player_position = self.visual.getPlayerPosition()
        self.game_symbol = self.visual.getPlayerGameSymbol()
        self.enemies = self.visual.get_enemies()
        self.raw_map, _ = self.game_interface.process_map()

        self.flag = np.where(self.raw_map == self.flag_symbol)

        if (self.flag == []):
            res = self.game_interface.interact("leave", text="No Flag in Map")
            if (self.debug):
                print(res)
                print("Error Flag")

        self.flag = (self.flag[0][0], self.flag[1][0])

    def update(self):
        self.raw_map, response = self.game_interface.process_map()

        if (self.debug):
            print(response)

        self.grid_cellular_map = Grid(width=len(self.raw_map),
                                      height=len(self.raw_map[0]))

        list_enemies_position = []
        for row in range(len(self.raw_map)):
            for column in range(len(self.raw_map[0])):

                current_cell = self.raw_map[row][column]
                walkable = True
                if (current_cell == "#" or current_cell == "@"
                        or current_cell == "!" or current_cell == "&"
                        or current_cell == self.flag_symbol.swapcase()):
                    result = -1
                    walkable = False
                elif (current_cell == "$"):
                    result = 2
                    walkable = True
                elif (self.is_enemy(current_cell)):
                    result = 5
                    walkable = True
                    if (self.visual.game_symbol != current_cell
                            and self.visual != self.flag_symbol):
                        list_enemies_position.append((row, column))
                else:
                    result = 5
                    walkable = True

                self.grid_cellular_map.nodes[column][row] = Node(
                    x=row, y=column, walkable=walkable, weight=result)

        if (self.mode == "007"):
            if (random.uniform(0, 1) >= self.risk_007):

                next_move = {}

                if (self.player_position[0] + 1 <= len(self.raw_map)):
                    next_move["S"] = (self.player_position[0] + 1,
                                      self.player_position[1])
                if (self.player_position[0] - 1 >= 0):
                    next_move["N"] = (self.player_position[0] - 1,
                                      self.player_position[1])
                if (self.player_position[1] - 1 <= 0):
                    next_move["O"] = (self.player_position[0],
                                      self.player_position[1] - 1)
                if (self.player_position[1] + 1 <= len(self.raw_map)):
                    next_move["E"] = (self.player_position[0],
                                      self.player_position[1] + 1)

                for key in next_move:
                    old_node = self.grid_cellular_map.nodes[next_move[key][0]][
                        next_move[key][1]]
                    for enemy_position in list_enemies_position:
                        if (enemy_position[1] == next_move[key][1]
                            ):  # Se la colonna è la stessa
                            self.grid_cellular_map.nodes[next_move[key][1]][
                                next_move[key][0]] = Node(
                                    x=next_move[key][0],
                                    y=next_move[key][1],
                                    walkable=old_node.walkable,
                                    weight=11)

                        if (enemy_position[0] == next_move[key][0]
                            ):  # Se la riga è la stessa
                            self.grid_cellular_map.nodes[next_move[key][1]][
                                next_move[key][0]] = Node(
                                    x=next_move[key][0],
                                    y=next_move[key][1],
                                    walkable=old_node.walkable,
                                    weight=11)

    def move(self):
        # Prima Mossa o errore precedente o mod 007
        if (self.path == []):
            start = self.grid_cellular_map.node(self.player_position[0],
                                                self.player_position[1])
            end = self.grid_cellular_map.node(self.flag[0], self.flag[1])

            self.grid_cellular_map.cleanup()
            finder = AStarFinder(diagonal_movement=DiagonalMovement.never,
                                 time_limit=10000,
                                 max_runs=100000)
            self.path, _ = finder.find_path(start, end, self.grid_cellular_map)

            self.n_moves = 1

            if (self.path == []):  # Path non trovato
                res = self.game_interface.interact("leave",
                                                   text="No path found")
                if (self.debug):
                    print("No path")
                    print(res)
                return 2

        for i in range(0, self.consecutive_moves_no_shot):

            path_x, path_y = self.path[self.n_moves][0], self.path[
                self.n_moves][1]

            direction = ""
            if (self.player_position[0] < path_x):
                direction = "S"
            elif (self.player_position[0] > path_x):
                direction = "N"
            elif (self.player_position[1] > path_y):
                direction = "W"
            else:
                direction = "E"

            command_mov = self.game_interface.interact("move", direction)

            self.n_moves += 1
            if (self.debug):
                print(command_mov)

            if ("blocked" not in command_mov):
                self.player_position = (path_x, path_y)
            else:
                if (self.debug):
                    print("I'm here with the player: " +
                          self.game_interface.player_name)

                result = self.game_interface.status("status")
                index_game_active = result.find("GA: name=" +
                                                self.game_interface.game_name +
                                                " " + "state=")
                condition_game_active = result[index_game_active + 9 + len(
                    str(self.game_interface.game_name)) + 7]

                check_player_active = [
                    True for elem in result.splitlines()
                    if (self.game_interface.player_name in elem
                        and "ACTIVE" in elem)
                ]

                # Vittoria
                if (self.raw_map[path_x][path_y] == self.flag_symbol
                        and condition_game_active.lower() != "a"):
                    return 1

                # Se il gioco è finito
                if (condition_game_active.lower() != "a"):
                    print("Game Finished, no win")
                    return 2
                else:
                    # Se è ancora vivo
                    if (check_player_active == [True]):
                        self.path = []
                    else:
                        pass

        if (self.mode == "007"):
            self.path = []
        return 0

    def attack(self):
        # print(self.game_interface.deduction_game(command="accuse",player="pl6"))
        # print(self.game_interface.deduction_game(command="judge",player="pl6",player_nature="AI"))

        dict_shoot_direction = {
            "N":
            np.flip(self.raw_map[:self.player_position[0],
                                 self.player_position[1]]),
            "W":
            np.flip(self.raw_map[
                self.player_position[0], :self.player_position[1]]),
            "S": [],
            "E": []
        }
        # Check bordi mappa
        if (self.player_position[0] == (len(self.raw_map[0]) - 1)):

            dict_shoot_direction["S"] = self.raw_map[self.player_position[0]:,
                                                     self.player_position[1]]

            if (self.player_position[1] != (len(self.raw_map[0]) - 1)):
                dict_shoot_direction["E"] = self.raw_map[
                    self.player_position[0], self.player_position[1] + 1:]
            else:
                dict_shoot_direction["E"] = self.raw_map[
                    self.player_position[0], self.player_position[1]:]
        else:
            dict_shoot_direction["S"] = self.raw_map[self.player_position[0] +
                                                     1:,
                                                     self.player_position[1]]

            if (self.player_position[1] == (len(self.raw_map[0]) - 1)):
                dict_shoot_direction["E"] = self.raw_map[
                    self.player_position[0], self.player_position[1]:]
            else:
                dict_shoot_direction["E"] = self.raw_map[
                    self.player_position[0], self.player_position[1] + 1:]

        self.last_shot = False
        for key in dict_shoot_direction:
            for elem in dict_shoot_direction[key]:
                if (self.is_unshottable(elem)):
                    break
                elif (self.is_enemy(elem)):

                    result = self.game_interface.interact("shoot",
                                                          direction=key)
                    self.already_shoot.append(elem)
                    self.last_shot = True

                    if (self.debug):
                        self.game_interface.command_chat("post",
                                                         text_chat="shooting")
                        print("***SHOOT***")
                        if (self.loyality):
                            print("IMPOSTOR-> ", self.game_symbol, " SHOOT ",
                                  elem)
                        print("Elem: ", elem)

                        print("RESULT: ", result)
                        if (result.lower().find("error") != -1):
                            print('Cannot Shoot')
                        else:
                            print("ARRAY SHOOTED")
                            print(self.already_shoot)
                            print("Vettore controllato: ")
                            print(key + ": " + str(dict_shoot_direction[key]))
                            print("***ENDSHOOT***")

                    break

        return self.last_shot

    def manage_end(self, result, start_match):
        print("--- %.2f seconds ---" % (time.time() - start_match))

        if (result == 1):
            print(
                "|||||||||||||||||||||||||||WIN|||||||||||||||||||||||||||||||||"
            )
            if (self.mode == "007"):
                file_object = open('sample.txt', 'a')
                file_object.write(self.visual.player.player_name + "\n")
                print("007 WIN " + self.visual.player.player_name)

            stat = self.game_interface.status("status")
            leave = self.game_interface.interact("leave", text="Win Game")
            if (self.debug):
                print(stat)
                print(leave)
            self.game_interface.finished = True
            return True

        if (result == 2):

            print(
                "|||||||||||||||||||||||||||ERROR|||||||||||||||||||||||||||||||"
            )
            leave = self.game_interface.command_chat("leave")
            if (self.debug):
                print(leave)
            return False

    def check_impostors(self, most_probable_impostor):
        if ("impostors" in self.manager_dict):
            current_most_pobable_impostor = max(
                self.manager_dict["impostors"],
                key=self.manager_dict["impostors"].get)

            if (current_most_pobable_impostor != most_probable_impostor):
                self.game_interface.deduction_game(
                    "accuse", current_most_pobable_impostor)
                most_pobable_impostor = current_most_pobable_impostor
                if (self.debug):
                    print("Find Impostor: ", most_pobable_impostor)
        return most_probable_impostor

    def wait_lobby(self):
        while (True):
            result = self.game_interface.status("status")
            if (self.debug):
                print(result)
            index = result.find("GA: name=" + self.game_interface.game_name +
                                " " + "state=")
            condition = result[index + 9 +
                               len(str(self.game_interface.game_name)) + 7]

            if (condition.lower() == "a"):
                # Prende il nome degli alleati
                self.manager_dict["allies"] = self.visual.get_allies_name(
                    result)
                break

    def is_enemy(self, elem):
        if (elem in ['@', '.', '~', '$', '!']):
            return False
        if (self.enemies == "upper" and elem.isupper()):
            return True
        elif (self.enemies == "lower" and elem.islower()):
            return True
        return False

    def is_unshottable(self, elem):
        if (elem in ['#', '&', 'X', 'x'] or elem in self.already_shoot):
            return True
        return False

    def play(self):
        ##### LOBBY #######################################################################

        self.wait_lobby()

        ####MATCH############################################################################
        start_match = time.time()
        most_probable_impostor = ""
        while (True):

            self.update()

            # GESTIONE ACCUSE
            most_probable_impostor = self.check_impostors(
                most_probable_impostor)

            # GESTIONE COOLDOWN
            if ((time.time() - start_match) < 45.0):
                print("waiting")
            while ((time.time() - start_match) < 45.0):
                # TODO
                pass

            # ATTACK AND MOVE
            if (not (self.attack())):
                result = self.move()
                if (result == 1 or result == 2):
                    return self.manage_end(result, start_match)
コード例 #15
0
ファイル: explore.py プロジェクト: DurandBastien/robotics2018
class Explore():
    def __init__(self, shrink_factor):
        self.points_of_interst = [(0, 0), (5, -11.5), (-8.65, -10.0), (8.0, 10.0), (-6.0, 12.0), (-2, -11), (1, 11)]
        self.start_time = None
        
        self.current_goal = None
        self.global_costmap_update = None
        self.global_costmap_update_width = None
        self.global_costmap_update_height = None
        
        self.shrink_factor = shrink_factor
        self.range_of_vision = 0.6
        
        self.current_odometry = None
        self.map_set = False
        self.msg = ""
        
        #used to see which cells have been explored
        # 0=obstacle,outOfBounds 1=unexplored, 2=explored
        self.exploration_map = None
        self.grid = None
        self.finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
        self.img = None
        self.previous_b_x = None
        self.previous_b_y = None
        self.previous_a_y = None
        self.previous_a_x = None
        
        #used for pathfinding and reseting exploration map
        #0=obstacle 1=free
        self.default_map = None

        #local costmap
        self.local_costmap = None
        self.local_costmap_origin = None
        self.local_costmap_width = None
        self.local_costmap_height = None
        self.local_costmap_setup = False

        self.global_costmap = None        

        rospy.loginfo("Waiting for a map...")
        try:
            occ_map = rospy.wait_for_message("/map", OccupancyGrid, 20)
        except:
            rospy.logerr("Problem getting a map. Check that you have a map_server"
                     " running: rosrun map_server map_server <mapname> " )
            sys.exit(1)
        rospy.loginfo("Map received. %d X %d, %f px/m." % (occ_map.info.width, occ_map.info.height,
                       occ_map.info.resolution))
        
        self.map_width = occ_map.info.width
        self.map_height = occ_map.info.height
        self.map_resolution = occ_map.info.resolution
        self.map_data = occ_map.data
        self.map_real_origin_x = occ_map.info.origin.position.x
        self.map_real_origin_y = occ_map.info.origin.position.y
        self.map_origin_x = ( occ_map.info.origin.position.x +
                         (self.map_width / 2.0) * self.map_resolution*self.shrink_factor )
        self.map_origin_y = ( occ_map.info.origin.position.y +
                         (self.map_height / 2.0) * self.map_resolution*self.shrink_factor )

        self.set_map_and_reduce()
        
        self._odometry_sub = rospy.Subscriber("/odom", Odometry, self._odometry_callback, queue_size=1)
        
        self._exploring_sub = rospy.Subscriber("/exploring", String, self._exploring_callback, queue_size=1)

        self._pose_subscriber = rospy.Subscriber("/amcl_pose", PoseWithCovarianceStamped,
		                                          self._pose_callback,
		                                          queue_size=1)

        self._local_costmap_subscriber = rospy.Subscriber("/move_base/local_costmap/costmap", OccupancyGrid, self._local_costmap_callback, queue_size=1)

        self._local_costmap_update_subscriber = rospy.Subscriber("/move_base/local_costmap/costmap_updates", OccupancyGridUpdate, self._local_costmap_update_callback, queue_size=1)

        self._global_costmap_subscriber = rospy.Subscriber("/move_base/global_costmap/costmap", OccupancyGrid, self._global_costmap_callback , queue_size=1)

        self._global_costmap_update_subscriber = rospy.Subscriber("/move_base/global_costmap/costmap_updates", OccupancyGridUpdate, self._global_costmap_update_callback , queue_size=1)
        

        
        self.goal_publisher = rospy.Publisher("/where_to_go", PoseWithCovarianceStamped ,queue_size=1)

        


    def _local_costmap_callback(self, costmap):
        self.local_costmap = costmap.data
        self.local_costmap_origin_position = self.translate_coord(costmap.info.origin.position.x, costmap.info.origin.position.y)
        self.local_costmap_width = costmap.info.width
        self.local_costmap_height = costmap.info.height
        self.local_costmap_setup = True

    def _local_costmap_update_callback(self, costmap):
        #rospy.loginfo("local_costmap_update_callback")
        self.local_costmap = costmap.data

        #rospy.loginfo("lcmu, x, y: {}".format((costmap.x, costmap.y)))
        #rospy.loginfo("Lcmu, height, width: {}".format((costmap.height, costmap.width)))

    def _global_costmap_callback(self, costmap):
        self.global_costmap= list(costmap.data)

    def _global_costmap_update_callback(self, costmap):
        self.global_costmap_update = costmap.data
        self.global_costmap_update_height = costmap.height
        self.global_costmap_update_width = costmap.width

        for i in range(len(costmap.data)):
            y = i/costmap.width + costmap.y
            x= i%costmap.width + costmap.x
            #print("type of gcm: {}, type of gcmu: {}".format(len(self.global_costmap), len(costmap.data)))
            self.global_costmap[y*self.map_width + x] = costmap.data[i]
            
        
        
        #rospy.loginfo("gcmu, x, y: {}".format((costmap.x, costmap.y)))
        #rospy.loginfo("gcmu, height, width: {}".format((costmap.height, costmap.width)))
    
        
    def _exploring_callback(self, msg):
        self.msg = msg.data

    def _pose_callback(self, odometry):
        self.current_odometry = odometry
        if self.map_set:
            self.update_exploration_map([], self.current_odometry.pose.pose)
        
        
    def _odometry_callback(self, odo):
        if self.map_set and self.current_odometry is not None and self.msg == "explore":
            if self.start_time is None:
                print("started time")
                self.start_time = time.time()
            copy_odo = deepcopy(self.current_odometry)
            
            #goal_pose = self.calc_next_goal(copy_odo.pose.pose)
            goal_pose = self.simple_calc_next_goal(copy_odo.pose.pose)
            self.current_goal = (goal_pose[0]*3, goal_pose[1]*3)
            rospy.loginfo("current_goal: {}".format(self.current_goal))

            rospy.loginfo("current_array_pose: {}, goal_array_pose: {}".format(self.translate_coord(copy_odo.pose.pose.position.x, copy_odo.pose.pose.position.y), goal_pose))
            
            goal_pose = self.translate_coord_back(goal_pose[0], goal_pose[1])
            rospy.loginfo("current_real_pose: {}, goal_real_pose: {}".format((round(copy_odo.pose.pose.position.x, 3), round(copy_odo.pose.pose.position.y, 3)), (round(goal_pose[0], 3), round(goal_pose[1], 3))))
            
            new_odo = copy_odo
            new_odo.pose.pose.position.x = goal_pose[0]
            new_odo.pose.pose.position.y = goal_pose[1]
            
            self.goal_publisher.publish(new_odo)
        rospy.sleep(3)


        
    def restart_exploration(self):
        self.exploration_map = self.default_map
        self.img = Image.fromarray(self.exploration_map.T, 'L')
        self.map_set = True
        rospy.loginfo("setup finished")

        
        
    def set_map(self):
        self.map_set = false
        self.default_map = np.zeros((self.map_height, self.map_width), dtype = np.uint8)
        
        for i in range(self.map_height):
            for j in range(self.map_width):
                cell = self.map_data[i*self.map_width + j]

                if cell < 0.196 and cell >= 0:
                    #not explored
                    self.default_map[i][j] = 1

        self.grid = Grid(matrix = self.default_map)
        self.restart_exploration()

        
        
    def set_map_and_reduce(self):
        #reduce the resolution as well
        self.map_set = False        
        self.default_map = np.zeros((self.map_height/self.shrink_factor,
                                self.map_width/self.shrink_factor),
                               dtype = np.uint8)
        
        for i in range(0, len(self.default_map)):
            for j in range(0, len(self.default_map[0])):
                sum = 0
                for k in range(i*self.shrink_factor, i*self.shrink_factor+self.shrink_factor):
                    for l in range(j*self.shrink_factor, j*self.shrink_factor + self.shrink_factor):
                        cell = self.map_data[k*self.map_width + l]
                        if cell < 0.196 and cell >= 0:
                            sum = sum + 1
                        
                if sum == math.pow(self.shrink_factor,2):
                    self.default_map[i, j] = 1


        self.inflate_obstacles()
        self.grid = Grid(matrix = self.default_map)
        self.restart_exploration()
        



    def inflate_obstacles(self):
        temp_img = Image.fromarray(self.default_map.T, 'L')
        dis= 4
        
        
        for i in range(len(self.default_map)):
            for j in range(len(self.default_map[0])):
                if self.default_map[i][j] == 0:
                    #if i > dis and j > dis and i < len(self.default_map)-dis and j < len(self.default_map) - dis:
                    ImageDraw.Draw(temp_img).ellipse([(i-dis, j-dis), (i+dis, j+dis)],fill=0, outline=0)
                    

        self.default_map = np.array(temp_img).T
        #return temp_img

        

    def update_exploration_map(self, scan_data, pose):
        # does not use  the scan_data
        # assume that camera is not abstructed
        # can be improved by taking the scan_data

        angle_of_vision = (math.pi*3)/5
        robot_orientation = self.getHeading(pose.orientation)
        robot_position = pose.position

        """
        a       b
        --------
        \      /
         \    /
          \  /
           \/
            c
        
        c = the position of robot
        triangle = what the robot can see with the camera
        """
        
        if robot_orientation - angle_of_vision/2 < -math.pi:
            b_angle = math.pi + (math.pi + (robot_orientation - angle_of_vision/2))
        else:
            b_angle = robot_orientation - angle_of_vision/2
        
        b_x = self.range_of_vision*math.cos(b_angle) + robot_position.x
        b_y = self.range_of_vision*math.sin(b_angle) + robot_position.y

        
        if robot_orientation + angle_of_vision/2 > math.pi:
            a_angle =  -(math.pi - ((robot_orientation + angle_of_vision/2) - math.pi))
        else:
            a_angle = robot_orientation + angle_of_vision/2
        
        a_x = self.range_of_vision*math.cos(a_angle) + robot_position.x
        a_y = self.range_of_vision*math.sin(a_angle) + robot_position.y
        
        #transform the cords to array space
        b_x, b_y = self.translate_coord(b_x, b_y)
        a_x, a_y = self.translate_coord(a_x, a_y)
        c_x, c_y = self.translate_coord(robot_position.x, robot_position.y)

        #set cells to 2 (explored)
        if self.previous_b_x is None:
            ImageDraw.Draw(self.img).polygon([(a_y, a_x), (b_y, b_x), (c_y, c_x)], outline=2, fill=2)
        else:
            ImageDraw.Draw(self.img).polygon([(a_y, a_x), (b_y, b_x), (c_y, c_x)], outline=2, fill=2)
            ImageDraw.Draw(self.img).polygon([(a_y, a_x), (b_y, b_x), (self.previous_b_y, self.previous_b_x), (self.previous_a_y, self.previous_a_x)], outline=2, fill=2)
            ImageDraw.Draw(self.img).polygon([(self.previous_a_y, self.previous_a_x), (a_y, a_x), (self.previous_b_y, self.previous_b_x), (b_y, b_x)], outline=2, fill=2)
            
        self.previous_b_x = b_x
        self.previous_b_y = b_y
        self.previous_a_y = a_y
        self.previous_a_x = a_x
        
        
                 
        
    def calc_next_goal(self, pose):
        #where the search will start (the location of robot/pose)
        x, y = self.translate_coord(pose.position.x, pose.position.y)

        self.exploration_map = np.array(self.img).T
        
        level = 0

        inside_the_wall = False
        go_to = 1 #go to unexplored point
        if self.default_map[y][x] == 0:
            rospy.loginfo("calc_next_goal: inside the wall")
            inside_the_wall = True
            go_to = 2 #go to explored point

        while True:
            x_start = np.max([x - level, 0])
            x_end = np.min([x + level, self.map_width/self.shrink_factor - 1])
            y_start = np.max([y - level, 0])
            y_end = np.min([y + level, self.map_height/self.shrink_factor - 1])

            #for each: if not explored and can be reached
            i = y_start
            j = x_start
            while j < x_end:
                if j < self.map_width/self.shrink_factor and self.exploration_map[i][j] == 1:
                    if (inside_the_wall or self.is_reachable(x, y, j, i)) and self.far_enough(x, y, j, i) and not self.blocked_in_local_costmap(j, i) and not self.blocked_in_global_costmap(j,i):
                        return (j, i)
                    else:
                        self.exploration_map[i][j] = 0
                j = j + 1

            i = y_end
            j = x_start
            while i < y_end:
                if i < self.map_height/self.shrink_factor and self.exploration_map[i][j] == 1:
                    if (inside_the_wall or self.is_reachable(x, y, j, i)) and self.far_enough(x, y, j, i) and not self.blocked_in_local_costmap(j, i) and not self.blocked_in_global_costmap(j,i):
                        return (j, i)
                    else:
                        self.exploration_map[i][j] = 0
                i = i + 1        

            i = y_end
            j = x_end
            while j > x_start:
                if j >= 0 and self.exploration_map[i][j] == 1:
                    if (inside_the_wall or self.is_reachable(x, y, j, i)) and self.far_enough(x, y, j, i) and not self.blocked_in_local_costmap(j, i) and not self.blocked_in_global_costmap(j,i):
                        return (j, i)
                    else:
                        self.exploration_map[i][j] = 0
                j = j - 1

            i = y_start
            j = x_end
            while i > y_start:
                if i >= 0 and self.exploration_map[i][j] == 1:
                    if (inside_the_wall or self.is_reachable(x, y, j, i)) and self.far_enough(x, y, j, i) and not self.blocked_in_local_costmap(j, i) and not self.blocked_in_global_costmap(j,i):
                        return (j, i)
                    else:
                        self.exploration_map[i][j] = 0
                i = i - 1

            level = level +1

            #worst case
            if level > self.map_width and level > self.map_height:
                rospy.logwarn("Goal not found, restarting on level: {}".format(level))
                self.restart_exploration()
                level = 0
  


    def simple_calc_next_goal(self, pose):
        self.exploration_map = np.array(self.img).T
        if len(self.points_of_interst) == 0:
            return (0, 0)

        shortest= []
        i = 0
        x, y = self.translate_coord(pose.position.x, pose.position.y)
        rospy.loginfo("simple_calc, x,y: {}".format((x,y)))
        while len(self.points_of_interst) > i:
            
            p1 = self.points_of_interst[i]
            x2, y2 = self.translate_coord(p1[0], p1[1])
            dis = self.calc_dis(x, y, x2, y2)
            if dis < 1:
                del self.points_of_interst[i]
            else:
                shortest.append((dis, (x2, y2)))
            i+=1
            
        shortest.sort()
        return shortest[0][1]
            
    def translate_coord(self, x, y):
        x = int((x - self.map_origin_x)/(self.map_resolution*self.shrink_factor) + 0.5
                + self.map_width/2.0)
        y = int((y - self.map_origin_y)/(self.map_resolution*self.shrink_factor) + 0.5
                + self.map_height/2.0)
	
        return (x, y)


    
    def translate_coord_back(self, x, y):
        real_x = (x - self.map_width/2.0)*self.map_resolution*self.shrink_factor + self.map_origin_x
        real_y = (y - self.map_height/2.0)*self.map_resolution*self.shrink_factor + self.map_origin_y
        return (real_x, real_y)

    def is_reachable(self, x, y, x2, y2):
        self.grid.cleanup()
        start = self.grid.node(x, y)
        end = self.grid.node(x2, y2)

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

        return len(path) > 0


    
    def get_goal(self, x, y, x2, y2):
        min_dis = 0.25
        self.grid.cleanup()
        start = self.grid.node(x, y)
        end = self.grid.node(x2, y2)

        path, runs = self.finder.find_path(start, end, self.grid)
        if len(path) == 0:
            return None

        path = path
        point = None
        dis = 0
        while True:
            if len(path) ==0:
                break
            
            point = path[0]
            r_dis = math.sqrt(math.pow((x2 - point[0])*self.map_resolution*self.shrink_factor, 2) + math.pow((y2 - point[1])*self.map_resolution*self.shrink_factor, 2))

            if r_dis == 0:
                ang = 0
            elif r_dis <= self.range_of_vision and r_dis >= min_dis:
                ang = math.acos(((x2 - point[0])*self.map_resolution*self.shrink_factor)/r_dis)
                if x2 - point[0] <= 0:
                    ang = ang
                    if y2 - point[1] <= 0:
                        ang = ang - 3*math.pi/2
                    else:
                        ang = -(ang-math.pi/2)
                else:
                    if y2 - point[1] <= 0:
                        ang = ang + math.copysign(1, x2 - point[0])*math.pi/2
                    else:
                        ang = ang
                break
            elif r_dis >= min_dis:
                path = path[(len(path) - 1):]
            else:
                point = path[0]
                #ang = 

        return (point[0], point[1], ang)


    
    def far_enough(self, x, y, x2, y2):
        r_dis = math.sqrt(math.pow((x2 - x)*self.map_resolution*self.shrink_factor, 2) + math.pow((y2 - y)*self.map_resolution*self.shrink_factor, 2))

        return r_dis >= 0.5

    def calc_dis(self, x, y, x2, y2):
        r_dis = math.sqrt(math.pow((x2 - x)*self.map_resolution*self.shrink_factor, 2) + math.pow((y2 - y)*self.map_resolution*self.shrink_factor, 2))
        return r_dis


    
    def blocked_in_local_costmap(self, x, y):
        rospy.loginfo("local costmap initiated: {}".format(self.local_costmap is not None))
        if not self.local_costmap_setup:
            return False

        rospy.loginfo("costmap, origin: {}, height/width: {}".format((self.local_costmap_origin_position[0], self.local_costmap_origin_position[1]), (self.local_costmap_height, self.local_costmap_width)))
        
        local_x = (x - self.local_costmap_origin_position[0])*self.shrink_factor
        local_y = (y - self.local_costmap_origin_position[1])*self.shrink_factor

        rospy.loginfo("costmap, x: {}, y: {}".format(local_x, local_y, ))

        if local_x >= 0 and local_x < self.local_costmap_width and local_y >= 0 and local_y < self.local_costmap_height:
            if self.local_costmap[local_y*self.local_costmap_width + local_x] == 0:
                return False
            else:
                return True
        else:
            return False


    def blocked_in_global_costmap(self, x, y):
        rospy.loginfo("global costmap initiated: {}".format(self.global_costmap is not None))
        if self.global_costmap == None:
            return False
        
        if self.global_costmap[y*self.shrink_factor*self.map_width + x*self.shrink_factor] == 0:
            return False
        else:
            rospy.loginfo("Blocked in global costmap: True")
            return True
        
        


    def getHeading(self, q):
        """
        from pf_localisation.util.py
        Get the robot heading in radians from a Quaternion representation.
    
        :Args:
            | q (geometry_msgs.msg.Quaternion): a orientation about the z-axis
        :Return:
            | (double): Equivalent orientation about the z-axis in radians
        """
        yaw = math.atan2(2 * (q.x * q.y + q.w * q.z),
                     q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z)
        return yaw
コード例 #16
0
class Enemy(pygame.sprite.Sprite):
    # Define the constructor for invader
    def __init__(self, color, width, height, x_ref, y_ref):
        # Call the sprite constructor
        super().__init__()
        
        # pathfinding map generation        
        matrix = [[0 for y in range(maxsizey)] for x in range(maxsizex)] 

        # Create walls on the screen (each tile is 20 x 20 so alter cords)
        self.hack = pygame.Surface([maxsizex * 20, maxsizey * 20], pygame.SRCALPHA)
        for y in range(maxsizey):
            for x in range (maxsizex):
                if map[x][y] == " ":
                    #matrix[x][y] = 1
                    #stlightly randomises map to make enemies move interestingly
                    randint = random.randint(1,50)
                    matrix[x][y] = randint     
                elif map[x][y] == "#" or map[x][y] == "":
                    matrix[x][y] = 0
                elif map[x][y] == "|":
                    matrix[x][y] = 0            
                elif map[x][y] == "_":
                    matrix[x][y] = 0
                elif map[x][y] == "o":
                    matrix[x][y] = 1
                elif map[x][y] == "e": 
                    matrix[x][y] = 1
        self.grid = Grid(matrix=matrix)
        # Create a sprite and fill it with colour
        self.image = pygame.Surface([width,height])
        #self.image.fill(color)
        self.rect = self.image.get_rect()
        pygame.draw.circle(self.image, color, (width//2, height//2), width//2)
        # Set the position of the player attributes
        self.rect.x = x_ref
        self.rect.y = y_ref
        self.speedx = 0
        self.speedy = 0
        self.width = width
        self.height = height
        self.targetx = self.rect.x + self.width // 2
        self.targety = self.rect.y + self.height // 2
    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