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 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 _goto_forward(self, me: Wizard): coords_tuple = self._get_next_waypoint(me) problem_unit = self._find_problem_units(me) if problem_unit: angle_to_connected_unit = me.get_angle_to_unit(problem_unit) self.log('found connected unit %s (%.4f angle)' % (problem_unit.id, angle_to_connected_unit)) if angle_to_connected_unit >= 0: self.log('run left') self.MOVE_STRAFE_SPEED = -1 * self.G.wizard_strafe_speed else: self.log('run right') self.MOVE_STRAFE_SPEED = self.G.wizard_strafe_speed else: turn_only = False if coords_tuple is None: turn_only = True coords_tuple = (self.ENEMY_BASE.x, self.ENEMY_BASE.y) angle = me.get_angle_to(*coords_tuple) self.MOVE_TURN = angle if fabs(angle) < self.STAFF_SECTOR / 4.0 and not turn_only: self.MOVE_SPEED = self.MAX_SPEED
def _goto_backward(self, me: Wizard): coords_tuple = self._get_prev_waypoint(me) problem_unit = self._find_problem_units(me, True) if problem_unit: angle_to_connected_unit = me.get_angle_to_unit(problem_unit) self.log('backward angle %.4f' % angle_to_connected_unit) self.log('found connected unit %s (%.4f angle)' % (problem_unit.id, angle_to_connected_unit)) if angle_to_connected_unit > 0: self.log('run right') self.MOVE_STRAFE_SPEED = -1 * self.G.wizard_strafe_speed else: self.log('run left') self.MOVE_STRAFE_SPEED = self.G.wizard_strafe_speed else: angle = me.get_angle_to(*coords_tuple) angle_reverse = radians(180) - fabs(angle) if angle > 0: angle_reverse *= -1 self.log('backward angle %.4f %.4f' % (angle, angle_reverse)) self.log('backward angle staff %.4f' % self.STAFF_SECTOR) self.MOVE_TURN = angle_reverse if fabs(angle_reverse) < self.STAFF_SECTOR / 4.0: self.MOVE_SPEED = -1 * self.MAX_SPEED