Exemplo n.º 1
0
def test_astar_single():
    astar = tcod.path_new_using_map(maps[0])
    for _ in range(PATH_NUMBER):
        tcod.path_compute(astar, 0, 0, MAP_WIDTH - 1 , MAP_HEIGHT - 1)
        x, y = tcod.path_walk(astar, False)
        while x is not None:
            x, y = tcod.path_walk(astar, False)
Exemplo n.º 2
0
def test_astar_single():
    astar = tcod.path_new_using_map(maps[0])
    for _ in range(PATH_NUMBER):
        tcod.path_compute(astar, 0, 0, MAP_WIDTH - 1, MAP_HEIGHT - 1)
        x, y = tcod.path_walk(astar, False)
        while x is not None:
            x, y = tcod.path_walk(astar, False)
Exemplo n.º 3
0
 def run(self):
     while 1:
         job, obj = jobs.get()
         if job == 'fov':
             tcod.map_compute_fov(obj, MAP_WIDTH // 2, MAP_HEIGHT // 2)
         elif job == 'astar':
             tcod.path_compute(self.astar, 0, 0, MAP_WIDTH - 1,
                               MAP_HEIGHT - 1)
             x, y = tcod.path_walk(self.astar, False)
             while x is not None:
                 x, y = tcod.path_walk(self.astar, False)
         jobs.task_done()
Exemplo n.º 4
0
 def run(self):
     while 1:
         job, obj = jobs.get()
         if job == 'fov':
             tcod.map_compute_fov(obj, MAP_WIDTH // 2, MAP_HEIGHT // 2)
         elif job == 'astar':
             tcod.path_compute(self.astar,
                               0, 0, MAP_WIDTH - 1 , MAP_HEIGHT - 1)
             x, y = tcod.path_walk(self.astar, False)
             while x is not None:
                 x, y = tcod.path_walk(self.astar, False)
         jobs.task_done()
Exemplo n.º 5
0
 def move_to_coordinates_step(x, y, dest_x, dest_y, map):
     fov_map = map.fov_map
     path = tcod.path_new_using_map(fov_map, 1)
     tcod.path_compute(path, x, y, dest_x, dest_y)
     x, y = tcod.path_walk(path, True)
     tcod.path_delete(path)
     return x, y
Exemplo n.º 6
0
    def move_astar(self, target, entities, game_map):
        #Create an FOV map with the dimensions of the map
        fov = tcod.map_new(game_map.width, game_map.height)

        #Scan the map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                tcod.map_set_properties(fov, x1, y1,
                                        not game_map.tiles[x1][y1].block_sight,
                                        not game_map.tiles[x1][y1].blocked)

        #Scan all objects to see if there are objects that must be navigated around (generally enemies)
        #Checks if each object isn't self or target (so the start and end points are not marked as unwalkable)
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                tcod.map_set_properties(fov, entity.x, entity.y, True, False)

        #Allocate the A* path
        #1.41 is the rough cost of diagonal movement (sqrt 2)
        my_path = tcod.path_new_using_map(fov, 1.41)

        #
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            x, y = tcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)

        tcod.path_delete(my_path)
Exemplo n.º 7
0
	def move_astar(self, target, entities, game_map):
		inframap = tcod.map.Map(constants.MAP_WIDTH * constants.WORLD_WIDTH, constants.MAP_HEIGHT * constants.WORLD_HEIGHT, "F") # map used in above map
		inframap.walkable[:] = True
		inframap.transparent[:] = False

		for entity in entities:
			if entity.blocks and entity != self and entity != target:

				inframap.transparent[entity.x, entity.y] = True
				inframap.walkable[entity.x, entity.y] = False

		monster_path = tcod.path.AStar(inframap, diagonal=1.41)

		tcod.path_compute(monster_path, self.x, self.y, target.x, target.y)

		# print(f"PLAYER WORLD: {target.x, target.y}")
		# print(f"MON WORLD: {self.x, self.y}")

		if not tcod.path_is_empty(monster_path) and tcod.path_size(monster_path) < 25:
			x, y = tcod.path_walk(monster_path, True)

			if x or y:
				self.x = x
				self.y = y

		else:
			self.move_towards(target.x, target.y, game_map, entities)
Exemplo n.º 8
0
    def move_astar(self, target, game_map):
        """
        """

        logger.debug(f"{self.name} A* Observe")

        fov = tcod.map_new(game_map.w, game_map.h)

        for tile in game_map:
            tcod.map_set_properties(fov, tile.x, tile.y, not tile.opaque,
                                    not tile.blocked)

        for entity in game_map.entities:
            if entity == self:
                continue
            if entity.kind != Entities.ITEM:
                tcod.map_set_properties(fov, entity.x, entity.y, True, False)

        my_path = tcod.path_new_using_map(fov, 1.41)

        logger.debug(f"{self.name} A* Orient")
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        logger.debug(f"{self.name} A* Decide")
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            logger.debug("{self.name} A* Act 0")
            self.position = tcod.path_walk(my_path, True)
        else:
            logger.debug(f"{self.name} A* Act 1")
            self.move_towards(target.x, target.y, game_map)

        tcod.path_delete(my_path)
Exemplo n.º 9
0
    def move_astar(self, target):
        fov = tcod.map_new(MAP_WIDTH, MAP_HEIGHT)

        for y1 in range(MAP_HEIGHT):
            for x1 in range(MAP_WIDTH):
                tcod.map_set_properties(fov, x1, y1,
                                        not map[x1][y1].block_sight,
                                        not map[x1][y1].blocked)

        for obj in objects:
            if obj.blocks and obj != self and obj != target:
                tcod.map_set_properties(fov, obj.x, obj.y, True, False)

        path = tcod.path_new_using_map(fov,
                                       0)  # 0: 대각선 금지, 1.41: 대각선 코스트(루트 2)

        tcod.path_compute(path, self.x, self.y, target.x, target.y)

        if not tcod.path_is_empty(path) and tcod.path_size(path) < 25:
            x, y = tcod.path_walk(path, True)
            if x or y:
                self.x = x
                self.y = y
                self.wait = self.speed
        else:
            self.move_towards(target.x, target.y)

        tcod.path_delete(path)
Exemplo n.º 10
0
    def move_astar(self, target, entities, game_map):
        # mapの寸法を持つfovマップを作製する
        fov = libtcod.map_new(game_map.width, game_map.height)

        # 現在の地図を毎回スキャンし、全ての壁を歩けないように設定する
        for y1, x1 in itertools.product(range(game_map.height),
                                        range(game_map.width)):
            libtcod.map_set_properties(fov, x1, y1,
                                       not game_map.tiles[x1][y1].block_sight,
                                       not game_map.tiles[x1][y1].blocked)

        # 全てのオブジェクトをスキャンして移動させるオブジェクトを確認する
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        my_path = libtcod.path_new_using_map(fov, 1.41)

        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)

        libtcod.path_delete(my_path)
Exemplo n.º 11
0
    def move_astar(self, target, entities, game_map):
        # Create FOV map with dimensions of game map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Set walls as blocked
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                                            not game_map.tiles[x1][y1].blocked)

        # Check for entities that are blocked and need to be navigated around
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True, False)

        # Allocate an A* path
        my_path = libtcod.path_new_using_map(fov, 1.41)

        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)

        libtcod.path_delete(my_path)
Exemplo n.º 12
0
    def move_astar(self, target, entities, game_map):
        fov = libtcod.map.Map(game_map.width, game_map.height)

        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                fov.transparent[y1,
                                x1] = not game_map.tiles[x1][y1].block_sight
                fov.walkable[y1, x1] = not game_map.tiles[x1][y1].blocked

        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                fov.transparent[entity.y, entity.x] = True
                fov.walkable[entity.y, entity.x] = False

        my_path = libtcod.path_new_using_map(fov, 1.41)

        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)
Exemplo n.º 13
0
    def move_astar(self, entity, viewshed, position_component, player_x,
                   player_y):  # target, entities, game_map):
        # /!\ On utilise visible_tiles, qui concerne ce que le mob voit = le transparent est consideré comme walkable.
        # /!\ Libtcod fonctionne en y,x et pas en x, y. Melange facile à faire, a ameliorer!
        # /!\ Pas de second check sur le deplacement, on teleporte le mob. Danger si walkable.
        # Create a FOV map that has the dimensions of the map
        fov = viewshed.visible_tiles
        current_map = World.fetch('current_map')

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = tcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        tcod.path_compute(my_path, position_component.y, position_component.x,
                          player_y, player_x)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths
        # (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map
        # if there's an alternative path really far away
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            y, x = tcod.path_walk(my_path, True)  # tcod : [y][x]
            if x or y:
                tcod.path_delete(my_path)
                return x, y
                # Set self's coordinates to the next path tile
        tcod.path_delete(my_path)
        return False
Exemplo n.º 14
0
    def move_astar(self, target_x, target_y, entities, nav_map):
        for entity in entities:
            if entity.blocks and entity != self and entity.x != target_x and entity.y != target_y:
                libtcod.map_set_properties(nav_map, entity.x, entity.y, True,
                                           False)

        my_path = libtcod.path_new_using_map(nav_map, 1.41)
        libtcod.path_compute(my_path, self.x, self.y, target_x, target_y)

        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                if abs(x) == abs(y) and self.energy >= 141:
                    self.x = x
                    self.y = y
                    self.energy = 0

                elif self.energy >= 100:
                    self.x = x
                    self.y = y
                    self.energy = 0
        else:
            self.move_towards(target_x, target_y, nav_map, entities)

            # Delete the path to free memory
        libtcod.path_delete(my_path)
Exemplo n.º 15
0
    def move_astar(self, target, entities, game_map):
        fov = libtcod.map_new(game_map.width, game_map.height)

        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                                           not game_map.tiles[x1][y1].blocked)

        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                libtcod.map_set_properties(fov, entity.x, entity.y, True, False)

        my_path = libtcod.path_new_using_map(fov, 1.41)

        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)

        libtcod.path_delete(my_path)
Exemplo n.º 16
0
    def move_astar(self, alvo, entidades, mapa):

        fov = libtcod.map_new(mapa.largura, mapa.altura)


        for y1 in range(mapa.altura):
            for x1 in range(mapa.largura):
                libtcod.map_set_properties(fov, x1, y1, not mapa.tiles[x1][y1].bloqueio_visao,
                                           not mapa.tiles[x1][y1].bloqueado)

        for entidade in entidades:
            if entidade.bloqueia and entidade != self and entidade != alvo:
                libtcod.map_set_properties(fov, entidade.x, entidade.y, True, False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = libtcod.path_new_using_map(fov, 1.41)
        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, self.x, self.y, alvo.x, alvo.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map if there's an alternative path really far away
        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            self.mover_para(alvo.x, alvo.y, mapa, entidades)

        # Delete
        libtcod.path_delete(my_path)
Exemplo n.º 17
0
Arquivo: main.py Projeto: Jipes/TYRMA
    def take_turn(self):
        monster = self.owner
        try:
            if self.path==None:
                self.path = libtcod.path_new_using_map(copy.deepcopy(path_map))
        except:
            self.path = libtcod.path_new_using_map(copy.deepcopy(path_map))

        try:
            if self.target_x is None or self.target_y is None:
                self.randomize_target()
        except:
            self.randomize_target()

        stepx,stepy=0,0
        moved=False
        if monster.distance_to(Point(self.target_x,self.target_y)) >= 2 and self.success:
            stepx,stepy=libtcod.path_walk(self.path,False)
            moved=monster.move(stepx-monster.x,stepy-monster.y)

        if not moved:
            if stepx!=0 and stepy!=0:
                blocking=get_object(stepx,stepy)
                if blocking is not None and hasattr(blocking,"fighter") and blocking.fighter is not None:
                    self.recalculate()
                    if blocking.fighter.hp > 0 and monster.distance_to(blocking) < 2:
                        monster.fighter.attack(blocking)
                else:
                    self.randomize_target()
            else:
                self.randomize_target()
Exemplo n.º 18
0
    def move_astar(self, target, entities, game_map):
        fov = tcod.map_new(game_map.width, game_map.height)
        # Walls are impassable of course
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                tcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].block_movement)
        for entity in entities:
            if entity.block_movement and entity != self and entity != target:
                # Treat allies as transparent but impassable
                tcod.map_set_properties(fov, entity.x, entity.y, True, False)
        # The 1 is diagonal cost, normally would be 1.41, but
        my_path = tcod.path_new_using_map(fov, 1)
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Low path size so that monsters won't run off in some random lil corridor
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 20:
            x, y = tcod.path_walk(my_path,
                                  True)  # True means to recompute path
            if x or y:  # wtf
                self.x = x
                self.y = y
        else:  # Backup option if not movable (corridor stuck)
            self.move_towards(target.x, target.y, game_map, entities)
        # Freeing some ram
        tcod.path_delete(my_path)
Exemplo n.º 19
0
    def move_to(self, target, game_map, entities, tile_map, player):
        move_results = []

        path_map = tile_map

        add_entities_to_path_map(path_map, entities, self, player)

        tcod.map_set_properties(path_map, self.x, self.y, True, True)

        # Allocate a A* path
        my_path = tcod.path_new_using_map(path_map, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = tcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            self.move_towards(target.x, target.y, game_map, entities)

        tcod.map_set_properties(path_map, self.x, self.y, True, False)

        tcod.path_delete(my_path)

        # Interact with landed on tile
        move_results.extend(
            game_map.tiles[self.x][self.y].overlap_entity(self))

        return move_results
Exemplo n.º 20
0
    def move_astar(self, target, game_map, mobs):
        if not self.stats or time.time(
        ) - self.stats.mv_time < self.stats.mv_wait:
            return

        self.stats.mv_time = time.time()

        fov = tc.map_new(game_map.wd, game_map.ht)
        for x in range(0, game_map.wd):
            for y in range(0, game_map.ht):
                tc.map_set_properties(fov, x, y,
                                      not game_map.cells[x][y].is_discovered,
                                      not game_map.cells[x][y].is_blocked)

        for mob in mobs:
            if mob != self and mob != target:
                tc.map_set_properties(fov, mob.x, mob.y, True, False)

        path = tc.path_new_using_map(fov, 0)
        tc.path_compute(path, self.x, self.y, target.x, target.y)
        if not tc.path_is_empty(path) and tc.path_size(path) < 30:
            x, y = tc.path_walk(path, True)
            if x or y:
                self.x = x
                self.y = y
            else:
                self.move_to_target(target.x, target.y, game_map, mobs)

            tc.path_delete(path)
Exemplo n.º 21
0
    def move_astar(self, target, entities, game_map):
        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                                           not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        
        # #  THIS IS THE PROBLEM!  We're not passing entities for movement, we're using Coords so the player blocks the target  
        for entity in entities:
            if entity.blocks and entity != self and not (entity.x == target.x and entity.y == target.y):
                # Set the tile as a wall so it must be navigated around
                libtcod.map_set_properties(fov, entity.x, entity.y, True, False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        if constants['AI_allow_diagonal']:
            diagonal_cost=1.41
        else:
            diagonal_cost=0.0
        
        my_path = libtcod.path_new_using_map(fov, diagonal_cost)

        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map if there's an alternative path really far away
        
        #Print path debugging info
        #print("Pathing from [" + str(self.x) + ", "+ str(self.y) + "] to ["+ str(target.x) +", "+ str(target.y) +"]")
        #print (my_path)
        #for i in  range(0, libtcod.path_size(my_path)):
        #    print (libtcod.path_get(my_path, i))
        
        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 200:
            # Find the next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)
            #print ("moving to [" +str(x)+ "," +str(y)+ "]") #DEBUG 
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            #print("using fallback pathing method")  #DEBUG 
            # Keep the old move function as a backup so that if there are no paths (for example another monster blocks a corridor)
            # it will still try to move towards the player (closer to the corridor opening)
            self.move_towards(target.x, target.y, game_map, entities)

            # Delete the path to free memory
        libtcod.path_delete(my_path)
Exemplo n.º 22
0
    def move_astar(self, target, entities, game_map):
        """Moves towards a target using the A* algorithm.

        TODO: Refactor this method to use new TCOD functions.
        TODO: Rewrite docstring to better document A* algorithm.
        TODO: Study and pick apart A* to understand how it works.

        Args:
            target(Entity): The Entity object to plot a path to.
            entities(list): A list of Entities.
            game_map(Map): The Map object used for displaying the game.
        """

        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                # libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight, not game_map.tiles[x1][y1].blocked)
                fov.transparent[y1, x1] = not game_map.tiles[x1][y1].block_sight
                fov.walkable[y1, x1] = not game_map.tiles[x1][y1].blocked

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                # libtcod.map_set_properties(fov, entity.x, entity.y, True, False)
                fov.transparent[entity.y, entity.x] = True
                fov.walkable[entity.y, entity.x] = False

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map if there's an alternative path really far away
        if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup so that if there are no paths (for example another monster blocks a corridor)
            # it will still try to move towards the player (closer to the corridor opening)
            self.move_towards(target.x, target.y, game_map, entities)

        # Delete the path to free memory
        libtcod.path_delete(my_path)
    def move_astar(self, target, game):

        game_map = game.map
        blocking_ents = game.walk_blocking_ents

        # Create a FOV map that has the dimensions of the map
        fov = tcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                tcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[(x1, y1)].block_sight,
                    not game_map.tiles[(x1, y1)].blocked)

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in blocking_ents:
            if entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                tcod.map_set_properties(fov, entity.x, entity.y, True, False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = tcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map if there's an alternative path really far away
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = tcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                logging.debug(f'{self} is A*-moving.')
                if target.pos == (
                        x, y
                ):  # At some edge-cases NPCs might attempt a* movement when they are adjacent to the target
                    self.f.attack_setup(target, game)
                else:
                    self.try_move(x, y, game, absolute=True)
                logging.debug(f'{self} finished A*-moving.')

        else:
            # Keep the old move function as a backup so that if there are no paths (for example another monster blocks a corridor)
            # it will still try to move towards the player (closer to the corridor opening)
            logging.debug(
                f'{self} could not find a* path. falling back to regular movement'
            )
            self.move_towards(target, game)
Exemplo n.º 24
0
    def move_astar(self, game_map, target):
        width, height = game_map.get_map_sizes()
        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(width, height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(height):
            for x1 in range(width):
                libtcod.map_set_properties(
                    fov,
                    x1,
                    y1,
                    not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked,
                )

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for entity in game_map.get_entities():
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths
        # (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map
        # if there's an alternative path really far away
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
                self.end_turn()
        else:
            # Keep the old move function as a backup so that if there are no paths
            # (for example another monster blocks a corridor)
            # it will still try to move towards the player (closer to the corridor opening)
            self.move_towards(target.x, target.y)

            # Delete the path to free memory
        libtcod.path_delete(my_path)
Exemplo n.º 25
0
    def move_astar(self, monster_path, _map, fov, objects, goal):
        x, y = libtcod.path_walk(monster_path, True)

        if x or y:
            # here will be time to move or attack, and it will return found and fighting

            self.move_to_target(_map, fov, objects, x, y)

            if utils.non_obj_distance_to(
                (goal[0], goal[1]), self.owner.x, self.owner.y) < 2:
                return 'reached'
Exemplo n.º 26
0
    def move_astar(self, target: 'Entity', entities: List['Entity'],
                   game_map: 'GameMap') -> None:
        # Create a FOV map that has the dimensions of the map
        fov = tcod.map.Map(game_map.width, game_map.height, order='F')

        # Scan the current map each turn and set all the walls as unwalkable
        for y in range(game_map.height):
            for x in range(game_map.width):
                fov.transparent[x, y] = not game_map.tiles[x][y].block_sight
                fov.walkable[x, y] = not game_map.tiles[x][y].blocked

        # Scan all the objects to see if there are objects that must be
        # navigated around
        # Check also that the object isn't self or the target (so that the
        # start and the end points are free)
        # The AI class handles the situation if self is next to the target so
        # it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                fov.walkable[entity.x, entity.y] = False

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0
        # if diagonal moves are prohibited
        my_path = tcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's
        # coordinates
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter
        # than 25 tiles
        # The path size matters if you want the monster to use alternative
        # longer paths (for example through other rooms) if for example the
        # player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters
        # from running around the map if there's an alternative path really far
        # away
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            next_x, next_y = tcod.path_walk(my_path, True)
            if next_x is not None and next_y is not None:
                # Set self's coordinates to the next path tile
                self.x = next_x
                self.y = next_y
        else:
            # Keep the old move function as a backup so that if there are no
            # paths (for example another monster blocks a corridor) it will
            # still try to move towards the player (closer to the corridor
            # opening)
            self.move_towards(target.x, target.y, game_map, entities)
Exemplo n.º 27
0
    def move_astar(self, target, entities, game_map):
        """
        Cette fonction permet aux monstres d'avoir des déplacements plus sophistiqués.
        Ils peuvent se déplacer en diagonal.

        """
        # Créer une carte FOV qui a les dimensions de la carte
        fov = libtcod.map_new(game_map.width, game_map.height)

        # On scanne la carte actuelle à chaque tour et on définit tous les murs comme inviolables
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        # On Scanne tous les objets pour voir s'il y a des objets qui doivent être parcourus
        # On Vérifie également que l'objet n'est pas lui-même ou la cible (pour que les points de départ et d'arrivée soient libres)
        # La classe AI gère la situation si le self est à côté de la cible, de sorte qu'elle n'utilisera pas cette fonction A * de toute façon
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allouer un chemin A *
        # Le 1,41 (racine carré de 2)  est le coût diagonal normal du déplacement, il peut être réglé sur 0,0 si les déplacements diagonaux sont interdits
        my_path = libtcod.path_new_using_map(fov, 1.41)

        # Calculer le chemin entre les coordonnées de self et les coordonnées de la cible
        libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Vérifiez si le chemin existe, et dans ce cas, si le chemin est également plus court que 25 tuiles
        # La taille du chemin est importante si vous voulez que le monstre utilise d'autres chemins plus longs (par exemple à travers d'autres pièces) si par exemple le joueur est dans un couloir
        # Il est logique de garder la taille du chemin relativement faible pour empêcher les monstres de courir sur la carte s'il y a un chemin alternatif très loin
        if not libtcod.path_is_empty(
                my_path) and libtcod.path_size(my_path) < 25:
            # Trouver les coordonnées suivantes dans le chemin complet calculé
            x, y = libtcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                # On attribue ces coordonnées à self
                self.x = x
                self.y = y
        else:
            # Conservez l'ancienne fonction de déplacement comme sauvegarde afin que s'il n'y a pas de chemin (par exemple, un autre monstre bloque un couloir)
            # il essaiera toujours de se déplacer vers le joueur (plus près de l'ouverture du couloir)
            self.move_towards(target.x, target.y, game_map, entities)

            # Supprimer le chemin pour libérer de la mémoire
        libtcod.path_delete(my_path)
Exemplo n.º 28
0
    def _astar_step(self, src: Vector, dst: Vector) -> Vector:
        # Create a FOV map that has the dimensions of the map
        game_map = self.world.get_resource(Map)
        fov = tcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                tcod.map_set_properties(
                    fov,
                    x1,
                    y1,
                    not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked,
                )

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation if self is next to the target so it will not use this A* function anyway
        for _, (position, _) in self.world.get_components(Position, Collider):
            if position.vector not in (src, dst):
                # Set the tile as a wall so it must be navigated around
                tcod.map_set_properties(fov, position.x, position.y, True, False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = tcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        tcod.path_compute(my_path, src.x, src.y, dst.x, dst.y)

        vector = None

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths (for example through other rooms) if for example the player is in a corridor
        # It makes sense to keep path size relatively low to keep the monsters from running around the map if there's an alternative path really far away
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = tcod.path_walk(my_path, True)
            if x is not None and y is not None:
                vector = (Vector(x, y) - src).norm()

        if vector is None:
            # Keep the old move function as a backup so that if there are no paths (for example another monster blocks a corridor)
            # it will still try to move towards the player (closer to the corridor opening)
            vector = (dst - src).norm()

        # Delete the path to free memory
        tcod.path_delete(my_path)
        return vector
Exemplo n.º 29
0
    def move_astar(self, target: "Entity", entities: List["Entity"],
                   game_map: GameMap):
        # Create a FOV map that has the dimensions of the map
        fov: tcod.map.Map = tcod.map.Map(width=game_map.width,
                                         height=game_map.height,
                                         order="F")

        # Scan the current map each turn and set all the walls as unwalkable
        for tile in game_map.tiles:
            fov.transparent[tile.x, tile.y] = not tile.blocks_sight
            fov.walkable[tile.x, tile.y] = not tile.blocked

        # Scan all the objects to see if there are objects that must be navigated around
        # Check also that the object isn't self or the target (so that the start and the end points are free)
        # The AI class handles the situation is self is next to the target so it will not use this A* function anyway
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a wall so it must be navigated around
                fov.transparent[entity.x, entity.y] = True
                fov.walkable[entity.x, entity.y] = False

        # Allocate an A* path
        # The 1.41 is the normal diagonal cost of moving, it can be set as 0.0 if diagonal moves are prohibited
        my_path = tcod.path_new_using_map(fov, 1.41)

        # Compute the path between self's coordinates and the target's coordinates
        tcod.path_compute(my_path, self.x, self.y, target.x, target.y)

        # Check if the path exists, and in this case, also the path is shorter than 25 tiles
        # The path size matters if you want the monster to use alternative longer paths (for
        # example through other rooms) if for example the player is in a corridor
        # It makes sense to keep the path size relatively low to keep monsters from running around
        # the map if there's an alternative path really far away
        if not tcod.path_is_empty(my_path) and tcod.path_size(my_path) < 25:
            # Find the next coordinates in the computed full path
            x, y = tcod.path_walk(my_path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup so that is there are no paths (for example
            # another monster blocks a corridor it will still try to move towards the player
            # (closer to the corridor opening)
            self.move_towards(target_position=target.position,
                              game_map=game_map,
                              entities=entities)

        # Delete the path to free memory
        tcod.path_delete(my_path)
Exemplo n.º 30
0
    def move_astar(self, target, entities, game_map):
        # A* search algorithm lets our monsters move diagonally, smartly

        # Create a FOV map that has the dimensions of the map
        fov = libtcod.map_new(game_map.width, game_map.height)

        # Scan the current map each turn and set all the walls as unwalkable
        for y1 in range(game_map.height):
            for x1 in range(game_map.width):
                libtcod.map_set_properties(
                    fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
                    not game_map.tiles[x1][y1].blocked)

        # Scan all the objects to see if there are objects that must be
        # navigated around. Check also that the object isn't self or the
        # target (so that the start/end points are free)
        # The AI class handles the situation if the self is next to the
        # target so it won't use this A* function anyway.
        for entity in entities:
            if entity.blocks and entity != self and entity != target:
                # Set the tile as a 'wall' so it must be navigated around
                libtcod.map_set_properties(fov, entity.x, entity.y, True,
                                           False)

        # Allocate a A* path
        # The 1.41 is the normal diagonal cost of moving
        # it can be set as 0.0 to disable diagonal moving
        path = libtcod.path_new_using_map(fov, 1.41)

        # Check if the path exists, and in this case, also the path is
        # shorter than 25 tiles. THe path size matters if you want the
        # monster to use alt longer paths (eg through other rooms) if eg
        # the player is in a corridor. It makes sense to keep path size
        # relatively low to keep monsters from running around the map if
        # there's an alternative path really far away
        if not libtcod.path_is_empty(path) and libtcod.path_size(path) < 25:
            # Find the next coordinates in the computer full path
            x, y = libtcod.path_walk(path, True)
            if x or y:
                # Set self's coordinates to the next path tile
                self.x = x
                self.y = y
        else:
            # Keep the old move function as a backup so that if there are
            # no paths (eg another monster blocks a corridor) it will still
            # try to move towards the player (closer to the corridor)
            self.move_towards(target.x, target.y, game_map, entities)

        # Delete the path to free memory
        libtcod.path_delete(path)
Exemplo n.º 31
0
 def ai(self):
     if not self.dead:
         super().ai()
         fov = compute_fov(self.map.transparent, (self.x, self.y), self.fov,
                           True, tcod.constants.FOV_BASIC)
         player = self.level.get_visible_player(fov)
         if player:
             path = tcod.path_new_using_map(self.map, 0)
             tcod.path_compute(path, self.x, self.y, player.x, player.y)
             if tcod.path_size(path) == 1:
                 self.attack(player)
             elif not tcod.path_is_empty(path):
                 px, py = tcod.path_walk(path, True)
                 self.move(px - self.x, py - self.y)
Exemplo n.º 32
0
    def ai_behavior(self):

        # alias
        target = self.ai_target

        combat_behavior = self.combat_behavior

        fov_map = self.game.floor_manager.get_current_floor().game_map.fov_map

        # Only trigger ai if in FOV
        if (fov_map.fov[self.y][self.x] == False):
            return

        # Dont do anything if no target
        if (target == None or self.combat_behavior.dead):
            return

        # Compute a new path with no diagonals
        path = tcod.path_new_using_map(fov_map, dcost=0)
        tcod.path_compute(path, self.x, self.y, target.x, target.y)

        # generate the next x and next y on the path recompute if necessary
        (next_x, next_y) = tcod.path_walk(path, recompute=True)

        # Only move if BUG FOUND
        if (next_x and next_y):
            # get the movement values
            dx = next_x - self.x
            dy = next_y - self.y
            print(dx)
            print(dy)

            # predicted position based off the path dx + dy
            predicted_pos_x = self.x + dx
            predicted_pos_y = self.y + dy

            # check if there are any gameobjects at the predicted
            gameobjects_at_next_position = find_gameobjects_at_point(
                self.game.floor_manager.get_current_floor(), predicted_pos_x,
                predicted_pos_y)

            # TODO ignore other monsters
            # dont move if a gameobject is at the next position
            if not (len(gameobjects_at_next_position) > 0):
                # if there are no gameobjects at the next position, go ahead and move
                self.move(dx, dy)

        # Check for adjacent attacks
        self.attack_adjacent(target)
Exemplo n.º 33
0
def test_astar(map_):
    astar = libtcodpy.path_new_using_map(map_)

    assert not  libtcodpy.path_compute(astar, *POINTS_AC)
    assert  libtcodpy.path_size(astar) == 0
    assert  libtcodpy.path_compute(astar, *POINTS_AB)
    assert  libtcodpy.path_get_origin(astar) == POINT_A
    assert  libtcodpy.path_get_destination(astar) == POINT_B
    libtcodpy.path_reverse(astar)
    assert libtcodpy.path_get_origin(astar) == POINT_B
    assert libtcodpy.path_get_destination(astar) == POINT_A

    assert libtcodpy.path_size(astar) != 0
    assert libtcodpy.path_size(astar) > 0
    assert not libtcodpy.path_is_empty(astar)

    for i in range(libtcodpy.path_size(astar)):
        x, y = libtcodpy.path_get(astar, i)

    while (x, y) != (None, None):
        x, y = libtcodpy.path_walk(astar, False)

    libtcodpy.path_delete(astar)