Пример #1
0
    def possibleMoves(self):
        """
        Return a list of the possible moves from the current location.
        """

        adjacent_coords = coordinates.adjacent_coords(self.coords)
        return [x for x in adjacent_coords if self.canMove(x)]
Пример #2
0
    def fighting(self):
        """
        Calculate the action of a monster who sees the player.
        """

        if self.currentLevel.player not in self.fov:
            if self.player_last_location is not None:
                # The player has escaped!  Find a likely square where he could have gone.
                adjacent_coords = coordinates.adjacent_coords(
                    self.player_last_location)
                legal_coords = [
                    i for i in adjacent_coords
                    if coordinates.legal(i, self.currentLevel.dimensions)
                ]
                passable_coords = [
                    i for i in legal_coords if self.currentLevel.isEmpty(i)
                ]
                out_of_vision_coords = \
                    [i for i in passable_coords if i not in self.fov]

                if len(out_of_vision_coords) > 0:
                    # There is a possible escape route!  Pursue!
                    self.direction = coordinates.subtract(
                        rng.choice(out_of_vision_coords),
                        self.player_last_location)
                    self.path = pf.find_shortest_path(
                        self.currentLevel, self.coords,
                        self.player_last_location, False)
                    if self.path == []:
                        # There is no route to the player's escape route.  Wait, but stay in
                        # state FIGHTING so as to take advantage of any route that opens up.
                        return action.Wait(self)
                    self.state = ais.TRAVELING
                    return self.traveling()
                else:
                    # There is no possible escape route; give up and rest.
                    self.state = ais.RESTING
                    return self.resting()

            else:
                assert False

        else:
            self.player_last_location = self.currentLevel.player.coords

            if self.AICode == "CLOSE":
                return self.closeToPlayer()

            elif self.AICode == "RANGEDAPPROACH":
                return self.rangedApproach()

            else:
                raise exc.InvalidDataWarning(
                    "The monster %s has an unknown AICode, %s" % (self.name,
                                                                  self.AICode))
                return action.Wait(self)

        assert False
Пример #3
0
    def immediately_accessible_squares(self, coords):
        """
        Returns a list of the squares walkable from the square at coords.

        This function does not take into account monsters present at the source
        or destination squares.
        """

        adjacent_coords = coordinates.adjacent_coords(coords)
        return [x for x in adjacent_coords if self.are_immediately_accessible(coords, x)]
Пример #4
0
    def statue(self):
        """
        The statue AI pattern is as follows:

        If a monster that meets certain conditions is in view, do
        a general haste.
        If no such monster is in view, teleport adjacent to a damaged monster.
        If no such monster exists, then teleport randomly.
        """

        for d in self.fov.dudes:
            if self.spec == "QUICKEN":
                if (not d.isPlayer()) and (d.AICode != "STATUE"):
                    return action.HasteAll(self, 8, False, False)
            else:
                assert False

# If the statue is stuck, it can't teleport, so it just stays.
        if self.hasCondition("STUCK"):
            return action.Wait(self)

# If the statue did not do anything to monsters in view, it must teleport.
        for m in self.currentLevel.dudeLayer:
            if m.cur_HP < m.max_HP and not m.isPlayer() and (m.AICode !=
                                                             "STATUE"):
                # Aha, a target!
                destination_candidates = coordinates.adjacent_coords(m.coords)
                destination_options = [
                    i for i in destination_candidates
                    if self.currentLevel.isEmpty(i)
                    and i not in self.currentLevel.dudeLayer
                ]
                if destination_options != []:
                    return action.Teleport(self,
                                           rng.choice(destination_options))


# If there are no monsters to which the statue can teleport, teleport randomly.
        for i in range(100):
            destination = rng.randomPointInRect(
                (0, 0), (self.currentLevel.dimensions[0] - 1,
                         self.currentLevel.dimensions[1] - 1))
            if self.currentLevel.isEmpty(destination) and \
                destination not in self.currentLevel.dudeLayer:

                return action.Teleport(self, destination)

        return action.Wait(self)
Пример #5
0
    def recalculate(self, level_, initial_location):
        """
        Set this fov to the squares seen from initial_location on level_.

        level_ - The level on which the field of view is being calculated.
        initial_location - the viewpoint from which the field of view is being
            calculated.
        """
        
        dimensions = level_.dimensions
        border = set()
        fov_set = set()
        dude_set = set()

        border.add(initial_location)

        while len(border) != 0:
            next_border = set()
            for i in border:
                for adjacent in coordinates.adjacent_coords(i):
                    if adjacent in fov_set or adjacent in border or adjacent in next_border:
                        pass
                    elif not coordinates.legal(adjacent, dimensions):
                        pass
                    else:
                        if level_.dungeonGlyph(adjacent) in OPEN_GLYPHS:
                            next_border.add(adjacent)
                        else:
                            fov_set.add(adjacent)
                        if adjacent in level_.dudeLayer:
                            dude_set.add(level_.dudeLayer[adjacent])

                fov_set.add(i)

            border = next_border

        self.__the_field = fov_set
        self.dudes = frozenset(dude_set)