예제 #1
0
    def move(self, me: Wizard, world: World, game: Game, move: Move):
        # First, initialize some common things.
        attack_faction = self.get_attack_faction(me.faction)
        skills = set(me.skills)

        # Learn some skill.
        move.skill_to_learn = self.skill_to_learn(skills)
        # Apply some skill.
        move.status_target_id = me.id

        # Bonus pick up.
        bonus_tick_index = world.tick_index % 2500
        if self.pick_up_bonus is None and (me.x > 1600.0 or me.y < 2400.0) and bonus_tick_index >= 2000:
            self.pick_up_bonus = min(BONUSES, key=(lambda bonus: me.get_distance_to(*bonus)))
        if me.x < 400.0 and me.y > 3600.0:
            self.pick_up_bonus = None
        if self.pick_up_bonus is not None:
            x, y = self.pick_up_bonus
            if not MyStrategy.attack_nearest_enemy(me, world, game, move, skills, attack_faction):
                move.turn = me.get_angle_to(x, y)
            if bonus_tick_index >= 2000 and me.get_distance_to(x, y) < me.radius + 2.0 * game.bonus_radius:
                # Bonus hasn't appeared yet. Stay nearby.
                return
            if 0 < bonus_tick_index < 2000 and (
                # Bonus has just been picked up.
                me.get_distance_to(x, y) < me.radius or
                # No bonus there.
                (me.get_distance_to(x, y) < me.vision_range and not world.bonuses)
            ):
                self.pick_up_bonus = None
            else:
                self.move_by_tiles_to(me, world, game, move, x, y)
            return

        # Check if I'm healthy.
        if self.is_in_danger(me, world, game, me.x, me.y, attack_faction):
            # Retreat to the nearest safe tile.
            x, y = min((
                (x, y)
                for x, y in KEY_TILES
                if not self.is_in_danger(me, world, game, x, y, attack_faction)
            ), key=(lambda point: me.get_distance_to(*point)))
            self.move_by_tiles_to(me, world, game, move, x, y)
            MyStrategy.attack_nearest_enemy(me, world, game, move, skills, attack_faction)
            return

        # Else try to attack the best target.
        if MyStrategy.attack_best_target(me, world, game, move, skills, attack_faction):
            return

        # Quick and dirty fix to avoid being stuck near the base.
        if me.x < 400.0 and me.y > 3600.0:
            move.turn = me.get_angle_to(*self.move_by_tiles_to(me, world, game, move, 200.0, 200.0))
            return

        # Nothing to do. Just go to enemy base.
        x, y = self.move_by_tiles_to(me, world, game, move, ATTACK_BASE_X, ATTACK_BASE_Y)
        move.turn = me.get_angle_to(x, y)
예제 #2
0
    def move(self, me: Hockeyist, world: World, game: Game, move: Move):
        factory = self.create_factory(me, world, game, move)
        strategy = self.create_strategy(factory, me, world, game, move)

        move.action = strategy.action
        move.speed_up = strategy.speed_up
        move.turn = strategy.turn

        factory.info[type(strategy)] = strategy.info
예제 #3
0
def apply_go_to_move(point: Point2D, me: Wizard, game: Game, move: Move):
    """
    Простейший способ перемещения волшебника.
    """
    angle = me.get_angle_to(point.x, point.y)
    move.turn = angle

    if math.fabs(angle) < game.staff_sector / 4.0:
        move.speed = game.wizard_forward_speed
예제 #4
0
    def move(self, me: Hockeyist, world: World, game: Game, move: Move):
        factory = self.create_factory(me, world, game, move)
        strategy = self.create_strategy(factory, me, world, game, move)

        move.action = strategy.action
        move.speed_up = strategy.speed_up
        move.turn = strategy.turn

        factory.info[type(strategy)] = strategy.info
예제 #5
0
    def move(self, me: Hockeyist, world: World, game: Game, move: Move):

        # self.me = me
        # self.world = world
        # self.game = game
        # self.me_move = move

        if me.state == HockeyistState.SWINGING:
            move.action = ActionType.STRIKE
            return

        if world.puck.owner_player_id == me.player_id:

            if world.puck.owner_hockeyist_id == me.id:

                opponent = world.get_opponent_player()

                net_x = 0.5 * (opponent.net_back + opponent.net_front)
                net_y = 0.5 * (opponent.net_bottom + opponent.net_top)

                angle_to_net = me.get_angle_to(net_x, net_y)
                move.turn = angle_to_net

                if abs(angle_to_net) < self.STRIKE_ANGLE:
                    move.action = ActionType.STRIKE

            else:

                nearest_opponent = self.get_nearest_opponent(me, world)

                if nearest_opponent is not None:

                    if me.get_distance_to_unit(nearest_opponent) > game.stick_length:
                        move.speed_up = 1
                    else:
                        move.action = ActionType.STRIKE

                    move.turn = me.get_angle_to_unit(nearest_opponent)

        else:
            move.speed_up = 1
            move.turn = me.get_angle_to_unit(world.puck)
            move.action = ActionType.TAKE_PUCK
예제 #6
0
    def move(self, me: Wizard, world: World, game: Game, move: Move):
        # Every tick, update state first
        state_machine.update_state(me, world, game)

        # Take action for this state
        state_machine.run(me, world, game)

        # Current state
        state = state_machine.get_state()

        # Move
        move.speed = state.forward_speed
        move.strafe_speed = state.strafe_speed
        move.turn = state.turn_angle
        move.action = state.action
예제 #7
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
예제 #8
0
    def read_move(self):
        if not self.read_boolean():
            return None

        move = Move()

        move.speed_up = self.read_double()
        move.turn = self.read_double()
        move.action = self.read_enum(ActionType)
        if move.action == ActionType.PASS:
            move.pass_power = self.read_double()
            move.pass_angle = self.read_double()
        elif move.action == ActionType.SUBSTITUTE:
            move.teammate_index = self.read_int()

        return move
예제 #9
0
    def read_move(self):
        if not self.read_boolean():
            return None

        move = Move()

        move.speed_up = self.read_double()
        move.turn = self.read_double()
        move.action = self.read_enum(ActionType)
        if move.action == ActionType.PASS:
            move.pass_power = self.read_double()
            move.pass_angle = self.read_double()
        elif move.action == ActionType.SUBSTITUTE:
            move.teammate_index = self.read_int()

        return move
예제 #10
0
    def move(self, me: Wizard, world: World, game: Game, move: Move):
        if world.tick_index == 0:
            self.init(me, move, world)
            return
        if world.tick_index < 500 and not me.master:
            if me.messages:
                for m in me.messages:
                    self.lane = m.lane
        if world.tick_index == 500 and self.lane is None:
            self.lane_analysis(world)

        self.last_tick = world.tick_index
        move.speed = 0
        move.strafe_speed = 0
        move.turn = 0
        self.x = me.x
        self.y = me.y
        self.tower_analysis(world)

        if world.tick_index - self.last_tick > 500:  # check death
            self.lane_point_index = 0
            self.stuck_start_tick = None
            self.is_fight = False
            self.lane_analysis(world)

        # Stuck
        if self.check_stuck(world.tick_index):
            self.get_out(move, game)
            self.debug_func(world)  # debug
            print("stuck")
            return

        # Escape
        if self.check_danger(me):
            if self.check_if_enemy_near(world, me, game):
                self.map_master(-1, me)
            else:
                # self.map_master(1, me)
                self.wait_status = True
                return
            self.step_point_x, self.step_point_y = self.find_way(world, me)
            self.go(me, move, game)
            self.debug_func(world)  # debug
            print("escape")
            return

        # Fight
        # TODO: уклонение от вражеских снарядов,
        # TODO: хитрая система отхода с максимзацией получаемого опыта
        # TODO: удар посохом
        # TODO: учёт бонусов на врагах
        # TODO: не всегда стрелять!?
        self.is_fight, enemy, distance_to_closest_minion, tower_near, wizards_amount = self.situation_analysis(
            world, me)
        if self.is_fight:
            self.attack(move, game, me, enemy)
            if (me.life < me.max_life*0.5) or \
                    (distance_to_closest_minion < 200) or \
                    ((type(enemy) is Wizard) and (me.life < enemy.life)) or \
                    (wizards_amount > 1):
                self.map_master(-1, me)
                self.step_point_x, self.step_point_y = self.find_way(world, me)
                self.go_back(me, move, game)
            else:
                if distance_to_closest_minion > 500 - 380 * (me.life /
                                                             me.max_life)**2:
                    if not tower_near and (wizards_amount <= 1) and (
                            type(enemy) is not MinionType.FETISH_BLOWDART):
                        self.target_point_x, self.target_point_y = enemy.x, enemy.y
                        self.step_point_x, self.step_point_y = self.find_way(
                            world, me)
                        self.go(me, move, game)
            self.debug_func(world)  # debug
            print("fight")
            return

        # GO
        if world.tick_index < 1500 - int(
                self.lane == LaneType.MIDDLE) * 250:  # wait for minions
            if me.y < 450 + me.x:
                self.map_master(-1, me)
            else:
                self.map_master(1, me)
        else:
            self.map_master(1, me)
        self.step_point_x, self.step_point_y = self.find_way(world, me)
        self.go(me, move, game)
        self.debug_func(world)  # debug
        print("GO")
예제 #11
0
 def move(self, me: Wizard, world: World, game: Game, move: Move):
     move.speed = game.wizard_forward_speed
     move.strafe_speed = game.wizard_strafe_speed
     move.turn = game.wizard_max_turn_angle
     move.action = ActionType.MAGIC_MISSILE
예제 #12
0
 def move(self, me: Hockeyist, world: World, game: Game, move: Move):
     move.speed_up = -1.0
     move.turn = pi
     move.action = ActionType.STRIKE
예제 #13
0
 def move(self, me: Hockeyist, world: World, game: Game, move: Move):
     move.speed_up = -1.0
     move.turn = pi
     move.action = ActionType.STRIKE
예제 #14
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