Ejemplo n.º 1
0
    def utility_score(self, bot) -> float:

        car = bot.info.my_car
        ball = bot.info.ball

        my_hit_time = predict.time_till_reach_ball(car, ball)
        ball_soon = predict.ball_predict(bot, min(my_hit_time, 1.0))

        close_to_ball_01 = clip01(1.0 - norm(car.pos - ball_soon.pos) / 3500) ** 0.5  # FIXME Not great

        reachable_ball = predict.ball_predict(bot, predict.time_till_reach_ball(bot.info.my_car, ball))
        xy_ball_to_goal = xy(bot.info.opp_goal.pos - reachable_ball.pos)
        xy_car_to_ball = xy(reachable_ball.pos - bot.info.my_car.pos)
        in_position_01 = ease_out(clip01(dot(xy_ball_to_goal, xy_car_to_ball)), 0.5)

        # Chase ball right after kickoff. High right after kickoff
        kickoff_bias01 = max(0, 1 - bot.info.time_since_last_kickoff * 0.3) * float(bot.info.my_car.objective == Objective.UNKNOWN)

        obj_bonus = {
            Objective.UNKNOWN: 1,
            Objective.GO_FOR_IT: 1,
            Objective.FOLLOW_UP: 0,
            Objective.ROTATING: 0,
            Objective.SOLO: 1,
        }[bot.info.my_car.objective]

        return clip01(close_to_ball_01 * in_position_01 + kickoff_bias01) * obj_bonus
Ejemplo n.º 2
0
    def utility(self, bot) -> float:

        if self.temp_utility_desire_boost > 0:
            self.temp_utility_desire_boost = max(
                0, self.temp_utility_desire_boost - bot.info.dt)
        elif self.temp_utility_desire_boost < 0:
            self.temp_utility_desire_boost = min(
                0, self.temp_utility_desire_boost + bot.info.dt)

        ball_soon = predict.ball_predict(bot, 1)

        arena_length2 = bot.info.team_sign * Field.LENGTH / 2
        own_half_01 = clip01(
            remap(arena_length2, -arena_length2, 0.0, 1.1, ball_soon.pos.y))

        reachable_ball = predict.ball_predict(
            bot, predict.time_till_reach_ball(bot.info.my_car, bot.info.ball))
        self.ball_to_goal_right = bot.info.enemy_goal_right - reachable_ball.pos
        self.ball_to_goal_left = bot.info.enemy_goal_left - reachable_ball.pos
        self.aim_cone = AimCone(self.ball_to_goal_right,
                                self.ball_to_goal_left)
        car_to_ball = reachable_ball.pos - bot.info.my_car.pos
        in_position = self.aim_cone.contains_direction(car_to_ball)

        # Chase ball right after kickoff. High right after kickoff
        kickoff_bias01 = max(0, 1 - bot.info.time_since_last_kickoff * 0.3)

        return clip01(own_half_01 + 0.1 * in_position +
                      self.temp_utility_desire_boost + kickoff_bias01)
Ejemplo n.º 3
0
    def utility_score(self, bot) -> float:

        car = bot.info.my_car

        if len(bot.info.teammates) == 0:
            team_committed01 = 0
            no_defence01 = 1
        else:
            mates = bot.info.teammates
            sum_pos = mates[0].pos + mates[0].vel * 0.5
            for mate in mates[1:]:
                sum_pos += mate.pos + mate.vel * 0.5
            avg_pos = sum_pos / len(mates)
            team_committed01 = clip01(
                norm(avg_pos - bot.info.own_goal.pos) / Field.LENGTH2)
            no_defence01 = clip01(
                argmin(mates,
                       lambda mate: norm(mate.pos - bot.info.own_goal.pos))[1]
                / 1000)

        dist_to_ball01 = clip01(
            norm(car.pos - bot.info.ball.pos) / Field.LENGTH2)

        obj_bonus = {
            Objective.UNKNOWN: 1.0,
            Objective.GO_FOR_IT: 0,
            Objective.FOLLOW_UP: 0,
            Objective.ROTATING: 1.0,
            Objective.SOLO: 1.0,
        }[car.objective]

        return 0.85 * team_committed01 * dist_to_ball01 * no_defence01 * obj_bonus
Ejemplo n.º 4
0
    def utility_score(self, bot) -> float:
        car = bot.info.my_car
        ball = bot.info.ball

        car_to_ball = car.pos - ball.pos

        bouncing_b = ball.pos.z > 130 or abs(ball.vel.z) > 300
        if not bouncing_b:
            return 0

        dist_01 = clip01(1 - norm(car_to_ball) / 3000)

        head_dir = lerp(Vec3(0, 0, 1), car.forward, 0.13)
        ang = angle_between(head_dir, car_to_ball)
        ang_01 = clip01(1 - ang / (math.pi / 2))
        xy_speed_delta_01 = lin_fall(norm(xy(car.vel - ball.vel)), 800)

        obj_bonus = {
            Objective.UNKNOWN: 0.8,
            Objective.GO_FOR_IT: 1.0,
            Objective.FOLLOW_UP: 0,
            Objective.ROTATING: 0,
            Objective.SOLO: 1.0,
        }[car.objective]

        return obj_bonus * clip01(xy_speed_delta_01 * ang_01 * dist_01 +
                                  self.is_dribbling * self.extra_utility_bias)
Ejemplo n.º 5
0
    def utility(self, bot) -> float:
        car = bot.info.my_car
        ball = bot.info.ball

        car_to_ball = car.pos - ball.pos

        bouncing_b = ball.pos.z > 130 or abs(ball.vel.z) > 300
        if not bouncing_b:
            return 0

        dist_01 = clip01(1 - norm(car_to_ball) / 3000)

        head_dir = lerp(Vec3(0, 0, 1), car.forward, 0.1)
        ang = angle_between(head_dir, car_to_ball)
        ang_01 = clip01(1 - ang / (math.pi / 2))

        return clip01(0.6 * ang_01 + 0.4 * dist_01
                      #  - 0.3 * bot.analyzer.team_mate_has_ball_01
                      + self.is_dribbling * self.extra_utility_bias)
Ejemplo n.º 6
0
    def utility(self, bot) -> float:
        team_sign = bot.info.team_sign

        length = team_sign * Field.LENGTH / 2
        ball_own_half_01 = clip01(
            remap(-length, length, -0.2, 1.2, bot.info.ball.pos.y))

        reachable_ball = predict.ball_predict(
            bot, predict.time_till_reach_ball(bot.info.my_car, bot.info.ball))
        car_to_ball = reachable_ball.pos - bot.info.my_car.pos
        in_position = self.aim_cone.contains_direction(car_to_ball,
                                                       math.pi / 8)

        return ball_own_half_01 * in_position
Ejemplo n.º 7
0
    def is_viable(self, car, current_time: float):
        up = car.up
        T = self.intercept_time - current_time
        xf = car.pos + car.vel * T + 0.5 * GRAVITY * T ** 2
        vf = car.vel + GRAVITY * T

        if self.jumping:
            if self.jump_begin_time == -1:
                jump_elapsed = 0
            else:
                jump_elapsed = current_time - self.jump_begin_time

            # How much longer we can press jump and still gain upward force
            tau = JUMP_MAX_DUR - jump_elapsed

            # Add jump pulse
            if jump_elapsed == 0:
                vf += up * JUMP_SPEED
                xf += up * JUMP_SPEED * T

            # Acceleration from holding jump
            vf += up * JUMP_ACCEL * tau
            xf += up * JUMP_ACCEL * tau * (T - 0.5 * tau)

            if self.do_second_jump:
                # Impulse from the second jump
                vf += up * JUMP_SPEED
                xf += up * JUMP_SPEED * (T - tau)

        delta_x = self.hit_pos - xf
        dir = normalize(delta_x)
        phi = angle_between(dir, car.forward)
        turn_time = 0.7 * (2 * math.sqrt(phi / 9))

        tau1 = turn_time * clip(1 - 0.3 / phi, 0.02, 1)
        required_acc = (2 * norm(delta_x)) / ((T - tau1) ** 2)
        ratio = required_acc / BOOST_ACCEL
        tau2 = T - (T - tau1) * math.sqrt(1 - clip01(ratio))
        velocity_estimate = vf + BOOST_ACCEL * (tau2 - tau1) * dir
        boost_estimate = (tau2 - tau1) * BOOST_PR_SEC
        enough_boost = boost_estimate < 0.95 * car.boost
        enough_time = abs(ratio) < 0.9
        return norm(velocity_estimate) < 0.9 * MAX_SPEED and enough_boost and enough_time
Ejemplo n.º 8
0
    def utility_score(self, bot) -> float:
        team_sign = bot.info.team_sign

        length = team_sign * Field.LENGTH2
        ball_own_half_01 = clip01(remap(-length, length, -0.8, 1.8, bot.info.ball.pos.y))

        reachable_ball = predict.ball_predict(bot, predict.time_till_reach_ball(bot.info.my_car, bot.info.ball))
        car_to_ball = reachable_ball.pos - bot.info.my_car.pos
        in_position = self.aim_cone.contains_direction(car_to_ball, math.pi / 8)

        obj_bonus = {
            Objective.UNKNOWN: 1,
            Objective.GO_FOR_IT: 1,
            Objective.FOLLOW_UP: 0,
            Objective.ROTATING: 0,
            Objective.SOLO: 1.0,
        }[bot.info.my_car.objective]

        return ball_own_half_01 * in_position * obj_bonus
Ejemplo n.º 9
0
    def utility_score(self, bot) -> float:

        car = bot.info.my_car
        ball = bot.info.ball

        follow_up_pos = bot.analyzer.ideal_follow_up_pos
        _, missing_follow_up_guy01 = argmin(
            bot.info.team_cars, lambda mate: 1.0 - clip01(
                norm(mate.pos - follow_up_pos) / Field.LENGTH2))
        attack_in_front = any(
            is_closer_to_goal_than(car.pos, mate.pos, car.team)
            for mate in bot.info.teammates
            if mate.objective == Objective.GO_FOR_IT)
        ball_in_front = is_closer_to_goal_than(car.pos, ball.pos, car.team)

        obj_bonus = {
            Objective.UNKNOWN: 0.5,
            Objective.GO_FOR_IT: 0,
            Objective.FOLLOW_UP: 1,
            Objective.ROTATING: 0,
            Objective.SOLO: 0.9,
        }[car.objective]

        return attack_in_front * ball_in_front * missing_follow_up_guy01 * bot.info.my_car.onsite * obj_bonus
Ejemplo n.º 10
0
    def exec(self, bot):

        if not self.announced_in_quick_chat:
            self.announced_in_quick_chat = True
            bot.send_quick_chat(QuickChats.CHAT_EVERYONE, QuickChats.Information_IGotIt)

        ct = bot.info.time
        car = bot.info.my_car
        up = car.up
        controls = SimpleControllerState()

        # Time remaining till intercept time
        T = self.intercept_time - bot.info.time
        # Expected future position
        xf = car.pos + car.vel * T + 0.5 * GRAVITY * T ** 2
        # Expected future velocity
        vf = car.vel + GRAVITY * T

        # Is set to false while jumping to avoid FeelsBackFlipMan
        rotate = True

        if self.jumping:
            if self.jump_begin_time == -1:
                jump_elapsed = 0
                self.jump_begin_time = ct
            else:
                jump_elapsed = ct - self.jump_begin_time

            # How much longer we can press jump and still gain upward force
            tau = JUMP_MAX_DUR - jump_elapsed

            # Add jump pulse
            if jump_elapsed == 0:
                vf += up * JUMP_SPEED
                xf += up * JUMP_SPEED * T
                rotate = False

            # Acceleration from holding jump
            vf += up * JUMP_SPEED * tau
            xf += up * JUMP_SPEED * tau * (T - 0.5 * tau)

            if self.do_second_jump:
                # Impulse from the second jump
                vf += up * JUMP_SPEED
                xf += up * JUMP_SPEED * (T - tau)

            if jump_elapsed < JUMP_MAX_DUR:
                controls.jump = True
            else:
                controls.jump = False
                if self.do_second_jump:
                    if self.jump_pause_counter < 4:
                        # Do a 4-tick pause between jumps
                        self.jump_pause_counter += 1
                    else:
                        # Time to start second jump
                        # we do this by resetting our jump counter and pretend and our aerial started in the air
                        self.jump_begin_time = -1
                        self.jumping = True
                        self.do_second_jump = False
                else:
                    # We are done jumping
                    self.jumping = False
        else:
            controls.jump = False

        delta_pos = self.hit_pos - xf
        direction = normalize(delta_pos)
        car_to_hit_pos = self.hit_pos - car.pos

        dodging = self.dodge_begin_time != -1
        if dodging:
            controls.jump = True

        # We are not pressing jump, so let's align the car
        if rotate and not dodging:

            if self.do_dodge and norm(car_to_hit_pos) < Ball.RADIUS + 80:
                # Start dodge

                self.dodge_begin_time = ct

                hit_local = dot(car_to_hit_pos, car.rot)
                hit_local.z = 0

                dodge_direction = normalize(hit_local)

                controls.roll = 0
                controls.pitch = -dodge_direction.x
                controls.yaw = sign(car.rot.get(2, 2)) * direction.y
                controls.jump = True

            else:
                # Adjust orientation
                if norm(delta_pos) > 50:
                    pd = bot.fly.align(bot, looking_in_dir(delta_pos))
                else:
                    if self.target_rot is not None:
                        pd = bot.fly.align(bot, self.target_rot)
                    else:
                        pd = bot.fly.align(bot, looking_in_dir(self.hit_pos - car.pos))

                controls.roll = pd.roll
                controls.pitch = pd.pitch
                controls.yaw = pd.yaw

        if not dodging and angle_between(car.forward, direction) < 0.3:
            if norm(delta_pos) > 40:
                controls.boost = 1
                controls.throttle = 0
            else:
                controls.boost = 0
                controls.throttle = clip01(0.5 * THROTTLE_AIR_ACCEL * T ** 2)
        else:
            controls.boost = 0
            controls.throttle = 0

        prediction = predict.ball_predict(bot, T)
        self.done = T < 0
        if norm(self.hit_pos - prediction.pos) > 50:
            # Jump shot failed
            self.done = True
            bot.send_quick_chat(QuickChats.CHAT_EVERYONE, QuickChats.Apologies_Cursing)

        if bot.do_rendering:
            car_to_hit_dir = normalize(self.hit_pos - car.pos)
            color = bot.renderer.pink()
            rendering.draw_cross(bot, self.hit_pos, color, arm_length=100)
            rendering.draw_circle(bot, lerp(car.pos, self.hit_pos, 0.25), car_to_hit_dir, 40, 12, color)
            rendering.draw_circle(bot, lerp(car.pos, self.hit_pos, 0.5), car_to_hit_dir, 40, 12, color)
            rendering.draw_circle(bot, lerp(car.pos, self.hit_pos, 0.75), car_to_hit_dir, 40, 12, color)
            bot.renderer.draw_line_3d(car.pos, self.hit_pos, color)

        return controls
Ejemplo n.º 11
0
    def exec(self, bot):
        pred_ball = predict.ball_predict(bot, bot.info.my_car.reach_ball_time)

        # On a scale from 0 to 1, how much is this a clear?
        clear01 = clip01(
            norm(bot.info.opp_goal.pos - pred_ball.pos) / Field.LENGTH)**2

        ts = bot.info.team_sign
        right = lerp(bot.info.opp_goal.right_post,
                     Vec3(ts * Field.WIDTH2, ts * (Field.LENGTH2 + 300), 0),
                     clear01)
        left = lerp(bot.info.opp_goal.left_post,
                    Vec3(-ts * Field.WIDTH2, ts * (Field.LENGTH2 + 300), 0),
                    clear01)

        ball_to_right = right - pred_ball.pos
        ball_to_left = left - pred_ball.pos

        aim_cone = AimCone(ball_to_right, ball_to_left)
        shot_ctrls = bot.shoot.with_aiming(bot, aim_cone,
                                           bot.info.my_car.reach_ball_time)

        if bot.shoot.can_shoot:
            aim_cone.draw(bot.shoot.ball_when_hit.pos, b=0, r=0)

        if not bot.shoot.can_shoot:
            # We can't shoot on target
            if len(bot.info.teammates) != 0:
                # Consider passing
                for mate in bot.info.teammates:
                    point_in_front_of_mate = lerp(mate.pos,
                                                  bot.info.opp_goal.pos, 0.5)
                    shot_ctrls = bot.shoot.towards(
                        bot, point_in_front_of_mate,
                        bot.info.my_car.reach_ball_time)
                    if bot.shoot.can_shoot:
                        draw.cross(point_in_front_of_mate, draw.green())
                        return shot_ctrls

            # Atba with bias I guess
            draw.line(bot.info.my_car.pos, pred_ball.pos, bot.renderer.red())
            return bot.shoot.any_touch(bot, bot.info.my_car.reach_ball_time)

            # # We are out of position, start rotating back
            # own_goal = lerp(bot.info.own_goal.pos, bot.info.ball.pos, 0.5)
            # return bot.drive.towards_point(
            #     bot,
            #     own_goal,
            #     target_vel=1460,
            #     slide=False,
            #     boost_min=0,
            #     can_keep_speed=True
            # )
        else:
            # Shoot!
            if bot.shoot.using_curve:
                draw.bezier([
                    bot.info.my_car.pos, bot.shoot.curve_point,
                    bot.shoot.ball_when_hit.pos
                ])
            return shot_ctrls
Ejemplo n.º 12
0
def lin_fall(x, max):
    """f(0)=1. Linear fall off. Hits 0 at max."""
    return clip01((max - x) / x)