Esempio n. 1
0
    def full_scan_movable(self, enemy_cleared=True):
        """
        Call this method if enemy moved.

        Args:
            enemy_cleared (bool): True if cleared an enemy and need to scan spawn enemies.
                                  False if just a simple walk and only need to scan movable enemies.
        """
        before = self.movable_before
        for grid in before:
            grid.wipe_out()

        self.full_scan(queue=None if enemy_cleared else before,
                       must_scan=before,
                       mode='movable')

        after = self.map.select(is_siren=True)
        step = self.config.MOVABLE_ENEMY_FLEET_STEP
        matched_before, matched_after = match_movable(
            before=before.location,
            spawn=self.map.select(may_siren=True).location,
            after=after.location,
            fleets=[self.fleet_current] if enemy_cleared else [],
            fleet_step=step)
        matched_before = self.map.to_selected(matched_before)
        matched_after = self.map.to_selected(matched_after)
        logger.info(f'Movable enemy {before} -> {after}')
        logger.info(f'Tracked enemy {matched_before} -> {matched_after}')

        for grid in after.delete(matched_after):
            if not grid.may_siren:
                logger.warning(f'Wrong detection: {grid}')
                grid.wipe_out()

        diff = before.delete(matched_before)
        if diff:
            logger.info(f'Movable enemy tracking lost: {diff}')
            covered = self.map.grid_covered(self.map[self.fleet_current], location=[(0, -2)]) \
                .add(self.map.grid_covered(self.map[self.fleet_1_location], location=[(0, -1)])) \
                .add(self.map.grid_covered(self.map[self.fleet_2_location], location=[(0, -1)]))
            for grid in after:
                covered = covered.add(self.map.grid_covered(grid))
            accessible = SelectedGrids([])
            location = [(x, y) for x in range(step) for y in range(step)
                        if abs(x) + abs(y) <= step]
            for grid in diff:
                accessible = accessible.add(
                    self.map.grid_covered(grid, location=location))
            predict = accessible.intersect(covered).select(is_sea=True)
            logger.info(f'Movable enemy predict: {predict}')
            for grid in predict:
                grid.is_siren = True
                grid.is_enemy = True

        for grid in matched_after:
            if grid.location != self.fleet_current:
                grid.is_movable = True
Esempio n. 2
0
    def find_submarine(self):
        if not (self.config.SUBMARINE
                and self.map.select(is_submarine_spawn_point=True)):
            return False

        fleets = self.map.select(is_submarine=True)
        count = fleets.count
        if count == 1:
            self.fleet_submarine = fleets[0].location
        elif count == 0:
            logger.info('No submarine found')
            # Try spawn points
            spawn_point = self.map.select(is_submarine_spawn_point=True)
            if spawn_point.count == 1:
                logger.info(
                    f'Predict the only submarine spawn point {spawn_point[0]} as submarine'
                )
                self.fleet_submarine = spawn_point[0].location
            else:
                logger.info(
                    f'Having multiple submarine spawn points: {spawn_point}')
                # Try covered grids
                covered = SelectedGrids([])
                for grid in spawn_point:
                    covered = covered.add(
                        self.map.grid_covered(grid, location=[(0, 1)]))
                covered = covered.filter(lambda g: g.is_enemy or g.is_fleet or
                                         g.is_siren or g.is_boss)
                if covered.count == 1:
                    spawn_point = self.map.grid_covered(covered[0],
                                                        location=[(0, -1)])
                    logger.info(
                        f'Submarine {spawn_point[0]} covered by {covered[0]}')
                    self.fleet_submarine = spawn_point[0].location
                else:
                    logger.info(
                        'Found multiple submarine spawn points being covered')
                    # Give up
                    self.find_all_submarines()
        else:
            logger.warning('Too many submarines: %s.' % str(fleets))
            self.find_all_submarines()

        if not len(self.fleet_submarine_location):
            logger.warning(
                'Unable to find submarine, assume it is at map center')
            shape = self.map.shape
            center = (shape[0] // 2, shape[1] // 2)
            self.fleet_submarine = self.map.select(
                is_land=False).sort_by_camera_distance(center)[0].location

        self.show_submarine()
        return self.fleet_submarine_location
Esempio n. 3
0
    def full_scan_movable(self, enemy_cleared=True):
        """
        Call this method if enemy moved.

        Args:
            enemy_cleared (bool): True if cleared an enemy and need to scan spawn enemies.
                                  False if just a simple walk and only need to scan movable enemies.
        """
        before = self.movable_before
        for grid in before:
            grid.wipe_out()

        self.full_scan(queue=None if enemy_cleared else before,
                       must_scan=before,
                       mode='movable')

        # Track siren moving
        after = self.map.select(is_siren=True)
        step = self.config.MOVABLE_ENEMY_FLEET_STEP
        matched_before, matched_after = match_movable(
            before=before.location,
            spawn=self.map.select(may_siren=True).location,
            after=after.location,
            fleets=[self.fleet_current] if enemy_cleared else [],
            fleet_step=step)
        matched_before = self.map.to_selected(matched_before)
        matched_after = self.map.to_selected(matched_after)
        logger.info(f'Movable enemy {before} -> {after}')
        logger.info(f'Tracked enemy {matched_before} -> {matched_after}')

        # Delete wrong prediction
        for grid in after.delete(matched_after):
            if not grid.may_siren:
                logger.warning(f'Wrong detection: {grid}')
                grid.wipe_out()

        # Predict missing siren
        diff = before.delete(matched_before)
        _, missing = self.map.missing_get(self.battle_count,
                                          self.mystery_count,
                                          self.siren_count,
                                          self.carrier_count,
                                          mode='normal')
        if diff and missing['siren'] != 0:
            logger.warning(f'Movable enemy tracking lost: {diff}')
            covered = self.map.grid_covered(self.map[self.fleet_current],
                                            location=[(0, -2)])
            if self.fleet_1_location:
                covered = covered.add(
                    self.map.grid_covered(self.map[self.fleet_1_location],
                                          location=[(0, -1)]))
            if self.fleet_2_location:
                covered = covered.add(
                    self.map.grid_covered(self.map[self.fleet_2_location],
                                          location=[(0, -1)]))
            for grid in after:
                covered = covered.add(self.map.grid_covered(grid))
            logger.attr('enemy_covered', covered)
            accessible = SelectedGrids([])
            for grid in diff:
                self.map.find_path_initial(grid, has_ambush=False)
                accessible = accessible.add(self.map.select(cost=0)) \
                    .add(self.map.select(cost=1)).add(self.map.select(cost=2))
            self.map.find_path_initial(self.fleet_current,
                                       has_ambush=self.config.MAP_HAS_AMBUSH)
            logger.attr('enemy_accessible', accessible)
            predict = accessible.intersect(covered).select(is_sea=True,
                                                           is_fleet=False)
            logger.info(f'Movable enemy predict: {predict}')
            for grid in predict:
                grid.is_siren = True
                grid.is_enemy = True
        elif missing['siren'] == 0:
            logger.info(f'Movable enemy tracking drop: {diff}')

        for grid in matched_after:
            if grid.location != self.fleet_current:
                grid.is_movable = True