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)
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
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
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
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
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
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
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")
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
def move(self, me: Hockeyist, world: World, game: Game, move: Move): move.speed_up = -1.0 move.turn = pi move.action = ActionType.STRIKE
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