Beispiel #1
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)
Beispiel #2
0
    def exec(self, bot):

        goal_to_ball = bot.info.ball.pos - bot.info.own_goal.pos
        goal_to_car = bot.info.my_car.pos - bot.info.own_goal.pos

        car_prj = proj_onto(goal_to_car, goal_to_ball)
        target = lerp(bot.info.own_goal.pos + car_prj,
                      lerp(bot.info.ball.pos, bot.info.opp_goal.pos, 0.4),
                      0.08)

        draw.line(bot.info.my_car.pos, target, bot.renderer.purple())

        speed = max(
            (norm(bot.info.my_car.pos - bot.info.ball.pos) - 900) * 0.6, 100)

        return bot.drive.towards_point(
            bot,
            target,
            target_vel=speed,
            slide=True,
            boost_min=0,
            can_keep_speed=norm(bot.info.my_car.pos - bot.info.ball.pos) >
            3000,
            can_dodge=True,
            wall_offset_allowed=125)
Beispiel #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
Beispiel #4
0
    def run(self, bot) -> SimpleControllerState:

        car = bot.info.my_car
        ball = bot.info.ball
        dist_ball = norm(car.pos - ball.pos)
        target_pos = bot.analyzer.ideal_follow_up_pos
        dist_target = norm(car.pos - target_pos)

        return bot.drive.towards_point(bot,
                                       bot.analyzer.ideal_follow_up_pos,
                                       target_vel=dist_target * 0.8,
                                       slide=dist_target > 1000,
                                       can_dodge=False)
Beispiel #5
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
Beispiel #6
0
    def find_landing_orientation(car: Car, num_points: int) -> Mat33:
        """
        dummy = DummyObject(car)
        trajectory = [Vec3(dummy.pos)]

        for i in range(0, num_points):
            fall(dummy, 0.0333)  # Apply physics and let car fall through the air
            trajectory.append(Vec3(dummy.pos))
            up = dummy.pitch_surface_normal()
            if norm(up) > 0.0 and i > 10:
                up = normalize(up)
                forward = normalize(dummy.vel - dot(dummy.vel, up) * up)
                left = cross(up, forward)

                return Mat33.from_columns(forward, left, up)

        return Mat33(car.rot)
        """

        forward = normalize(xy(
            car.vel)) if norm(xy(car.vel)) > 20 else car.forward
        up = Vec3(z=1)
        left = cross(up, forward)

        return Mat33.from_columns(forward, left, up)
Beispiel #7
0
    def exec(self, bot) -> SimpleControllerState:
        car = bot.info.my_car

        # Somehow we didn't find a good pad
        if self.target_pad is None:
            self.done = True
            return SimpleControllerState()

        # Since this maneuver is stopped early, we make sure some time pass before announcing. This prevents spam
        if not self.announced_in_tmcp and self.time_begin + 0.1 < bot.info.time:
            self.announced_in_tmcp = True
            bot.send_tmcp(
                TMCPMessage.boost_action(bot.team, bot.index,
                                         self.target_pad.index))

        # End maneuver when almost there or pad becomes inactive
        car_to_pad = self.target_pad.pos - car.pos
        vel = proj_onto_size(car.vel, car_to_pad)
        dist = norm(car_to_pad)
        if dist < 50 + vel * 0.2 or car.boost > 50 or not self.target_pad.is_active:
            self.done = True

        draw.line(car.pos, self.target_pad.pos, bot.renderer.yellow())
        return bot.drive.towards_point(bot,
                                       self.target_pad.pos,
                                       target_vel=self.target_vel,
                                       slide=True,
                                       boost_min=0,
                                       can_dodge=self.target_pad.is_big)
Beispiel #8
0
    def find_landing_orientation(car: Car) -> Mat33:

        # FIXME: This uses a cheap approximation of the walls to find landing orientation

        obj = DummyObject(car)
        prev_pos = obj.pos
        for i in range(100):
            predict.fall(obj, 0.1)

            # Checking for intersections
            for plane in Field.SIDE_WALLS_AND_GROUND:
                if intersects_plane(prev_pos, obj.pos, plane):
                    # Bingo!
                    fall_dir = normalize(obj.pos - prev_pos)
                    left = -cross(fall_dir, plane.normal)
                    forward = -cross(plane.normal, left)

                    return Mat33.from_columns(forward, left, plane.normal)

            prev_pos = obj.pos

        # No wall/ground intersections found in fall
        # Default to looking in direction of velocity, but upright

        forward = normalize(xy(
            car.vel)) if norm(xy(car.vel)) > 20 else car.forward
        up = Vec3(z=1)
        left = cross(up, forward)

        return Mat33.from_columns(forward, left, up)
Beispiel #9
0
def time_till_reach_ball(car, ball):
    """ Rough estimate about when we can reach the ball in 2d. """
    car_to_ball = xy(ball.pos - car.pos)
    dist = norm(car_to_ball) - Ball.RADIUS / 2
    vel_c_f = proj_onto_size(car.vel, car_to_ball)
    vel_b_f = proj_onto_size(ball.vel, car_to_ball)
    vel_c_amp = lerp(vel_c_f, norm(car.vel), 0.58)
    vel_f = vel_c_amp - vel_b_f
    dist_long_01 = clip01(dist / 10_000.0)
    time_normal = dist / max(220, vel_f)
    time_long = dist / max(norm(car.vel), 1410)
    time = lerp(time_normal, time_long, dist_long_01)
    arrive_time = time * 0.85
    # Combine slightly with old prediction to negative rapid changes
    result = lerp(arrive_time, car.last_expected_time_till_reach_ball, 0.22)
    car.last_expected_time_till_reach_ball = arrive_time
    return result
Beispiel #10
0
    def exec(self, bot) -> SimpleControllerState:
        car = bot.info.my_car

        self.done = norm(car.pos) < 1100  # End when getting close to ball (approx at boost pad)

        curve_point = curve_from_arrival_dir(car.pos, self.target_loc, self.target_dir)
        return bot.drive.towards_point(bot, curve_point, target_vel=1200, slide=True, boost_min=20,
                                       can_keep_speed=False)
Beispiel #11
0
    def exec(self, bot) -> SimpleControllerState:
        DODGE_DIST = 250
        MIDDLE_OFFSET = 430

        # Since ball is at (0,0) we don't we a car_to_ball variable like we do so many other places
        car = bot.info.my_car
        dist = norm(car.pos)
        vel_p = -proj_onto_size(car.vel, car.pos)

        point = Vec3(0, bot.info.team_sign * (dist / 2.6 - MIDDLE_OFFSET), 0)
        speed = 2300
        opp_dist = norm(bot.info.opponents[0].pos)
        opp_does_kick = opp_dist < dist + 600

        # Opponent is not going for kickoff, so we slow down a bit
        if not opp_does_kick:
            speed = 2210
            point = Vec3(0, bot.info.team_sign * (dist / 2.05 - MIDDLE_OFFSET),
                         0)
            point += Vec3(35 * sign(car.pos.x), 0, 0)

        # Dodge when close to (0, 0) - but only if the opponent also goes for kickoff.
        # The dodge itself should happen in about 0.3 seconds
        if dist - DODGE_DIST < vel_p * 0.3 and opp_does_kick:
            bot.drive.start_dodge(bot)

        # Make two dodges when spawning far back
        elif dist > 3640 and vel_p > 1200 and not opp_does_kick:
            bot.drive.start_dodge(bot)

        # Pickup boost when spawning back corner by driving a bit towards the middle boost pad first
        elif abs(car.pos.x) > 230 and abs(car.pos.y) > 2880:
            # The pads exact location is (0, 2816), but don't have to be exact
            point.y = bot.info.team_sign * 2790

        self.done = not bot.info.is_kickoff
        bot.renderer.draw_line_3d(car.pos, point, bot.renderer.white())

        return bot.drive.towards_point(bot,
                                       point,
                                       target_vel=speed,
                                       slide=False,
                                       boost_min=0,
                                       can_dodge=False,
                                       can_keep_speed=False)
Beispiel #12
0
 def closest_enemy(self, pos: Vec3):
     enemy = None
     dist = -1
     for e in self.opponents:
         d = norm(e.pos - pos)
         if enemy is None or d < dist:
             enemy = e
             dist = d
     return enemy, dist
Beispiel #13
0
    def exec(self, bot):

        controls = SimpleControllerState()
        dt = bot.info.dt
        car = bot.info.my_car

        relative_rotation = dot(transpose(car.rot), self.target)
        geodesic_local = rotation_to_axis(relative_rotation)

        # figure out the axis of minimal rotation to target
        geodesic_world = dot(car.rot, geodesic_local)

        # get the angular acceleration
        alpha = Vec3(
            self.controller(geodesic_world.x, car.ang_vel.x, dt),
            self.controller(geodesic_world.y, car.ang_vel.y, dt),
            self.controller(geodesic_world.z, car.ang_vel.z, dt)
        )

        # reduce the corrections for when the solution is nearly converged
        alpha.x = self.q(abs(geodesic_world.x) + abs(car.ang_vel.x)) * alpha.x
        alpha.y = self.q(abs(geodesic_world.y) + abs(car.ang_vel.y)) * alpha.y
        alpha.z = self.q(abs(geodesic_world.z) + abs(car.ang_vel.z)) * alpha.z

        # set the desired next angular velocity
        ang_vel_next = car.ang_vel + alpha * dt

        # determine the controls that produce that angular velocity
        roll_pitch_yaw = AerialTurnManeuver.aerial_rpy(car.ang_vel, ang_vel_next, car.rot, dt)
        controls.roll = roll_pitch_yaw.x
        controls.pitch = roll_pitch_yaw.y
        controls.yaw = roll_pitch_yaw.z

        self._timer += dt

        if ((norm(car.ang_vel) < self.epsilon_ang_vel and
             norm(geodesic_world) < self.epsilon_rotation) or
                self._timer >= self.timeout or car.on_ground):
            self.done = True

        controls.throttle = 1.0

        return controls
Beispiel #14
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
Beispiel #15
0
    def find_landing_orientation(car: Car) -> Mat33:

        # FIXME: If we knew the arena's mesh we could test if we are landing on a wall or something

        forward = normalize(xy(
            car.vel)) if norm(xy(car.vel)) > 20 else car.forward
        up = Vec3(z=1)
        left = cross(up, forward)

        return Mat33.from_columns(forward, left, up)
Beispiel #16
0
 def pick_pad(self, bot, pads: List[BoostPad]):
     # Find closest boost pad
     my_pos = bot.info.my_car.pos
     shortest_dist = 99999999
     for pad in pads:
         if pad.is_active:
             dist = norm(my_pos - pad.pos)
             if dist < shortest_dist:
                 self.target_pad = pad
                 shortest_dist = dist
Beispiel #17
0
def index_of_teammate_at_kickoff_spawn(bot, loc):
    """
    Returns index of teammate at loc, or -1 if there is no teammate
    """
    # RLU Cars does not contain index, so we have to find that ourselves :(
    for car in bot.info.teammates:
        dist = norm(car.pos - loc)
        if dist < 150:
            return car.index
    return -1
Beispiel #18
0
    def exec(self, bot) -> SimpleControllerState:
        car = bot.info.my_car

        car_to_pad = self.boost_pad_pos - car.pos
        vel = proj_onto_size(car.vel, car_to_pad)
        dist = norm(car_to_pad)
        if dist < vel * 0.3:
            self.done = True

        # Drive towards the pad
        return bot.drive.towards_point(bot, self.boost_pad_pos, target_vel=2300, boost_min=0, can_keep_speed=True)
Beispiel #19
0
    def utility(self, bot) -> float:
        team_sign = bot.info.team_sign
        ball = bot.info.ball

        ball_to_goal = bot.info.own_goal - ball.pos
        too_close = norm(ball_to_goal) < Field.GOAL_WIDTH / 2 + Ball.RADIUS

        hits_goal_prediction = predict.will_ball_hit_goal(bot)
        hits_goal = hits_goal_prediction.happens and sign(
            ball.vel.y) == team_sign and hits_goal_prediction.time < 3

        return hits_goal or too_close
Beispiel #20
0
    def run(self, bot) -> SimpleControllerState:
        self.is_dribbling = True

        car = bot.info.my_car
        ball = bot.info.ball
        ball_landing = predict.next_ball_landing(bot)
        ball_to_goal = bot.info.opp_goal.pos - ball.pos

        # Decide on target pos and speed
        target = ball_landing.data["obj"].pos - self.offset_bias * normalize(
            ball_to_goal)
        dist = norm(target - bot.info.my_car.pos)
        speed = 1400 if ball_landing.time == 0 else dist / ball_landing.time

        # Do a flick?
        car_to_ball = ball.pos - car.pos
        dist = norm(car_to_ball)
        enemy, enemy_dist = bot.info.closest_enemy(ball.pos)
        if dist <= self.required_distance_to_ball_for_flick:
            self.flick_timer += bot.info.dt
            if self.flick_timer > self.wait_before_flick and enemy_dist < 900:
                bot.maneuver = DodgeManeuver(
                    bot,
                    bot.info.opp_goal.pos)  # use flick_init_jump_duration?
        else:
            self.flick_timer = 0

        if bot.do_rendering:
            bot.renderer.draw_line_3d(car.pos, target, bot.renderer.pink())

        return bot.drive.towards_point(bot,
                                       target,
                                       target_vel=speed,
                                       slide=False,
                                       can_keep_speed=False,
                                       can_dodge=True,
                                       wall_offset_allowed=0)
Beispiel #21
0
def sdf_wall_dist(point: Vec3) -> float:
    """
    Returns the distance to the nearest wall of using an SDF approximation.
    The result is negative if the point is outside the arena.
    """

    # SDF box https://www.youtube.com/watch?v=62-pRVZuS5c
    # SDF rounded corners https://www.youtube.com/watch?v=s5NGeUV2EyU

    ONES = Vec3(1, 1, 1)

    # Base cube
    base_q = abs(point -
                 Vec3(z=Field.HEIGHT / 2)) - SEMI_SIZE + ONES * ROUNDNESS
    base_dist_outside = norm(vec_max(base_q, Vec3()))
    base_dist_inside = min(max_comp(base_q), 0)
    base_dist = base_dist_outside + base_dist_inside

    # Corners cube
    corner_q = abs((dot(ROT_45_MAT, point)) - Vec3(
        z=Field.HEIGHT / 2)) - CORNER_SEMI_SIZE + ONES * ROUNDNESS
    corner_dist_outside = norm(vec_max(corner_q, Vec3()))
    corner_dist_inside = min(max_comp(corner_q), 0)
    corner_dist = corner_dist_outside + corner_dist_inside

    # Intersection of base and corners
    base_corner_dist = max(base_dist, corner_dist) - ROUNDNESS

    # Goals cube
    goals_q = abs(point - Vec3(z=Field.GOAL_HEIGHT /
                               2)) - GOALS_SEMI_SIZE + ONES * ROUNDNESS
    goals_dist_outside = norm(vec_max(goals_q, Vec3()))
    goals_dist_inside = min(max_comp(goals_q), 0)
    goals_dist = base_dist_outside + base_dist_inside

    # Union with goals and invert result
    return -min(base_corner_dist, goals_dist)
Beispiel #22
0
    def get_boost_pad_convenience_score(self, pad):
        if not pad.is_active:
            return 0

        car_to_pad = pad.pos - self.my_car.pos
        angle = angle_between(self.my_car.forward, car_to_pad)

        # Pads behind the car is bad
        if abs(angle) > 1.3:
            return 0

        dist = norm(car_to_pad)

        dist_score = 1 - clip((abs(dist) / 2500)**2, 0, 1)
        angle_score = 1 - clip((abs(angle) / 3), 0, 1)

        return dist_score * angle_score * (0.8, 1)[pad.is_big]
Beispiel #23
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)
Beispiel #24
0
    def utility_score(self, bot) -> float:
        team_sign = bot.info.team_sign
        ball = bot.info.ball

        ball_to_goal = bot.info.own_goal.pos - ball.pos
        too_close = norm(ball_to_goal) < Goal.WIDTH2 + Ball.RADIUS

        hits_goal_prediction = predict.will_ball_hit_goal(bot)
        hits_goal = hits_goal_prediction.happens and sign(
            ball.vel.y) == team_sign and hits_goal_prediction.time < 3

        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 float(hits_goal or too_close) * obj_bonus
Beispiel #25
0
    def find_landing_orientation(car: Car, num_points: int) -> Mat33:
        dummy = DummyObject(car)

        for i in range(0, num_points):
            fall(dummy,
                 0.0333)  # Apply physics and let car fall through the air

            if i > 5 and sdf_contains(dummy.pos):
                up = normalize(sdf_normal(dummy.pos))
                left = cross(normalize(dummy.vel), up)
                forward = cross(up, left)

                return Mat33.from_columns(forward, left, up)

        forward = normalize(xy(
            car.vel)) if norm(xy(car.vel)) > 20 else car.forward
        up = Vec3(z=1)
        left = cross(up, forward)

        return Mat33.from_columns(forward, left, up)
Beispiel #26
0
    def exec(self, bot) -> SimpleControllerState:
        car = bot.info.my_car

        # Somehow we didn't find a good pad
        if self.closest_pad is None:
            self.done = True
            return SimpleControllerState()

        # End maneuver when almost there or pad becomes inactive
        car_to_pad = self.closest_pad.pos - car.pos
        vel = proj_onto_size(car.vel, car_to_pad)
        dist = norm(car_to_pad)
        if dist < 50 + vel * 0.2 or car.boost > 50 or not self.closest_pad.is_active:
            self.done = True

        bot.renderer.draw_line_3d(car.pos, self.closest_pad.pos,
                                  bot.renderer.yellow())
        return bot.drive.go_towards_point(bot,
                                          self.closest_pad.pos,
                                          target_vel=2200,
                                          slide=True,
                                          boost_min=0,
                                          can_dodge=self.closest_pad.is_big)
Beispiel #27
0
    def stay_at(self, bot, point: Vec3, looking_at: Vec3):

        OKAY_DIST = 100

        car = bot.info.my_car
        car_to_point = point - car.pos
        car_to_point_dir = normalize(point - car.pos)
        dist = norm(car_to_point)

        if dist > OKAY_DIST:
            return self.towards_point(bot, point, int(dist * 2))
        else:
            look_dir = normalize(looking_at - car.pos)
            facing_correctly = dot(car.forward, look_dir) > 0.9
            if facing_correctly:
                return SimpleControllerState()
            else:
                ctrls = SimpleControllerState()
                ctrls.throttle = 0.7 * sign(dot(car.forward, car_to_point_dir))
                ctrls.steer = -ctrls.throttle * sign(
                    dot(car.left, car_to_point_dir))

                return ctrls
Beispiel #28
0
    def go_home(self, bot):
        car = bot.info.my_car
        home = bot.info.own_goal
        target = home

        closest_enemy, enemy_dist = bot.info.closest_enemy(bot.info.ball.pos)

        car_to_home = home - car.pos
        dist = norm(car_to_home)
        vel_f_home = proj_onto_size(car.vel, car_to_home)

        if vel_f_home * 2 > dist:
            target = bot.info.ball.pos

        boost = 40 - (dist / 100) + enemy_dist / 200
        dodge = dist > 1500 or enemy_dist < dist

        return self.go_towards_point(bot,
                                     target,
                                     2300,
                                     True,
                                     boost_min=boost,
                                     can_dodge=dodge)
Beispiel #29
0
    def exec(self, bot):

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

        car_to_ball = ball.pos - car.pos
        ball_to_enemy_goal = bot.info.enemy_goal - ball.pos
        own_goal_to_ball = ball.pos - bot.info.own_goal
        dist = norm(car_to_ball)

        offence = ball.pos.y * bot.info.team_sign < 0
        dot_enemy = dot(car_to_ball, ball_to_enemy_goal)
        dot_own = dot(car_to_ball, own_goal_to_ball)
        right_side_of_ball = dot_enemy > 0 if offence else dot_own > 0

        if right_side_of_ball:
            # Aim cone
            dir_to_post_1 = (bot.info.enemy_goal +
                             Vec3(3800, 0, 0)) - bot.info.ball.pos
            dir_to_post_2 = (bot.info.enemy_goal +
                             Vec3(-3800, 0, 0)) - bot.info.ball.pos
            cone = AimCone(dir_to_post_1, dir_to_post_2)
            cone.get_goto_point(bot, car.pos, bot.info.ball.pos)
            if bot.do_rendering:
                cone.draw(bot, bot.info.ball.pos)

            # Chase ball
            return bot.drive.go_towards_point(bot,
                                              xy(ball.pos),
                                              2000,
                                              True,
                                              True,
                                              can_dodge=dist > 2200)
        else:
            # Go home
            return bot.drive.go_towards_point(bot, bot.info.own_goal_field,
                                              2000, True, True)
Beispiel #30
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