Example #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
Example #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)
Example #3
0
    def run(self, bot) -> SimpleControllerState:
        car = bot.info.my_car
        shoot_controls = bot.shoot.with_aiming(
            bot, self.aim_cone,
            predict.time_till_reach_ball(bot.info.my_car, bot.info.ball))
        hit_pos = bot.shoot.ball_when_hit.pos

        if bot.do_rendering:
            self.aim_cone.draw(bot, hit_pos, r=0, g=170, b=255)

        if bot.shoot.can_shoot:
            if bot.shoot.using_curve and bot.do_rendering:
                rendering.draw_bezier(
                    bot, [car.pos, bot.shoot.curve_point, hit_pos])
            return shoot_controls

        else:
            # go home-ish
            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=True,
                                           boost_min=0,
                                           can_keep_speed=True)
Example #4
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
Example #5
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
Example #6
0
    def run(self, bot) -> SimpleControllerState:

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

        hits_goal_prediction = predict.will_ball_hit_goal(bot)
        reach_time = clip(predict.time_till_reach_ball(car, ball), 0,
                          hits_goal_prediction.time - 0.5)
        reachable_ball = predict.ball_predict(bot, reach_time)
        self.ball_to_goal_right = bot.info.own_goal.right_post - reachable_ball.pos
        self.ball_to_goal_left = bot.info.own_goal.left_post - reachable_ball.pos
        self.aim_cone = AimCone(self.ball_to_goal_left,
                                self.ball_to_goal_right)

        self.aim_cone.draw(reachable_ball.pos, r=200, g=0, b=160)

        shoot_controls = bot.shoot.with_aiming(bot, self.aim_cone, reach_time)

        if not bot.shoot.can_shoot:
            # Go home
            return bot.drive.home(bot)
        else:
            return shoot_controls
Example #7
0
    def run(self, bot) -> SimpleControllerState:

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

        my_hit_time = predict.time_till_reach_ball(car, ball)
        reachable_ball = predict.ball_predict(bot, predict.time_till_reach_ball(car, ball))
        ball_to_goal_right = bot.info.opp_goal.right_post - reachable_ball.pos
        ball_to_goal_left = bot.info.opp_goal.left_post - reachable_ball.pos
        aim_cone = AimCone(ball_to_goal_right, ball_to_goal_left)
        shoot_controls = bot.shoot.with_aiming(bot, aim_cone, my_hit_time)

        hit_pos = bot.shoot.ball_when_hit.pos
        dist = norm(car.pos - hit_pos)
        closest_enemy, enemy_dist = bot.info.closest_enemy(0.5 * (hit_pos + ball.pos))

        if not bot.shoot.can_shoot and is_closer_to_goal_than(car.pos, hit_pos, bot.info.team):
            # Can't shoot but or at least on the right side: Chase

            goal_to_ball = normalize(hit_pos - bot.info.opp_goal.pos)
            offset_ball = hit_pos + goal_to_ball * Ball.RADIUS * 0.9
            enemy_hit_time = predict.time_till_reach_ball(closest_enemy, ball)
            enemy_hit_pos = predict.ball_predict(bot, enemy_hit_time).pos
            if enemy_hit_time < 1.5 * my_hit_time:
                if bot.do_rendering:
                    bot.renderer.draw_line_3d(closest_enemy.pos, enemy_hit_pos, bot.renderer.red())
                return bot.drive.home(bot)

            if bot.do_rendering:
                bot.renderer.draw_line_3d(car.pos, offset_ball, bot.renderer.yellow())

            return bot.drive.towards_point(bot, offset_ball, target_vel=2200, slide=False, boost_min=0)

        elif len(bot.info.teammates) == 0 and not bot.shoot.aim_is_ok and hit_pos.y * -bot.info.team_sign > 4250 and abs(hit_pos.x) > 900 and not dist < 420:
            # hit_pos is an enemy corner and we are not close: Avoid enemy corners in 1s and just wait

            enemy_to_ball = normalize(hit_pos - closest_enemy.pos)
            wait_point = hit_pos + enemy_to_ball * enemy_dist  # a point 50% closer to the center of the field
            wait_point = lerp(wait_point, ball.pos + Vec3(0, bot.info.team_sign * 3000, 0), 0.5)

            if bot.do_rendering:
                bot.renderer.draw_line_3d(car.pos, wait_point, bot.renderer.yellow())

            return bot.drive.towards_point(bot, wait_point, norm(car.pos - wait_point), slide=False, can_keep_speed=True, can_dodge=False)

        elif bot.shoot.can_shoot:

            # Shoot !
            if bot.do_rendering:
                aim_cone.draw(bot, bot.shoot.ball_when_hit.pos, r=0, b=0)
                if bot.shoot.using_curve:
                    rendering.draw_bezier(bot, [car.pos, bot.shoot.curve_point, hit_pos])
            return shoot_controls

        else:
            # We can't shoot at goal reliably
            # How about a shot to the corners then?
            corners = [
                Vec3(-Field.WIDTH2, -bot.info.team_sign * Field.LENGTH2, 0),
                Vec3(Field.WIDTH2, -bot.info.team_sign * Field.LENGTH2, 0),
            ]
            for corner in corners:
                ctrls = bot.shoot.towards(bot, corner, bot.info.my_car.reach_ball_time)
                if bot.shoot.can_shoot:
                    aim_cone.draw(bot, bot.shoot.ball_when_hit.pos, b=0)
                    if bot.shoot.using_curve:
                        rendering.draw_bezier(bot, [car.pos, bot.shoot.curve_point, hit_pos])
                    return ctrls

            enemy_to_ball = normalize(xy(ball.pos - closest_enemy.pos))
            ball_to_my_goal = normalize(xy(bot.info.own_goal.pos - ball.pos))
            dot_threat = dot(enemy_to_ball, ball_to_my_goal)  # 1 = enemy is in position, -1 = enemy is NOT in position

            if car.boost <= 10 and ball.pos.y * bot.info.team_sign < 0 and dot_threat < 0.15:
                collect_center = ball.pos.y * bot.info.team_sign <= 0
                collect_small = closest_enemy.pos.y * bot.info.team_sign <= 0 or enemy_dist < 900
                pads = filter_pads(bot, bot.info.big_boost_pads, big_only=not collect_small, enemy_side=False,
                                   center=collect_center)
                bot.maneuver = CollectClosestBoostManeuver(bot, pads)

            # return home-ish
            return bot.drive.stay_at(bot, lerp(bot.info.own_goal.pos, ball.pos, 0.2), ball.pos)
Example #8
0
    def exec(self, bot) -> SimpleControllerState:

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

        my_hit_time = predict.time_till_reach_ball(car, ball)
        shoot_controls = bot.shoot.with_aiming(bot, self.aim_cone, my_hit_time)
        if bot.do_rendering:
            self.aim_cone.draw(bot, bot.shoot.ball_when_hit.pos, b=0)

        hit_pos = bot.shoot.ball_when_hit.pos
        dist = norm(car.pos - hit_pos)
        closest_enemy, enemy_dist = bot.info.closest_enemy(
            0.5 * (hit_pos + ball.pos))

        if not bot.shoot.can_shoot and is_closer_to_goal_than(
                car.pos, hit_pos, bot.info.team):
            # Can't shoot but or at least on the right side: Chase

            goal_to_ball = normalize(hit_pos - bot.info.enemy_goal)
            offset_ball = hit_pos + goal_to_ball * Ball.RADIUS * 0.9
            enemy_hit_time = predict.time_till_reach_ball(closest_enemy, ball)
            enemy_hit_pos = predict.ball_predict(bot, enemy_hit_time).pos
            if enemy_hit_time < 1.5 * my_hit_time:
                self.temp_utility_desire_boost -= bot.info.dt
                if bot.do_rendering:
                    bot.renderer.draw_line_3d(closest_enemy.pos, enemy_hit_pos,
                                              bot.renderer.red())
                return bot.drive.go_home(bot)

            if bot.do_rendering:
                bot.renderer.draw_line_3d(car.pos, offset_ball,
                                          bot.renderer.yellow())

            return bot.drive.go_towards_point(bot,
                                              offset_ball,
                                              target_vel=2200,
                                              slide=False,
                                              boost_min=0)

        elif not bot.shoot.aim_is_ok and hit_pos.y * -bot.info.team_sign > 4250 and abs(
                hit_pos.x) > 900 and not dist < 420:
            # hit_pos is an enemy corner and we are not close: Avoid enemy corners and just wait

            enemy_to_ball = normalize(hit_pos - closest_enemy.pos)
            wait_point = hit_pos + enemy_to_ball * enemy_dist  # a point 50% closer to the center of the field
            wait_point = lerp(wait_point,
                              ball.pos + Vec3(0, bot.info.team_sign * 3000, 0),
                              0.5)

            if bot.do_rendering:
                bot.renderer.draw_line_3d(car.pos, wait_point,
                                          bot.renderer.yellow())

            return bot.drive.go_towards_point(bot,
                                              wait_point,
                                              norm(car.pos - wait_point),
                                              slide=False,
                                              can_keep_speed=True,
                                              can_dodge=False)

        elif not bot.shoot.can_shoot:

            enemy_to_ball = normalize(xy(ball.pos - closest_enemy.pos))
            ball_to_my_goal = normalize(xy(bot.info.own_goal - ball.pos))
            dot_threat = dot(
                enemy_to_ball, ball_to_my_goal
            )  # 1 = enemy is in position, -1 = enemy is NOT in position

            if car.boost == 0 and ball.pos.y * bot.info.team_sign < 500 and dot_threat < 0.1:

                collect_center = ball.pos.y * bot.info.team_sign <= 0
                collect_small = closest_enemy.pos.y * bot.info.team_sign <= 0 or enemy_dist < 900
                pads = filter_pads(bot,
                                   bot.info.big_boost_pads,
                                   big_only=not collect_small,
                                   enemy_side=False,
                                   center=collect_center)
                bot.maneuver = CollectClosestBoostManeuver(bot, pads)
            # return home
            return bot.drive.go_home(bot)

        else:
            # Shoot !
            if bot.shoot.using_curve and bot.do_rendering:
                rendering.draw_bezier(
                    bot, [car.pos, bot.shoot.curve_point, hit_pos])
            return shoot_controls
    def update(self, bot):
        ball = bot.info.ball

        # Find closest foe to ball
        self.opp_closest_to_ball, self.opp_closest_to_ball_dist = argmin(bot.info.opponents, lambda opp: norm(opp.pos - ball.pos))

        # Possession and on/off-site
        self.car_with_possession = None
        self.ally_with_possession = None
        self.opp_with_possession = None
        for car in bot.info.cars:

            # Effective position
            car.effective_pos = car.pos + xy(car.vel) * 0.8

            # On site
            car_to_ball = ball.pos - car.pos
            car_to_ball_unit = normalize(car_to_ball)
            car.onsite = dot(Vec3(y=-car.team_sign), car_to_ball_unit)

            # Reach ball time
            car.reach_ball_time = predict.time_till_reach_ball(car, ball)
            reach01 = 1 - 0.9 * lin_fall(car.reach_ball_time, 4) ** 0.5

            # Possession
            point_in_front = car.pos + car.vel * 0.5
            ball_point_dist = norm(ball.pos - point_in_front)
            dist01 = 1000 / (1000 + ball_point_dist)  # Halved after 1000 uu of dist, 1/3 at 2000
            in_front01 = (dot(car.forward, car_to_ball_unit) + 1) / 2.0
            car.possession = dist01 * in_front01 * reach01
            if self.car_with_possession is None or car.possession > self.car_with_possession.possession:
                self.car_with_possession = car
            if car.team == bot.team and (self.ally_with_possession is None or car.possession > self.ally_with_possession.possession):
                self.ally_with_possession = car
            if car.team != bot.team and (self.opp_with_possession is None or car.possession > self.opp_with_possession.possession):
                self.opp_with_possession = car

        # Objectives
        if len(bot.info.team_cars) == 1:
            # No team mates. No roles
            bot.info.my_car.objective = bot.info.my_car.last_objective = Objective.SOLO
            return

        for car in bot.info.cars:
            car.last_objective = car.objective
            car.objective = Objective.UNKNOWN

        attacker, attacker_score = argmax(bot.info.team_cars,
                                          lambda ally: ((1.0 if ally.last_objective == Objective.GO_FOR_IT else 0.73)
                                                        * ease_out(0.2 + 0.8 * ally.boost / 100, 2)  # 50 boost is 0.85, 0 boost is 0.2
                                                        * ally.possession
                                                        * ally.got_it_according_to_quick_chat_01(bot.info.time)
                                                        * (1.0 if ally.onsite else 0.5)
                                                        * (0 if ally.is_demolished else 1)))

        attacker.objective = Objective.GO_FOR_IT
        self.ideal_follow_up_pos = xy(ball.pos + bot.info.own_goal.pos) * 0.5
        follower, follower_score = argmax([ally for ally in bot.info.team_cars if ally.objective == Objective.UNKNOWN],
                                          lambda ally: (1.0 if ally.last_objective == Objective.FOLLOW_UP else 0.73)
                                                        * ease_out(0.2 * 0.8 * ally.boost / 100, 2)
                                                        * (1 + ally.onsite / 2)
                                                        * lin_fall(norm(ally.effective_pos - self.ideal_follow_up_pos), 3000)
                                                        * (0 if ally.is_demolished else 1))
        if follower is not None:
            follower.objective = Objective.FOLLOW_UP
        for car in bot.info.team_cars:
            if car.objective == Objective.UNKNOWN:
                car.objective = Objective.ROTATING