def shell_damage(shell, tank):
    '''return health damage'''
    pessimistic_tank = copy(tank)
    pessimistic_tank.width *= 1.1
    pessimistic_tank.height *= 1.1
    front, right, back, left = utils.get_borders(pessimistic_tank)
    # front, right, back, left = utils.get_borders(tank)

    next_shell_x = shell.x + shell.speedX * 1000.
    next_shell_y = shell.y + shell.speedY * 1000.

    borders_with_intersections = [(b,
            geometry.intervals_intersection(
                    b[0], b[1], b[2], b[3], shell.x, shell.y, next_shell_x, next_shell_y)) for
            b in front, right, back, left]

    borders_with_intersections = filter(lambda bi: bi[1] is not None, borders_with_intersections)
    if not borders_with_intersections:
        return 0.
    border, intersection_point = min(borders_with_intersections,
            key=lambda b: math.hypot(b[1][0] - shell.x, b[1][1] - shell.y))

    angle = geometry.get_angle(border[0] - border[2], border[1] - border[3], shell.speedX, shell.speedY)
    if angle > math.pi / 2:
        angle = math.pi - angle
    angle = math.pi / 2. - angle

    r1 = math.hypot(border[0] - intersection_point[0], border[1] - intersection_point[1])
    r2 = math.hypot(border[2] - intersection_point[0], border[3] - intersection_point[1])
    r = r1 + r2
    dist_factor = (r - 2. * min(r1, r2)) / r

    return coeff_by_angle(shell, geometry.rad_to_degree(angle)) * coeff_by_dist_factor(dist_factor)
 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 do_stop(env):
    speed_abs = geometry.vector_abs(env.me.speed_x, env.me.speed_y)
    angle = geometry.get_angle(
        math.cos(env.me.angle), math.sin(env.me.angle),
        env.me.speed_x, env.me.speed_y)
    if abs(geometry.rad_to_degree(angle)) < 90:
        env.move.turn = angle
        env.move.speed_up = -min(1., speed_abs / env.game.hockeyist_speed_down_factor)
    else:
        env.move.turn = -angle
        env.move.speed_up = min(1., speed_abs / env.game.hockeyist_speed_up_factor)
    def move(self, me, world, game, move):
        if me.teammate_index != 0:
            return

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

        if world.tick == 0:
            self.expected_angle = me.angle

        move.turn = geometry.degree_to_rad(10)
        print (
            'tick = ', world.tick,
            'angle = ', geometry.rad_to_degree(me.angle),
            'expected_angle =', geometry.rad_to_degree(self.expected_angle),
            'diff = ', geometry.rad_to_degree(abs(self.expected_angle - me.angle)),
            'angular_speed = ', geometry.rad_to_degree(me.angular_speed)
        )

        self.expected_angle = predict_andle(env)


        if world.tick >= 20:
            import ipdb; ipdb.set_trace()
    def do(self, env):
        speed_abs = geometry.vector_abs(env.me.speed_x, env.me.speed_y)
        if speed_abs < 0.0001:
            self.done = True
            print (
                'tick = ', env.world.tick,
                'Stop done',
                'x = ', env.me.x,
                'y = ', env.me.y,
                'speed abs = ', speed_abs
            )
            return

        angle = geometry.get_angle(
            math.cos(env.me.angle), math.sin(env.me.angle),
            env.me.speed_x, env.me.speed_y)
        if abs(geometry.rad_to_degree(angle)) < 90:
            env.move.turn = angle
            env.move.speed_up = -min(1., speed_abs / env.game.hockeyist_speed_down_factor)
        else:
            env.move.turn = -angle
            env.move.speed_up = min(1., speed_abs / env.game.hockeyist_speed_up_factor)