コード例 #1
0
 def attack(me: Wizard, game: Game, move: Move, skills: Set, unit: LivingUnit, allow_fireball: bool):
     action_type, min_cast_distance = MyStrategy.get_action(me, game, skills, unit, allow_fireball)
     if action_type == ActionType.NONE:
         return False
     # We can cast something.
     is_oriented, cast_angle = MyStrategy.is_oriented_to_unit(me, game, unit)
     if is_oriented:
         # Attack!
         move.cast_angle = cast_angle
         move.action = action_type
         move.min_cast_distance = min_cast_distance
         return True
     # Turn around to the enemy.
     move.turn = me.get_angle_to_unit(unit)
     return True
コード例 #2
0
    def move(self, me: Wizard, world: World, game: Game, move: Move):
        if self.debug:
            self.debug.syncronize(world)

        if not self.initialized:
            self.initialize(me, world, game)

        self.initialize_tick(me, world, game)

        score_threshold = -0.1
        wizard_score = me.life / (me.max_life * 0.5) - 1

        if self.battle_front:
            self.battle_front.init(world, me)
            front_score = self.battle_front.get_front_score(me)
            k = 0.6
            common_score = front_score * (1 - k) + wizard_score * k
        else:
            common_score = wizard_score

        nearest_target = Points2D.get_nearest_target(me, world)
        if nearest_target is not None:
            distance = me.get_distance_to_unit(nearest_target)
            angle = me.get_angle_to_unit(nearest_target)
            if (distance <= game.staff_range) and (abs(angle) <
                                                   game.staff_sector / 2.0):
                move.action = ActionType.STAFF
            elif (distance <= me.cast_range) and (abs(angle) <
                                                  game.staff_sector / 2.0):
                move.action = ActionType.MAGIC_MISSILE
                move.cast_angle = angle
                move.min_cast_distance = distance - nearest_target.radius + game.magic_missile_radius

        if common_score < score_threshold:
            previous_waypoint = Points2D.get_previous_waypoint(
                self.waypoints, me)
            self.map.note_enemy_angle = False
            self.go_to(move, previous_waypoint, note_angle=False)
            self.last_actions[world.tick_index %
                              STOP_CHECK_TICK_COUNT] = Action.BACK
            return
        else:
            nearest_target = Points2D.get_nearest_target(me, world)
            if nearest_target is not None:
                distance = me.get_distance_to_unit(nearest_target)
                angle = me.get_angle_to_unit(nearest_target)
                if distance <= me.cast_range:
                    self.go_to(move, None, note_angle=False)
                    if abs(angle) < game.staff_sector / 2.0:
                        move.action = ActionType.MAGIC_MISSILE
                        move.cast_angle = angle
                        move.min_cast_distance = distance - nearest_target.radius + game.magic_missile_radius
                    self.last_actions[world.tick_index %
                                      STOP_CHECK_TICK_COUNT] = Action.ENEMY
                    return
                else:
                    min_attack_dist = min_atack_distance(me) * self.life_coef
                    new_x = me.x + (nearest_target.x - me.x) / distance * (
                        distance - min_attack_dist)
                    new_y = me.y + (nearest_target.y - me.y) / distance * (
                        distance - min_attack_dist)
                    self.go_to(move, Point2D(new_x, new_y), note_angle=True)
                    self.last_actions[world.tick_index %
                                      STOP_CHECK_TICK_COUNT] = Action.NEXT
                    return
            else:
                next_waypoint = Points2D.get_next_waypoint(self.waypoints, me)
                note_angle = True
                if world.tick_index > STOP_CHECK_TICK_COUNT:
                    last_pos_index = (world.tick_index +
                                      1) % STOP_CHECK_TICK_COUNT
                    dist_last_poses = me.get_distance_to_unit(
                        self.last_poses[last_pos_index])
                    # если далеко не ушел и если последние все действия NEXT
                    if ((dist_last_poses < STOP_CHECK_TICK_COUNT * 0.2 *
                         game.wizard_forward_speed) and
                        (sum([x == Action.NEXT for x in self.last_actions])
                         == STOP_CHECK_TICK_COUNT)):
                        note_angle = False
                        self.map.neutral_coef = 1000 * np.random.normal(1, 0.3)
                        self.map.neutral_dist_coef = 1000
                self.go_to(move, next_waypoint, note_angle=note_angle)
                self.last_actions[world.tick_index %
                                  STOP_CHECK_TICK_COUNT] = Action.NEXT
                if world.tick_index < SLOW_MOVE_TICK_COUNT:
                    move.speed *= 0.5
                    move.strafe_speed *= 0.5
                return
コード例 #3
0
    def move(self, me: Wizard, world: World, game: Game, move: Move):
        self.log('TICK %s' % world.tick_index)
        self._init(game, me, world, move)
        self.log('me %s %s %f' %
                 (me.x, me.y, me.get_distance_to(*self.INIT_POINT)))

        # initial cooldown
        if self.PASS_TICK_COUNT:
            self.PASS_TICK_COUNT -= 1
            self.log('initial cooldown pass turn')
            return

        # select lane
        self._select_lane(me)

        # STRATEGY LOGIC
        enemy_targets = self._enemies_in_attack_distance(me)
        enemy_who_can_attack_me = self._enemies_who_can_attack_me(me)
        retreat_move_lock = False
        retreat_by_low_hp = False

        # чистим уже погибшие снаряды из карты
        current_projectiles_id = set(
            [p.id for p in self.W.projectiles if p.owner_unit_id == me.id])
        cached_projectiles_id = set(self.PROJECTILE_MAP.keys())
        for k in cached_projectiles_id - current_projectiles_id:
            del self.PROJECTILE_MAP[k]

        # ищем последний созданный снаряд и его цель для карты снарядов
        if self.PROJECTILE_LAST_ENEMY:
            for p in self.W.projectiles:
                if p.owner_unit_id == me.id and p.id not in self.PROJECTILE_MAP:
                    self.PROJECTILE_MAP[p.id] = self.PROJECTILE_LAST_ENEMY
                    self.PROJECTILE_LAST_ENEMY = None
                    break
        self.log('projectile map %s' % str(self.PROJECTILE_MAP))

        # если ХП мало отступаем
        if me.life < me.max_life * self.LOW_HP_FACTOR:
            retreat_by_low_hp = True
            self.log('retreat by low HP')
            if len(enemy_who_can_attack_me):
                self._goto_backward(me)
                retreat_move_lock = True

        if len(enemy_who_can_attack_me) > self.MAX_ENEMIES_IN_DANGER_ZONE:
            self.log('retreat by enemies in danger zone')
            self._goto_backward(me)
            retreat_move_lock = True

        # если врагов в радиусе обстрела нет - идём к их базе если не находимся в режиме отступления
        if not enemy_targets and not retreat_by_low_hp:
            self.log('move to next waypoint')
            self._goto_forward(me)

        # если на поле есть наши снаряды и расстояние до цели меньше расстояния каста
        # пробуем подойти к цели (если не находимся в отступлении)
        if not retreat_by_low_hp:
            potential_miss_enemies = self._find_potential_miss_enemy(me)
            self.log('found %s potential miss enemies' %
                     potential_miss_enemies)
            if potential_miss_enemies:
                e = self._sort_by_angle(me, potential_miss_enemies)[0]
                self._goto_enemy(me, e)

        if enemy_targets:
            # есть враги в радиусе обстрела
            self.log('found %d enemies for attack' % len(enemy_targets))
            selected_enemy = self._select_enemy_for_attack(me, enemy_targets)
            angle_to_enemy = me.get_angle_to_unit(selected_enemy)

            # если цель не в секторе атаки - поворачиваемся к ней (приоритет за направлением на точку отступления)
            if not self._enemy_in_attack_sector(me, selected_enemy):
                if not retreat_move_lock:
                    self.log('select enemy for turn %s' % selected_enemy.id)
                    self.MOVE_TURN = angle_to_enemy
                else:
                    self.log('ignore select enemy for turn %s by retreat' %
                             selected_enemy.id)
            else:
                # если можем атаковать - атакуем
                self.log('select enemy for attack %s' % selected_enemy.id)
                move.cast_angle = angle_to_enemy
                if self._enemy_in_cast_distance(me, selected_enemy):
                    self.log('cast attack')
                    move.action = ActionType.MAGIC_MISSILE
                    move.min_cast_distance = self._cast_distance(
                        me, selected_enemy)
                    self.PROJECTILE_LAST_ENEMY = selected_enemy.id
                else:
                    self.log('staff attack')
                    move.action = ActionType.STAFF

        if self.MOVE_TURN is not None:
            move.turn = self.MOVE_TURN
            self.MOVE_TURN = None
        if self.MOVE_SPEED is not None:
            move.speed = self.MOVE_SPEED
            self.MOVE_SPEED = None
        if self.MOVE_STRAFE_SPEED is not None:
            move.strafe_speed = self.MOVE_STRAFE_SPEED
            self.MOVE_STRAFE_SPEED = None