Example #1
0
    def boost_steal(self, controls, car_location, my_car, ball_location):
        active_boosts = [
            boost for boost in self.boost_pad_tracker.get_full_boosts()
            if boost.is_active == True
        ]
        car_x = int(car_location.x)
        car_y = int(car_location.y)

        boost_distances = []

        for boost in active_boosts:
            boost_x = int(boost.location.x)
            boost_y = int(boost.location.y)

            distance_from_boost = abs(boost_x - car_x) + abs(boost_y - car_y)
            boost_distances.append(distance_from_boost)

        if len(active_boosts) == 0:
            controls.steer = steer_toward_target(my_car, ball_location)
            controls.throttle = 1.0
        else:
            boost_index = boost_distances.index(min(boost_distances))
            boost_location = active_boosts[boost_index].location

            controls.steer = steer_toward_target(my_car, boost_location)
            controls.throttle = 1.0
Example #2
0
 def goalie():
     target_location = car_location
     # Roll back onto the wheels
     if abs(car_rotation.roll) >= math.pi * 3 / 4:
         override = self.jump_once(packet)
     # Prepare for a save
     if sign(car_location.y) == -sign(send_location.y) and abs(
             car_location.y) >= abs(send_location.y):
         target_location = car_location - Vec3(0, send_location.y, 0)
         if car_velocity.length() >= 850:
             controls.throttle = -1
         else:
             if Vec3(car_velocity.x, car_velocity.y, 0).length() >= 250:
                 override = self.reverse_flip(packet)
             else:
                 controls.pitch = 0
                 controls.roll = 0
                 if (not math.pi * 0.4 <= abs(car_rotation.yaw) <=
                         math.pi * 0.6 or sign(car_rotation.yaw)
                         == -sign(send_location.y)) and abs(
                             car_velocity.z) <= 1:
                     override = self.jump_once(packet)
                 controls.yaw = clamp(
                     steer_toward_target(my_car, send_location) -
                     my_car.physics.angular_velocity.z, -1, 1)
             controls.throttle = 0
     # Drive into the goal unless it's already done so
     else:
         target_location = defend()
     return target_location
Example #3
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        """
        This function will be called by the framework many times per second. This is where you can
        see the motion of the ball, etc. and return controls to drive your car.
        """

        # This is good to keep at the beginning of get_output. It will allow you to continue
        # any sequences that you may have started during a previous call to get_output.
        if self.active_sequence and not self.active_sequence.done:
            return self.active_sequence.tick(packet)

        self.spike_watcher.read_packet(packet)
        ball_prediction = self.get_ball_prediction_struct()

        # Example of predicting a goal event
        predicted_goal = find_future_goal(ball_prediction)
        goal_text = "No Goal Threats"
        if predicted_goal:
            goal_text = f"Goal in {predicted_goal.time - packet.game_info.seconds_elapsed:.2f}s"

        my_car = packet.game_cars[self.index]
        car_velocity = Vec3(my_car.physics.velocity)

        # Example of using a sequence
        # This will do a front flip if the car's velocity is between 550 and 600
        if 550 < car_velocity.length() < 600:
            self.active_sequence = Sequence([
                ControlStep(0.05, SimpleControllerState(jump=True)),
                ControlStep(0.05, SimpleControllerState(jump=False)),
                ControlStep(0.2, SimpleControllerState(jump=True, pitch=-1)),
                ControlStep(0.8, SimpleControllerState()),
            ])
            return self.active_sequence.tick(packet)

        # Example of using the spike watcher.
        # This will make the bot say I got it! when it spikes the ball,
        # then release it 2 seconds later.
        if self.spike_watcher.carrying_car == my_car:
            if self.spike_watcher.carry_duration == 0:
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Information_IGotIt)
            elif self.spike_watcher.carry_duration > 2:
                return SimpleControllerState(use_item=True)

        # Example of doing an aerial. This will cause the car to jump and fly toward the
        # ceiling in the middle of the field.
        if my_car.boost > 50 and my_car.has_wheel_contact:
            self.start_aerial(Vec3(0, 0, 2000),
                              packet.game_info.seconds_elapsed + 4)

        # If nothing else interesting happened, just chase the ball!
        ball_location = Vec3(packet.game_ball.physics.location)
        self.controller_state.steer = steer_toward_target(
            my_car, ball_location)
        self.controller_state.throttle = 1.0

        # Draw some text on the screen
        draw_debug(self.renderer, [goal_text])

        return self.controller_state
Example #4
0
 def demo():
     nearest = None
     best_time = math.inf
     last = True
     for i in range(len(packet.game_cars)):
         if packet.game_cars[i].team != self.team and Vec3(
                 packet.game_cars[i].physics.location).z > 0:
             time_taken = (Vec3(packet.game_cars[i].physics.location) -
                           car_location).length()
             if time_taken < best_time:
                 best_time = time_taken
                 nearest = packet.game_cars[i]
     # Get location
     target_location = Vec3(
         nearest.physics.location) + Vec3(nearest.physics.velocity) * (
             (Vec3(nearest.physics.location) - car_location).length() -
             30) * safe_div(car_velocity.length())
     controls.throttle = 1
     controls.boost = abs(steer_toward_target(
         my_car,
         target_location)) <= 0.1 and car_velocity.length() < 2200
     self.renderer.draw_line_3d(car_location, target_location,
                                self.renderer.black())
     self.renderer.draw_rect_3d(target_location,
                                8,
                                8,
                                True,
                                self.renderer.black(),
                                centered=True)
     return target_location
Example #5
0
 def move_towards_point(self, my_car, point, boost: bool) -> SimpleControllerState:
      # Set the final controls based off of above decision making
     controls = SimpleControllerState()
     controls.steer = steer_toward_target(my_car, point)
     controls.throttle = 1.0
     if boost:
         controls.boost = True
     return controls
Example #6
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        """
        This function will be called by the framework many times per second. This is where you can
        see the motion of the ball, etc. and return controls to drive your car.
        """

        # Keep our boost pad info updated with which pads are currently active
        self.boost_pad_tracker.update_boost_status(packet)

        # This is good to keep at the beginning of get_output. It will allow you to continue
        # any sequences that you may have started during a previous call to get_output.
        if self.active_sequence is not None and not self.active_sequence.done:
            controls = self.active_sequence.tick(packet)
            if controls is not None:
                return controls

        # Gather some information about our car and the ball
        my_car = packet.game_cars[self.index]
        car_location = Vec3(my_car.physics.location)
        car_velocity = Vec3(my_car.physics.velocity)
        ball_location = Vec3(packet.game_ball.physics.location)
        nearest_boost_loc = self.get_nearest_boost(car_location)

        # By default we will chase the ball, but target_location can be changed later
        target_location = nearest_boost_loc

        # if car_location.dist(ball_location) > 1500:
        #     # We're far away from the ball, let's try to lead it a little bit
        #     ball_prediction = self.get_ball_prediction_struct()  # This can predict bounces, etc
        #     ball_in_future = find_slice_at_time(ball_prediction, packet.game_info.seconds_elapsed + 2)
        #
        #     # ball_in_future might be None if we don't have an adequate ball prediction right now, like during
        #     # replays, so check it to avoid errors.
        #     if ball_in_future is not None:
        #         target_location = Vec3(ball_in_future.physics.location)
        #         self.renderer.draw_line_3d(ball_location, target_location, self.renderer.cyan())

        # Draw some things to help understand what the bot is thinking
        self.renderer.draw_line_3d(car_location, target_location, self.renderer.white())
        self.renderer.draw_string_3d(car_location, 1, 1, f'Speed: {car_velocity.length():.1f}', self.renderer.white())
        self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True)

        if 750 < car_velocity.length() < 800:
            # We'll do a front flip if the car is moving at a certain speed.
            return self.begin_front_flip(packet)

        controls = SimpleControllerState()
        controls.steer = steer_toward_target(my_car, target_location)
        controls.throttle = 1.0
        controls.boost = True
        controls.handbrake = True
        # You can set more controls if you want, like controls.boost.

        return controls
Example #7
0
    def go_towards_own_goal(self, controls, my_car, car_location, ball_location):
        """
        Goes towards own goal and changes back to ball chasing when a bit away from the ball
        """
        self.renderer.draw_string_3d(car_location, 1, 1, "\nGoing towards own goal", self.renderer.red())
        info = self.get_field_info()
        own_goal_vec = info.goals[self.team].location
        own_goal_location = Vec3(own_goal_vec)
        controls.steer = steer_toward_target(my_car, own_goal_location)
        controls.throttle = 1.0

        # goes back to ball chase state if far enough away from the ball
        if car_location.dist(ball_location) > 1000 or car_location.dist(own_goal_location) < 4000:
            self.bot_state = 0
Example #8
0
    def ball_chase(self, controls, my_car, car_location, car_velocity,
                   ball_location, packet):
        if car_location.dist(ball_location) > 1500:
            # We're far away from the ball, let's try to lead it a little bit
            ball_prediction = self.get_ball_prediction_struct(
            )  # This can predict bounces, etc
            ball_in_future = find_slice_at_time(
                ball_prediction, packet.game_info.seconds_elapsed + 2)
            target_location = Vec3(ball_in_future.physics.location)
            self.renderer.draw_line_3d(ball_location, target_location,
                                       self.renderer.cyan())
        else:
            target_location = ball_location

        controls.steer = steer_toward_target(my_car, ball_location)
        controls.throttle = 1.0
        self.manage_speed(packet, controls, my_car, car_velocity)
Example #9
0
    def front_flip_kickoff(self, my_car, car_location, car_velocity,
                           ball_location, controls, packet):
        self.send_quick_chat(
            team_only=False,
            quick_chat=QuickChatSelection.Information_Incoming)
        controls.steer = steer_toward_target(my_car, ball_location)
        controls.throttle = 1.0
        controls.boost = True

        distance_from_ball = car_location.dist(ball_location)

        # tweak these settings so the first and second flips go off at the right time
        if 750 < car_velocity.length() < 900:
            self.begin_front_flip(packet)

        if distance_from_ball <= 1000:
            self.begin_front_flip(packet)
Example #10
0
    def retreat_to_goal(self, controls, packet, my_car, car_location, car_velocity):
        """
        Makes the bot retreat back to the goal and only change back to another state when it's close to the goal
        """
        self.renderer.draw_string_3d(car_location, 1, 1, "\nRetreating to goal", self.renderer.red())
        info = self.get_field_info()
        own_goal_vec = info.goals[self.team].location
        own_goal_location = Vec3(own_goal_vec)
        controls.steer = steer_toward_target(my_car, own_goal_location)
        controls.throttle = 1.0

        if not my_car.is_super_sonic and car_velocity.length() > 200 and car_location.dist(own_goal_location) > 4500:
            controls.boost = True

        # change back to ball chasing if distance to goal is small
        self.renderer.draw_string_3d(car_location, 1, 1, f"\n\nDist to goal {car_location.dist(own_goal_location)}", self.renderer.white())
        if car_location.dist(own_goal_location) < 4000:
            self.bot_state = 0
Example #11
0
    def ball_chase(self, controls, packet, my_car, car_velocity, car_location, target_location, ball_location, relative, time_to_target, time_to_floor, orientation):
        """
        Makes the bot chase the ball unless some conditions are valid
        """

        # retreat to own goal if the ball is a lot closer to our goal than we are
        info = self.get_field_info()
        own_goal_vec = info.goals[self.team].location
        own_goal_location = Vec3(own_goal_vec)

        if ball_location.dist(own_goal_location) + 1000 < car_location.dist(own_goal_location) and car_location.dist(own_goal_location) > 4000:
            self.bot_state = 1
        elif own_goal_vec.y > 5000 and car_location.y + 100 < target_location.y:  # BLUE
            self.bot_state = 2
        elif own_goal_vec.y < -5000 and car_location.y > target_location.y + 100:  # ORANGE
            self.bot_state = 2

        self.renderer.draw_string_3d(car_location, 1, 1, "\nBall chasing", self.renderer.red())

        # makes the bots shoot towards the goal
        target_location = self.ball_towards_goal_location(target_location, own_goal_location, car_location, ball_location)
        self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.red(), centered=True)
        self.renderer.draw_line_3d(car_location, target_location, self.renderer.red())

        controls.steer = steer_toward_target(my_car, target_location)
        controls.throttle = 1.0
        # You can set more controls if you want, like controls.boost.

        # angle to ball
        car_to_ball = Vec3(ball_location.x - car_location.x, ball_location.y - car_location.y, ball_location.z - car_location.z)
        angle = math.degrees(orientation.forward.ang_to(car_to_ball))

        # boost
        if angle < 20 and not my_car.is_super_sonic:
            controls.boost = True

        # try to turn around quickly
        if angle > 160 and relative.x < -2000:
            self.begin_half_flip(packet)
        elif angle > 40:
            controls.handbrake = True
        elif 1000 < car_velocity.length() and angle < 90 and car_to_ball.length() < 400 and relative.z < 200:
            # We'll do a front flip if the car is moving at a certain speed.
            return self.begin_front_flip(packet, angle, orientation.right.length())
Example #12
0
    def tick(self, packet: GameTickPacket) -> StepResult:
        car = packet.game_cars[self.index]

        seconds_till_arrival = self.arrival_time - packet.game_info.seconds_elapsed
        if seconds_till_arrival <= 0:
            return StepResult(SimpleControllerState(), done=True)
        current_speed = Vec3(car.physics.velocity).length()
        avg_speed_needed = Vec3(car.physics.location).flat().dist(
            self.target.flat()) / seconds_till_arrival

        steering = steer_toward_target(car, self.target)
        controls = SimpleControllerState(
            steer=steering,
            throttle=1 if avg_speed_needed > current_speed else 0,
            boost=avg_speed_needed > current_speed
            and avg_speed_needed > MAX_SPEED_WITHOUT_BOOST)

        ready_to_jump = abs(
            steering) < 0.1 and current_speed / avg_speed_needed > 0.7

        return StepResult(controls, done=ready_to_jump)
Example #13
0
  def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

    # Get currently active boost pad info
    self.boost_pad_tracker.update_boost_status(packet)

    # Continue sequences from previous call
    if self.active_sequence and not self.active_sequence.done:
      controls = self.active_sequence.tick(packet)
      if controls is not None: return controls

    # Gather information about car and ball
    my_car = packet.game_cars[self.index]
    car_location = Vec3(my_car.physics.location)
    car_velocity = Vec3(my_car.physics.velocity)
    ball_location = Vec3(packet.game_ball.physics.location)

    if car_location.dist(ball_location) > 1500:
      # Set path of car to future ball location
      ball_prediction = self.get_ball_prediction_struct()  # This can predict bounces, etc
      ball_in_future = find_slice_at_time(ball_prediction, packet.game_info.seconds_elapsed + 2)
      target_location = Vec3(ball_in_future.physics.location)
      self.renderer.draw_line_3d(ball_location, target_location, self.renderer.cyan())
    else:
      target_location = ball_location

    # Draw rendering lines
    self.renderer.draw_line_3d(car_location, target_location, self.renderer.white())
    self.renderer.draw_string_3d(car_location, 1, 1, f'Speed: {car_velocity.length():.1f}', self.renderer.white())
    self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True)

    # Front flip if car is moving at a certain speed
    if 750 < car_velocity.length() < 800: return self.begin_front_flip(packet)

    controls = SimpleControllerState()
    controls.steer = steer_toward_target(my_car, target_location)
    controls.throttle = 1.0

    return controls
Example #14
0
    def get_controls(self, car_state: CarState, car: Car):
        controls = SimpleControllerState()
        target_Vec3 = Vec3(self.location[0], self.location[1],
                           self.location[2])

        if angle_between(self.location - to_vec3(car_state.physics.location),
                         car.forward()) > pi / 2:
            controls.boost = False
            controls.handbrake = True
        elif angle_between(self.location - to_vec3(car_state.physics.location),
                           car.forward()) > pi / 4:
            controls.boost = False
            controls.handbrake = False
        else:
            controls.boost = self.boost
            controls.handbrake = False

        # Be smart about not using boost at max speed
        # if Vec3(car.physics.velocity).length() > self.boost_analysis.frames[-1].speed - 10:
        #     controls.boost = False

        controls.steer = steer_toward_target(car_state, target_Vec3)
        controls.throttle = 1
        return controls
Example #15
0
    def get_output(self, parsed_packet: ParsedPacket, packet: rl.GameTickPacket, agent: DrawingAgent) -> SimpleControllerState:
         # Gather some information about our car and the ball
        my_car = parsed_packet.my_car
        car_location = my_car.physics.location
        car_velocity = my_car.physics.velocity
        ball_location = parsed_packet.ball.physics.location
        ball_velocity = parsed_packet.ball.physics.velocity
        ball_prediction = agent.get_ball_prediction_struct()
        slices = list(map(lambda x : Vector(x.physics.location), ball_prediction.slices))

        agent.draw_circle(parsed_packet.my_car.physics.location, self.STOP_AND_WAIT_RADIUS, agent.renderer.white(), False, 0)

        

        my_car_ori = Orientation(my_car.physics.rotation)
        car_to_ball = ball_location - car_location
        car_to_ball_angle = my_car_ori.forward.ang_to(car_to_ball)

        self.chooseContactPoint(ball_prediction.slices, my_car.physics, agent)
        
        if(self.contactSlice == None):
            flip_point = Vector(find_slice_at_time(ball_prediction, packet.game_info.seconds_elapsed + 1).physics.location)
        else:
            flip_point = Vector(self.contactSlice.physics.location)
        target_location = flip_point

        if not agent.prev_seq_done and agent.WRITE_FLIP_PHYSICS_TO_DB:
            agent.prev_seq_done = True
            agent.write_flip_physics(agent.current_flip_physics)

        if car_location.dist(flip_point) < 300 and self.contactSlice != None:
            if agent.WRITE_FLIP_PHYSICS_TO_DB == True:
                # record physics info at beginning of flip
                agent.current_flip_physics = {}

                # TODO: add slices here

                
                agent.current_flip_physics["car_ball_angle"] = car_to_ball_angle
                agent.current_flip_physics["car_ball_dist"] = car_location.dist(ball_location)
                

                agent.current_flip_physics["car_velo_x"] = car_velocity[0]
                agent.current_flip_physics["car_velo_y"] = car_velocity[1]
                agent.current_flip_physics["car_velo_z"] = car_velocity[2]
                agent.current_flip_physics["car_velo_mag"] = car_velocity.length()

                agent.current_flip_physics["car_loc_x"] = car_location[0]
                agent.current_flip_physics["car_loc_y"] = car_location[1]
                agent.current_flip_physics["car_loc_z"] = car_location[2]

                agent.current_flip_physics["ball_velo_x"] = ball_velocity[0]
                agent.current_flip_physics["ball_velo_y"] = ball_velocity[1]
                agent.current_flip_physics["ball_velo_z"] = ball_velocity[2]
                agent.current_flip_physics["ball_velo_mag"] = ball_velocity.length()
                
                agent.current_flip_physics["ball_loc_x"] = ball_location[0]
                agent.current_flip_physics["ball_loc_y"] = ball_location[1]
                agent.current_flip_physics["ball_loc_z"] = ball_location[2]

                agent.current_flip_physics["contact"] = False

            return agent.begin_front_flip(packet)

        # Draw target to show where the bot is attempting to go
        if (self.contactSlice == None):
            agent.draw_line_with_rect(car_location, target_location, 8, agent.renderer.cyan())
        else:
            contactPt = Vector(self.contactSlice.physics.location)
            agent.draw_line_with_rect(contactPt, contactPt + get_post_collision_velocity(my_car.physics, Physics(self.contactSlice.physics)), 1, agent.renderer.red())

        angle = get_angle(parsed_packet.my_car.physics.rotation, parsed_packet.my_car.physics.location, target_location)
        agent.write_string_2d(1000, 1000, f"{angle}")

        # Set the final controls based off of above decision making
        controls = SimpleControllerState()
        controls.steer = steer_toward_target(my_car, target_location)

        if(self.contactSlice != None or car_location.dist(ball_location) > self.STOP_AND_WAIT_RADIUS):
            controls.throttle = 1.0
        else:
            controls.throttle = -1

        if (angle > self.POWERSLIDE_THRESHOLD):
            controls.handbrake = True

        # You can set more controls if you want, like controls.boost.
        return controls
Example #16
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        self.boost_pad_tracker.update_boost_status(packet)

        if self.active_sequence is not None and not self.active_sequence.done:
            controls = self.active_sequence.tick(packet)
            if controls is not None:
                return controls
        # Get the distance from the nearest surface (walls, floor, roof, etc.)
        def distance_from_surface(pos):
            min_dist = math.inf
            nearest_surface = pos
            if min_dist > pos.z:
                min_dist = pos.z
                nearest_surface = Vec3(pos.x, pos.y, 0)
            if min_dist > self.map_size[1] - abs(pos.x):
                min_dist = self.map_size[1] - abs(pos.x)
                nearest_surface = Vec3(
                    sign(pos.x) * self.map_size[1], pos.y, pos.z)
            if min_dist > self.map_size[0] - abs(pos.y):
                min_dist = self.map_size[0] - abs(pos.y)
                nearest_surface = Vec3(pos.x,
                                       sign(pos.y) * self.map_size[0], pos.z)
            if min_dist > 99999 + (8064 - abs(pos.x) -
                                   abs(pos.y)) / math.sqrt(2):
                min_dist = (8064 - abs(pos.x) - abs(pos.y)) / math.sqrt(2)
                nearest_surface = Vec3(pos.x,
                                       sign(pos.y) * self.map_size[0], pos.z)
            return nearest_surface

        # Get the rate in which the object is moving away from the nearest surface
        def velocity_from_surface(pos, vel):
            val = pos - distance_from_surface(pos)
            if val.x != 0:
                return vel.x * sign(val.x)
            elif val.y != 0:
                return vel.y * sign(val.y)
            elif val.z != 0:
                return vel.z * sign(val.z)

        # Get the order within the team
        def distance_order(teams):
            nearest = 1
            overall_nearest = 1
            last = 0
            ref = (car_location - ball_location).length(
            ) / (car_velocity.length() + 2300) + math.asin(
                (car_velocity * safe_div(car_velocity.length()) -
                 ball_location * safe_div(ball_location.length())).length() /
                2) * 3 / math.pi * 0
            for i in range(len(packet.game_cars)):
                if (packet.game_cars[i].team !=
                    (-teams * packet.game_cars[self.index].team +
                     (1 + teams) / 2) or teams == False
                    ) and packet.game_cars[i].physics.location.z > 0:
                    time_taken = (
                        Vec3(packet.game_cars[i].physics.location) -
                        ball_location).length() / (Vec3(packet.game_cars[
                            i].physics.velocity).length() + 2300) + math.asin(
                                (Vec3(packet.game_cars[i].physics.velocity) *
                                 safe_div(
                                     Vec3(packet.game_cars[i].physics.velocity
                                          ).length()) - ball_location *
                                 safe_div(ball_location.length())).length() /
                                2) * 3 / math.pi * 0
                    # When the car is further front than the POV
                    if ref > time_taken:
                        if ((Vec3(packet.game_cars[i].physics.location) +
                             send_location).length() <=
                            (ball_location + send_location).length()
                                or (car_location + send_location).length() >
                            (ball_location + send_location).length()):
                            nearest += 1
                        overall_nearest += 1
                    last += 1
            # Keep the full-time goal keeper
            if overall_nearest == last:
                nearest = overall_nearest
            # Prevent the division by 0 error
            return last, nearest

        # Find the best boost pads to use to refuel as fast as possible
        def find_best_boost_pads():
            best_pad = None
            best_score = math.inf
            for i in range(len(self.get_field_info().boost_pads)):
                pad = self.get_field_info().boost_pads[i]
                if packet.game_boosts[
                        i].is_active == True or packet.game_boosts[i].timer <= (
                            Vec3(pad.location) - car_location).length() / 2300:
                    score = (Vec3(pad.location) - car_location).length(
                    ) * safe_div(car_velocity.length()) + math.sin(
                        ((Vec3(pad.location) - car_location) /
                         (Vec3(pad.location) - car_location).length() -
                         car_velocity * safe_div(car_velocity.length())
                         ).length() / 2) * 3 / math.pi
                    if pad.is_full_boost:
                        score *= safe_div((50 - my_car.boost / 2) / 6)
                    if score < best_score:
                        best_score = score
                        best_pad = pad
            return Vec3(best_pad.location)

        # Get the yaw based on position
        def get_yaw(x, y):
            a = math.acos(x / Vec3(x, y, 0).length())
            if abs(a) < math.pi:
                return a * sign(y)
            else:
                return math.pi

        # Get the angle between two places
        def get_angle(p1, p2):
            d = (p1 * safe_div(p1.length()) -
                 p2 * safe_div(p2.length())).length()
            angle = 2 * math.asin(d / 2)
            return angle

        # Determine when the car would intersect the ball assuming a speed
        def intersect_time(surface):
            t1 = 5
            t2 = 5
            best_spd = math.inf
            slowest = math.inf
            if surface == False:
                for i in range(1, 101):
                    time_location = Vec3(predict_ball(i / 20).physics.location)
                    if (time_location - car_location).length(
                    ) * 20 / i <= car_velocity.length() and t1 == 5:
                        t1 = i / 20
                    if (time_location -
                            car_location).length() * 20 / i <= slowest:
                        slowest = (time_location -
                                   car_location).length() * 20 / i
                        t2 = i / 20
            else:
                for i in range(1, 101):
                    time_location = Vec3(predict_ball(i / 20).physics.location)
                    if (distance_from_surface(time_location) -
                            distance_from_surface(car_location)).length(
                            ) * 20 / i <= car_velocity.length() and t1 == 5:
                        t1 = i / 20
                    if (distance_from_surface(time_location) -
                            distance_from_surface(car_location)
                        ).length() * 20 / i <= slowest:
                        slowest = (distance_from_surface(time_location) -
                                   distance_from_surface(car_location)
                                   ).length() * 20 / i
                        t2 = i / 20

            return t1, t2

        # Determine when the car should jump
        def jump_ready(val):
            if val <= 300 and val > 92.75:
                delay = (2 * (val - 92.75) / 650)**0.5
                return delay
            else:
                return 0

        # Get the nearest player to the ball
        def nearest_player(teams, speed_offset):
            nearest = None
            best_time = math.inf
            last = True
            for i in range(len(packet.game_cars)):
                if (packet.game_cars[i].team !=
                    (-teams * packet.game_cars[self.index].team +
                     (1 + teams) / 2) or teams == False) and Vec3(
                         packet.game_cars[i].physics.location) != Vec3(
                             0, 0, 0):
                    time_taken = (Vec3(
                        packet.game_cars[i].physics.location
                    ) - ball_location).length() / (Vec3(
                        packet.game_cars[i].physics.velocity
                    ).length() + speed_offset) + math.sin(
                        (Vec3(packet.game_cars[i].physics.velocity) * safe_div(
                            Vec3(packet.game_cars[i].physics.velocity).length(
                            )) - ball_location *
                         safe_div(ball_location.length())).length() /
                        2) * 3 / math.pi
                    if time_taken < best_time:
                        best_time = time_taken
                        nearest = packet.game_cars[i]
            return nearest, best_time

        # Get the list of moments when the ball should be hit
        def opportunities():
            li = []
            prev_pos = ball_location
            for i in range(1, 101):
                time_location = predict_ball(i / 20)
                if time_location.z <= 300:
                    li.append([
                        i / 20,
                        (time_location - car_location).length() * 20 / i
                    ])
                prev_pos = time_location
            return li

        # ???
        def plane_dist(pos, dist):
            if Vec3(pos.x, pos.y, 0).length() <= dist:
                return True
            elif Vec3(pos.x, 0, pos.z).length() <= dist:
                return True
            elif Vec3(0, pos.y, pos.z).length() <= dist:
                return True
            else:
                return False

        # Get the ball's position and velocity at a specific time
        def predict_ball(t):
            ball_in_future = find_slice_at_time(
                ball_prediction, packet.game_info.seconds_elapsed + t)
            if ball_in_future is not None:
                return ball_in_future
            else:
                return packet.game_ball

        # Divide numbers without division by 0
        def safe_div(x):
            if x == 0:
                return math.inf
            else:
                return 1 / x

        # Return the direction of the value from 0
        def sign(x):
            if x < 0:
                return -1
            elif x > 0:
                return 1
            else:
                return 0

        # Return a value with limitations
        def clamp(x, m, M):
            if x < m:
                return m
            elif x > M:
                return M
            else:
                return x

        # Move the target location to straighten the ascent up walls
        def move_target_for_walls(pos1, pos2):
            up1 = distance_from_surface(pos1)
            up2 = distance_from_surface(pos2)
            new_pos = pos2
            if up1.z == 0 and up2.z > 0:
                new_pos = Vec3(new_pos, 0, new_pos) + (up2 - pos2) * safe_div(
                    (up2 - pos2).length()) * up2.z
            if up1.z > 0 and up2.z == 0 and pos1.z >= 30:
                if abs(up1.x) == self.map_size[1]:
                    new_pos = Vec3(up1.x, up2.y, -abs(up2.x - up1.x))
                elif abs(up1.y) == self.map_size[0]:
                    new_pos = Vec3(up2.x, up1.y, -abs(up2.y - up1.y))
            return new_pos

        # Actions
        # Use flip jumps to attack the ball
        def jump_attack():
            dir_y = 0
            dir_x = 0
            if ((car_location + car_velocity / 5) -
                (ball_location + ball_velocity / 5)).length() <= 175:
                if (car_location + Vec3(car_velocity.y, -car_velocity.x, 0) *
                        safe_div(car_velocity.length()) -
                        ball_location).length() < (car_location -
                                                   ball_location).length():
                    dir_x = -1
                if (car_location + Vec3(-car_velocity.y, car_velocity.x, 0) *
                        safe_div(car_velocity.length()) -
                        ball_location).length() < (car_location -
                                                   ball_location).length():
                    dir_x = 1
                if (car_location + car_velocity / 5 - ball_location -
                        ball_velocity / 5
                    ).length() <= (car_location - ball_location).length() - 50:
                    dir_y = -1
                dir_x *= sign(math.pi / 2 -
                              get_angle(car_direction, car_velocity))
                dir_y *= sign(math.pi / 2 -
                              get_angle(car_direction, car_velocity))
                override = self.flip(packet, dir_x, dir_y, not my_car.jumped)

        # Jump over cars to prevent collision
        def avoid_bump():
            for i in range(len(packet.game_cars)):
                if i != self.index and packet.game_cars[
                        i].physics.location.z > 0:
                    pos = car_location
                    pos2 = Vec3(packet.game_cars[i].physics.location)
                    vel = car_velocity
                    vel2 = Vec3(packet.game_cars[i].physics.velocity)
                    dist = (pos - pos2).length()
                    on_course = False
                    if dist > 40:
                        if get_angle(pos2 - pos, vel) <= math.tan(
                                math.sqrt(40**2 / (dist**2 - 40**2))):
                            on_course = True
                    else:
                        on_course = True
                    if on_course == True and dist <= 40 + (vel - vel2).length(
                    ) / 2 and (vel.length() <= vel2.length()
                               or packet.game_cars[i].team != self.team):
                        self.jump_once(packet)

        # Modes
        def attack():
            # Target
            target_ball = predict_ball(earliest_intersection)
            target_location = Vec3(target_ball.physics.location)
            target_location = target_location + (
                target_location - send_location) / (
                    target_location - send_location).length() * 92.75
            # Smoother wall transitions
            target_location = move_target_for_walls(car_location,
                                                    target_location)
            jumping = jump_ready(
                (target_location -
                 distance_from_surface(target_location)).length())
            # Manage speed
            if velocity_from_surface(
                    Vec3(target_ball.physics.location),
                    Vec3(target_ball.physics.velocity)) >= 0 or (Vec3(
                        target_ball.physics.location) - distance_from_surface(
                            Vec3(target_ball.physics.location))).length(
                            ) <= 300 or target_ball.physics.location.y * sign(
                                send_location.y) <= -self.map_size[0]:
                controls.throttle = 1
            else:
                controls.throttle = 0
            # Boost
            controls.boost = abs(
                steer_toward_target(my_car, target_location)
            ) <= 0.1 and car_velocity.length() < 2300 and (
                (Vec3(target_ball.physics.location) - distance_from_surface(
                    Vec3(target_ball.physics.location))).length() <= 300
                or velocity_from_surface(Vec3(target_ball.physics.location),
                                         Vec3(target_ball.physics.velocity)) >=
                0) and car_index == 1
            # Jump
            h = (Vec3(target_ball.physics.location) - distance_from_surface(
                Vec3(target_ball.physics.location))).length()
            if jump_ready(
                (Vec3(target_ball.physics.location) -
                 distance_from_surface(Vec3(target_ball.physics.location))
                 ).length()) >= earliest_intersection and steer_toward_target(
                     my_car, target_location) < 1:
                controls.pitch = 0
                controls.yaw = 0
                controls.roll = 0
                controls.jump = True
                controls.boost = False
            else:
                jump_attack()
            # Catch the ball when in the air
            if abs(
                    target_location.z - car_location.z
            ) <= 92.75 * 0.75 and get_angle(
                    target_location - car_location, car_velocity
            ) >= math.atan(
                    200 * safe_div(car_velocity.length())
            ) and my_car.jumped == True and my_car.double_jumped == False and False:
                controls.yaw = sign(
                    (target_location - car_location -
                     Vec3(car_velocity.y, -car_velocity.x, car_velocity.z)
                     ).length() -
                    (target_location - car_location -
                     Vec3(-car_velocity.y, car_velocity.x, car_velocity.z)
                     ).length())
                controls.jump = True
            # Draw
            self.renderer.draw_line_3d(car_location, target_location,
                                       self.renderer.red())
            self.renderer.draw_rect_3d(target_location,
                                       8,
                                       8,
                                       True,
                                       self.renderer.red(),
                                       centered=True)
            return target_location

        def standby():
            # Friendly/enemey
            if enemy_time >= friendly_time + 0.2:
                nearest_ref = nearest_friendly
                md = "friendly"
            else:
                nearest_ref = nearest_enemy
                md = "enemy"
            # Target
            if md == "enemy" or True:
                target_location = ball_location - (
                    Vec3(nearest_ref.physics.location) - ball_location) / (
                        Vec3(nearest_ref.physics.location) -
                        ball_location).length() * (2500 + Vec3(
                            nearest_ref.physics.velocity).length() * 5 / 2.3)
                target_location = Vec3(
                    target_location.x,
                    ball_location.y + (target_location.y - ball_location.y) *
                    sign(target_location.y - ball_location.y) *
                    -sign(send_location.y), target_location.z)
            else:
                target_location = ball_location - (
                    Vec3(nearest_ref.physics.location) - ball_location) / (
                        Vec3(nearest_ref.physics.location) -
                        ball_location).length() * (2500 + Vec3(
                            nearest_ref.physics.velocity).length() * 5 / 2.3)
                target_location = target_location + (
                    target_location - send_location) / (
                        target_location - send_location).length() * 927.5
            # Walls
            if (distance_from_surface(target_location) -
                    target_location).length() <= 300:
                target_location = distance_from_surface(target_location)
                target_location = move_target_for_walls(
                    car_location, target_location)
            else:
                target_location = Vec3(target_location.x, target_location.y, 0)
            # Draw
            self.renderer.draw_line_3d(car_location, target_location,
                                       self.renderer.green())
            self.renderer.draw_rect_3d(target_location,
                                       8,
                                       8,
                                       True,
                                       self.renderer.green(),
                                       centered=True)
            # Manage speed
            controls.boost = False
            controls.throttle = clamp(
                (target_location - car_location).length() / 1000, -1, 1)
            return target_location

        def refuel():
            # Target
            target_location = find_best_boost_pads()
            # Draw
            self.renderer.draw_line_3d(car_location, target_location,
                                       self.renderer.green())
            self.renderer.draw_rect_3d(target_location,
                                       8,
                                       8,
                                       True,
                                       self.renderer.green(),
                                       centered=True)
            # Speed
            controls.throttle = 1
            controls.boost = False
            return target_location

        def goalie():
            target_location = car_location
            # Roll back onto the wheels
            if abs(car_rotation.roll) >= math.pi * 3 / 4:
                override = self.jump_once(packet)
            # Prepare for a save
            if sign(car_location.y) == -sign(send_location.y) and abs(
                    car_location.y) >= abs(send_location.y):
                target_location = car_location - Vec3(0, send_location.y, 0)
                if car_velocity.length() >= 850:
                    controls.throttle = -1
                else:
                    if Vec3(car_velocity.x, car_velocity.y, 0).length() >= 250:
                        override = self.reverse_flip(packet)
                    else:
                        controls.pitch = 0
                        controls.roll = 0
                        if (not math.pi * 0.4 <= abs(car_rotation.yaw) <=
                                math.pi * 0.6 or sign(car_rotation.yaw)
                                == -sign(send_location.y)) and abs(
                                    car_velocity.z) <= 1:
                            override = self.jump_once(packet)
                        controls.yaw = clamp(
                            steer_toward_target(my_car, send_location) -
                            my_car.physics.angular_velocity.z, -1, 1)
                    controls.throttle = 0
            # Drive into the goal unless it's already done so
            else:
                target_location = defend()
            return target_location

        def defend():
            if not in_goal:
                target_ball = predict_ball(earliest_intersection)
                target_location = Vec3(target_ball.physics.location)
                nearest_surface = (target_location - car_location) / (
                    target_location - car_location).length() * 140
                nearest_surface_r = Vec3(-nearest_surface.y, nearest_surface.x,
                                         nearest_surface.z)
                nearest_surface_l = Vec3(nearest_surface.y, -nearest_surface.x,
                                         nearest_surface.z)
                if False:
                    side = -sign((nearest_surface_l - send_location).length() -
                                 (nearest_surface_r - send_location).length())
                else:
                    side = -sign(((nearest_surface_l - ball_location) -
                                  ball_velocity).length() -
                                 ((nearest_surface_r - ball_location) -
                                  ball_velocity).length())
                nearest_surface = Vec3(-nearest_surface.y * side,
                                       nearest_surface.x * side,
                                       nearest_surface.z)
                if abs(target_location.x +
                       nearest_surface.x) >= self.map_size[1] or get_angle(
                           car_location - send_location,
                           car_location - target_location
                       ) > math.pi / 3 * 2 or ball_location.z > 130:
                    target_location = -send_location
                else:
                    target_location = target_location + nearest_surface / 140 * car_velocity.length(
                    )
                controls.boost = enemy_time < 1 and abs(
                    steer_toward_target(my_car, target_location)) <= 0.1
                # Jump
                h = (Vec3(target_ball.physics.location) -
                     distance_from_surface(Vec3(
                         target_ball.physics.location))).length()
                if jump_ready(
                        h) >= earliest_intersection and steer_toward_target(
                            my_car, target_location) < 1:
                    controls.pitch = 0
                    controls.yaw = 0
                    controls.roll = 0
                    controls.jump = True
                    controls.boost = False
                else:
                    jump_attack()
                # Draw
                self.renderer.draw_line_3d(car_location,
                                           ball_location + nearest_surface,
                                           self.renderer.cyan())
                self.renderer.draw_rect_3d(ball_location + nearest_surface,
                                           8,
                                           8,
                                           True,
                                           self.renderer.cyan(),
                                           centered=True)
                controls.throttle = 1
            else:
                target_location = -send_location
                controls.throttle = 1
            return target_location

        def recovery():
            tx = (self.map_size[1] - car_location.x *
                  sign(car_velocity.x)) * safe_div(car_velocity.x)
            ty = (self.map_size[0] - car_location.y *
                  sign(car_velocity.y)) * safe_div(car_velocity.y)
            tt = 0
            if car_location.z / 325 - (car_velocity.z / 650)**2 >= 0:
                tz = car_velocity.z / 650 + math.sqrt(car_location.z / 325 -
                                                      (car_velocity.z /
                                                       650)**2)
            else:
                tz = car_velocity.z / 650 - math.sqrt(car_location.z / 325 +
                                                      (car_velocity.z /
                                                       650)**2)
            if tx >= tz <= ty:
                controls.roll = clamp(-car_rotation.roll, -1, 1)
                controls.pitch = clamp(-car_rotation.pitch, -1, 1)
                tt = tz
            elif tx >= ty <= tz:
                point = (math.pi / 2 +
                         sign(abs(car_rotation.yaw) - math.pi / 2) * math.pi /
                         2) * sign(car_rotation.yaw)
                controls.roll = clamp(
                    math.pi / 2 * sign(car_velocity.y) *
                    sign(abs(car_rotation.yaw) - math.pi / 2) -
                    car_rotation.roll, -1, 1)
                controls.pitch = clamp(point - car_rotation.yaw, -1, 1)
                tt = ty
            draw_point = Vec3(
                car_location.x + car_velocity.x * tt,
                car_location.y + car_velocity.y * tt,
                car_location.z + car_velocity.z * tt - 325 * tt**2)
            self.renderer.draw_line_3d(car_location, draw_point,
                                       self.renderer.pink())
            self.renderer.draw_rect_3d(draw_point,
                                       8,
                                       8,
                                       True,
                                       self.renderer.pink(),
                                       centered=True)

        # Variables

        my_car = packet.game_cars[self.index]
        car_location = Vec3(my_car.physics.location)
        car_velocity = Vec3(my_car.physics.velocity)
        car_rotation = my_car.physics.rotation
        car_direction = Vec3(
            math.cos(car_rotation.yaw) * math.cos(car_rotation.pitch),
            math.sin(car_rotation.yaw) * math.cos(car_rotation.pitch),
            math.sin(car_rotation.pitch))
        ball_prediction = self.get_ball_prediction_struct()
        ball_location = Vec3(packet.game_ball.physics.location)
        ball_velocity = Vec3(packet.game_ball.physics.velocity)
        send_location = Vec3(0, sign(0.5 - self.team) * self.map_size[0], 0)
        earliest_intersection, easiest_intersection = intersect_time(True)
        team_size, car_index = distance_order(1)
        nearest_enemy, enemy_time = nearest_player(0, 460)
        nearest_friendly, friendly_time = nearest_player(0, 460)
        in_goal = (ball_location + send_location).length() > (
            car_location + send_location).length()
        target_location = car_location
        mode = ""
        override = None

        # Controls
        controls = SimpleControllerState()

        # Half-flip to quickly turn
        if car_velocity.length() <= 500 and get_angle(
                car_velocity,
                target_location - car_location) >= math.pi / 3 * 2:
            override = self.reverse_flip(packet)

        # Assign role in the team
        if abs(send_location.y + Vec3(predict_ball(2).physics.location).y
               ) <= 1000 or abs(send_location.y + ball_location.y) <= 1000:
            if in_goal:
                mode = "Attack"
            else:
                mode = "Defense"
        else:
            if car_index == 1:
                if in_goal:
                    mode = "Attack"
                else:
                    mode = "Defense"
            elif car_index < team_size:
                if my_car.boost == 100 and car_index == 2:
                    mode = "Standby"
                else:
                    mode = "Refuel"
            else:
                mode = "Goalie"
        # Recovery
        if my_car.double_jumped:
            recovery()
        # Demolition
        if mode == "Demo":
            target_location = demo()
        # Attack the ball
        if mode == "Attack":
            avoid_bump()
            target_location = attack()
            controls.use_item = True
        # Stand by for hit
        if mode == "Standby":
            avoid_bump()
            target_location = standby()
        # Collect boost
        if mode == "Refuel":
            avoid_bump()
            target_location = refuel()
        # Retreat
        if mode == "Defense":
            avoid_bump()
            target_location = defend()
        # Goalie
        if mode == "Goalie":
            avoid_bump()
            target_location = goalie()

        controls.steer = steer_toward_target(my_car, target_location)

        # Draw
        if False:
            self.renderer.draw_string_2d(
                800, 200, 1, 1, "X: " +
                str(packet.game_cars[1 - self.index].physics.location.x),
                self.renderer.white())
            self.renderer.draw_string_2d(
                800, 220, 1, 1, "Y: " +
                str(packet.game_cars[1 - self.index].physics.location.y),
                self.renderer.white())
            self.renderer.draw_string_2d(1400, 200, 1, 1,
                                         "Map: " + str(self.map),
                                         self.renderer.white())
        self.renderer.draw_string_2d(
            50, 680 + car_index * 20 * (0.5 - self.team) * 2, 1, 1,
            "Noob Bot " + str(car_index) + ": " + str(mode),
            self.renderer.white())
        self.renderer.draw_line_3d(target_location,
                                   distance_from_surface(target_location),
                                   self.renderer.yellow())

        if override:
            return override
        else:
            return controls
Example #17
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        self.boost_pad_tracker.update_boost_status(packet)

        if self.active_sequence is not None and not self.active_sequence.done:
            controls = self.active_sequence.tick(packet)
            if controls is not None:
                return controls

        def predict_ball(t):
            ball_in_future = find_slice_at_time(
                ball_prediction, packet.game_info.seconds_elapsed + t)
            if ball_in_future is not None:
                return ball_in_future
            else:
                return packet.game_ball

        def intersect_time(speed):
            best_spd = math.inf
            for i in range(1, 301):
                time_location = Vec3(predict_ball(i / 60).physics.location)
                if (time_location - car_location).length() * 60 / i <= speed:
                    return i / 60
            return 5

        my_car = packet.game_cars[self.index]
        car_location = Vec3(my_car.physics.location)
        car_velocity = Vec3(my_car.physics.velocity)
        ball_location = Vec3(packet.game_ball.physics.location)
        ball_location_gs = Vector3(packet.game_ball.physics.location)
        ball_velocity = Vec3(packet.game_ball.physics.velocity)
        ball_prediction = self.get_ball_prediction_struct()
        target_location = ball_location
        send_location = Vec3(0, 10240 * (0.5 - self.team), 300)
        if car_location.z == 0:
            self.pos = car_location

        self.renderer.draw_line_3d(self.pos, (target_location - self.pos) /
                                   (target_location - self.pos).length() *
                                   self.travel_distance, self.renderer.white())
        self.renderer.draw_string_3d(self.pos, 1, 1,
                                     f'Speed: {car_velocity.length():.1f}',
                                     self.renderer.white())
        self.renderer.draw_rect_3d(target_location,
                                   8,
                                   8,
                                   True,
                                   self.renderer.cyan(),
                                   centered=True)

        controls = SimpleControllerState()
        controls.steer = steer_toward_target(my_car, target_location)
        controls.throttle = 0
        if packet.game_info.is_round_active == True:
            self.travel_distance += 2300 / 60
        else:
            self.travel_distance = 0
        if (self.pos - ball_location).length(
        ) <= self.travel_distance and ball_location.y / send_location.y <= 1:
            ball_velout = -ball_velocity
            v = -(ball_location - send_location) / (
                ball_location - send_location).length() * 2300
            tp = (ball_velout + v) / (ball_velout + v).length() * 2300
            p = ball_location - tp / tp.length() * 100
            self.travel_distance = 0
            # Intentional weakness
            if random.random() <= 0.125:
                side = random.choice([1, -1])
                p = ball_location + Vec3(-v.x * side, 0,
                                         v.z * side) / 2300 * 150
                self.travel_distance = -11500
            car_state = CarState(
                physics=Physics(location=Vector3(p.x, p.y, p.z),
                                velocity=Vector3(v.x, v.y, v.z)))
            gs = GameState(cars={self.index: car_state})
            self.set_game_state(gs)
            self.pos = Vec3(packet.game_cars[self.index].physics.location)
        elif packet.game_info.is_round_active == True and self.travel_distance >= 0:
            p = self.pos + (ball_location - self.pos) / (
                ball_location - self.pos).length() * (self.travel_distance -
                                                      200)
            car_state = CarState(physics=Physics(
                location=Vector3(p.x, p.y, p.z), velocity=Vector3(0, 0, 0)))
            gs = GameState(cars={self.index: car_state})
            self.set_game_state(gs)
        else:
            self.pos = Vec3(packet.game_cars[self.index].physics.location)
        if packet.game_info.is_round_active == False:
            self.send_quick_chat(
                team_only=False,
                quick_chat=QuickChatSelection.Compliments_WhatASave)
        return controls
Example #18
0
 def attack():
     # Target
     target_ball = predict_ball(earliest_intersection)
     target_location = Vec3(target_ball.physics.location)
     target_location = target_location + (
         target_location - send_location) / (
             target_location - send_location).length() * 92.75
     # Smoother wall transitions
     target_location = move_target_for_walls(car_location,
                                             target_location)
     jumping = jump_ready(
         (target_location -
          distance_from_surface(target_location)).length())
     # Manage speed
     if velocity_from_surface(
             Vec3(target_ball.physics.location),
             Vec3(target_ball.physics.velocity)) >= 0 or (Vec3(
                 target_ball.physics.location) - distance_from_surface(
                     Vec3(target_ball.physics.location))).length(
                     ) <= 300 or target_ball.physics.location.y * sign(
                         send_location.y) <= -self.map_size[0]:
         controls.throttle = 1
     else:
         controls.throttle = 0
     # Boost
     controls.boost = abs(
         steer_toward_target(my_car, target_location)
     ) <= 0.1 and car_velocity.length() < 2300 and (
         (Vec3(target_ball.physics.location) - distance_from_surface(
             Vec3(target_ball.physics.location))).length() <= 300
         or velocity_from_surface(Vec3(target_ball.physics.location),
                                  Vec3(target_ball.physics.velocity)) >=
         0) and car_index == 1
     # Jump
     h = (Vec3(target_ball.physics.location) - distance_from_surface(
         Vec3(target_ball.physics.location))).length()
     if jump_ready(
         (Vec3(target_ball.physics.location) -
          distance_from_surface(Vec3(target_ball.physics.location))
          ).length()) >= earliest_intersection and steer_toward_target(
              my_car, target_location) < 1:
         controls.pitch = 0
         controls.yaw = 0
         controls.roll = 0
         controls.jump = True
         controls.boost = False
     else:
         jump_attack()
     # Catch the ball when in the air
     if abs(
             target_location.z - car_location.z
     ) <= 92.75 * 0.75 and get_angle(
             target_location - car_location, car_velocity
     ) >= math.atan(
             200 * safe_div(car_velocity.length())
     ) and my_car.jumped == True and my_car.double_jumped == False and False:
         controls.yaw = sign(
             (target_location - car_location -
              Vec3(car_velocity.y, -car_velocity.x, car_velocity.z)
              ).length() -
             (target_location - car_location -
              Vec3(-car_velocity.y, car_velocity.x, car_velocity.z)
              ).length())
         controls.jump = True
     # Draw
     self.renderer.draw_line_3d(car_location, target_location,
                                self.renderer.red())
     self.renderer.draw_rect_3d(target_location,
                                8,
                                8,
                                True,
                                self.renderer.red(),
                                centered=True)
     return target_location
Example #19
0
 def defend():
     if not in_goal:
         target_ball = predict_ball(earliest_intersection)
         target_location = Vec3(target_ball.physics.location)
         nearest_surface = (target_location - car_location) / (
             target_location - car_location).length() * 140
         nearest_surface_r = Vec3(-nearest_surface.y, nearest_surface.x,
                                  nearest_surface.z)
         nearest_surface_l = Vec3(nearest_surface.y, -nearest_surface.x,
                                  nearest_surface.z)
         if False:
             side = -sign((nearest_surface_l - send_location).length() -
                          (nearest_surface_r - send_location).length())
         else:
             side = -sign(((nearest_surface_l - ball_location) -
                           ball_velocity).length() -
                          ((nearest_surface_r - ball_location) -
                           ball_velocity).length())
         nearest_surface = Vec3(-nearest_surface.y * side,
                                nearest_surface.x * side,
                                nearest_surface.z)
         if abs(target_location.x +
                nearest_surface.x) >= self.map_size[1] or get_angle(
                    car_location - send_location,
                    car_location - target_location
                ) > math.pi / 3 * 2 or ball_location.z > 130:
             target_location = -send_location
         else:
             target_location = target_location + nearest_surface / 140 * car_velocity.length(
             )
         controls.boost = enemy_time < 1 and abs(
             steer_toward_target(my_car, target_location)) <= 0.1
         # Jump
         h = (Vec3(target_ball.physics.location) -
              distance_from_surface(Vec3(
                  target_ball.physics.location))).length()
         if jump_ready(
                 h) >= earliest_intersection and steer_toward_target(
                     my_car, target_location) < 1:
             controls.pitch = 0
             controls.yaw = 0
             controls.roll = 0
             controls.jump = True
             controls.boost = False
         else:
             jump_attack()
         # Draw
         self.renderer.draw_line_3d(car_location,
                                    ball_location + nearest_surface,
                                    self.renderer.cyan())
         self.renderer.draw_rect_3d(ball_location + nearest_surface,
                                    8,
                                    8,
                                    True,
                                    self.renderer.cyan(),
                                    centered=True)
         controls.throttle = 1
     else:
         target_location = -send_location
         controls.throttle = 1
     return target_location