def goalie_can_save_straight(env, puck=None, player=None, goalie=None):
    if puck is None:
        puck = env.world.puck
    if player is None:
        player = shortcuts.opponent_player(env)
    if goalie is None:
        goalie = shortcuts.goalie(env, player)

    goal_interval = shortcuts.goal_interval(env, player)

    intersection = geometry.ray_interval_intersection(
        puck.x, puck.y, puck.speed_x, puck.speed_y,
        goal_interval[0].x, goal_interval[0].y, goal_interval[1].x, goal_interval[1].y)

    # шайба не летит в ворота
    if intersection is None:
        return True

    if goalie is None:
        return False

    old_puck = puck
    old_goalie = goalie
    for i in range(50):
        next_puck = next_puck_position(env, old_puck)
        next_goalie = next_goalie_position(env, old_goalie, old_puck)
        # print 'next_puck', next_puck.x, next_puck.y
        # print 'next_goalie', next_goalie.x, next_goalie.y

        # HARDCODE
        if geometry.distance(old_puck, next_goalie) <= 50:
            return True
        if geometry.distance(next_puck, next_goalie) <= 50:
            return True

        if shortcuts.im_left(env):
            if next_puck.x > shortcuts.opponent_player(env).net_front:
                return False
        else:
            if next_puck.x < shortcuts.opponent_player(env).net_front:
                return False

        old_puck = next_puck
        old_goalie = next_goalie

    return True
 def f(point):
     nfc = shortcuts.net_front_center(env, shortcuts.opponent_player(env))
     angles = [
         min(geometry.degree_to_rad(110), geometry.ray_ray_angle(oh, env.me, point))
         for oh in shortcuts.opponent_field_hockeyists(env)
         if geometry.distance(oh, nfc) > 300
     ]
     ticks_to_reach_point = assessments.ticks_to_reach_point(env, env.me, point)
     if not angles:
         return -ticks_to_reach_point
     return geometry.rad_to_degree(min(angles)) - ticks_to_reach_point / 100
        def count_strike_point(env):
            opponent_player = shortcuts.opponent_player(env)
            # uu = Unit(0,0,0,opponent_player.net_front, env.game.goal_net_top + env.game.goal_net_height, 0,0,0,0)
            # geometry.rad_to_degree(uu.get_angle_to(env.game.rink_left / 2. + env.game.rink_right /2. , env.game.rink_top))

            # import ipdb; ipdb.set_trace()
            return geometry.ray_interval_intersection_v2(
                geometry.Point(opponent_player.net_front, env.game.goal_net_top + env.game.goal_net_height),
                geometry.Point(math.cos(geometry.degree_to_rad(-150)), math.sin(geometry.degree_to_rad(-150))),
                geometry.Point(0, env.game.goal_net_top - 100),
                geometry.Point(world.width, env.game.goal_net_top - 100),
            )
 def __init__(self, env):
     op = shortcuts.opponent_player(env)
     mp = shortcuts.my_player(env)
     self.attack_polygons = experiments.count_optimistic_attack_polygons(
         env, op)
     self.target_polygons = [
         experiments.count_target_up_attack_polygon(env, op),
         experiments.count_target_down_attack_polygon(env, op),
     ]
     self.defence_point = experiments.count_defence_point(env)
     self.weak_polygons = experiments.count_cautious_attack_polygons(
         env, mp)
     self.dead_polygons = experiments.count_dead_polygons(env, op)
    def move(self, me, world, game, move):

        env = environment.Environment(me, world, game, move)

        if world.tick == 0:
            op = shortcuts.opponent_player(env)
            mp = shortcuts.my_player(env)
            self.attack_polygons = experiments.count_optimistic_attack_polygons(env, op)
            self.target_polygons = [
                experiments.count_target_up_attack_polygon(env, op),
                experiments.count_target_down_attack_polygon(env, op),
            ]
            self.defence_point = experiments.count_defence_point(env)
            self.weak_polygons = experiments.count_cautious_attack_polygons(env, mp)
            self.dead_polygons = experiments.count_dead_polygons(env, op)

            self.last_puck_owner_player_id = None

        self.save_last_puck_owner(env)
        self.save_start_game_tick(env)

        if env.me.state == HockeyistState.SWINGING:
            if self.swing_condition(env):
                env.move.action = ActionType.SWING

            if self.strike_condition(env):
                env.move.action = ActionType.STRIKE

            return

        hockeyist_with_puck = shortcuts.hockeyist_with_puck(env)
        my_nearest_hockeyist = min(
            shortcuts.my_field_hockeyists(env), key=lambda h: assessments.ticks_to_reach_point(env, h, env.world.puck)
        )
        if hockeyist_with_puck is None or hockeyist_with_puck.player_id != env.me.player_id:
            if my_nearest_hockeyist.id == me.id:
                self.do_get_puck_actions(env)
            else:
                self.do_protect_goal_actions(env)
        elif hockeyist_with_puck.player_id == env.me.player_id:
            if hockeyist_with_puck.id == env.me.id:
                self.attack_with_puck(env)
            else:
                self.do_protect_goal_actions(env)
    def pass_condition(self, env, strike_point):
        if env.world.tick - self.game_start_tick <= 75:
            return True

        collega = filter(lambda h: h.id != env.me.id, shortcuts.my_field_hockeyists(env))[0]
        net_center = shortcuts.net_front_center(env, shortcuts.opponent_player(env))
        if geometry.distance(collega, env.me) > 200:
            for oh in shortcuts.opponent_field_hockeyists(env):
                # my_angle = geometry.ray_ray_angle(env.me, strike_point, net_center)
                # o_angle = geometry.ray_ray_angle(oh, strike_point, net_center)
                # my_distance = geometry.distance(env.me, strike_point)
                # o_distance = geometry.distance(oh, strike_point)

                # if my_angle > o_angle and my_distance > o_distance:
                #     return True

                if geometry.interval_point_distance(env.me, strike_point, oh) < 60:
                    return True

        if any(geometry.point_in_convex_polygon(env.me, p) for p in self.dead_polygons):
            return True

        return False
    def move(self, me, world, game, move):

        env = environment.Environment(me, world, game, move)

        if world.tick == 0:
            self.attack_polygons = experiments.count_attack_polygons(
                env,
                shortcuts.opponent_player(env))
            self.weak_points = count_weak_points(env)

        if env.me.state == HockeyistState.SWINGING:
            if env.me.swing_ticks >= env.game.max_effective_swing_ticks:
                env.move.action = ActionType.STRIKE
            elif assessments.someone_can_reach_me_after_ticks(env, 2):
                env.move.action = ActionType.STRIKE
            else:
                env.move.action = ActionType.SWING
            return

        if self.attack_mode(env):
            self.do_attack_actions(env)
        else:
            self.do_defence_actions(env)