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 go_nuts(gi: GameInfo) -> Sequence: ball_location = Vec3(gi.packet.game_ball.physics.location) if gi.car.location.flat().dist(ball_location.flat()) > 2000: # We're far away from the ball, let's try to lead it a little bit ball_prediction = gi.bot.get_ball_prediction_struct() # This can predict bounces, etc ball_in_future_location = Vec3(find_slice_at_time(ball_prediction, gi.packet.game_info.seconds_elapsed + 2).physics.location) target_location = ball_in_future_location.flat() + (ball_in_future_location.flat() - Vec3(gi.field.opponent_goal.location)).rescale(2200).flat() with Renderer(gi.bot.renderer) as r: r.draw_line_3d(ball_location, target_location, r.cyan()) else: target_location = ball_location + (ball_location - Vec3(gi.field.opponent_goal.location)).rescale(100) # Draw some things to help understand what the bot is thinking with Renderer(gi.bot.renderer) as r: r.draw_line_3d(gi.car.location, target_location, r.white()) r.draw_string_3d(gi.car.location, 1, 1, f'Speed: {gi.car.velocity.length():.1f}', r.white()) r.draw_rect_3d(target_location, 8, 8, True, r.cyan(), centered=True) controls = SimpleControllerState() controls.steer = gi.car.steer_toward_target(target_location) controls.throttle = 1.0 controls.boost = abs(controls.steer) < 0.2 and gi.car.velocity.length() < 2000 # controls.handbrake = abs(controls.steer) > 0.99 and gi.car.location.dist(ball_location) > 1000 return Sequence([SingleStep(controls)])
def render(self, packet): # 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) # By default we will chase the ball, but target_location can be changed later target_location = ball_location 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)
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) # By default we will chase the ball, but target_location can be changed later target_location = ball_location 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 # You can set more controls if you want, like controls.boost. return controls
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)
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 self.render(packet) my_car = packet.game_cars[self.index] 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) target_location = ball_location if car_location.dist(ball_location) > 1500: ball_prediction = self.get_ball_prediction_struct() ball_in_future = find_slice_at_time(ball_prediction, packet.game_info.seconds_elapsed + 2) if ball_in_future is not None: target_location = Vec3(ball_in_future.physics.location) # Drive at ball controls = self.last_state or SimpleControllerState(throttle=1) # controls.steer = steer_toward_target(my_car, target_location) self.set_controls_from_model(packet, controls) self.last_state = controls return controls
def push_ball_toward_target(gi: GameInfo, target: Vec3) -> Sequence: ball_loc = Vec3(gi.packet.game_ball.physics.location) ball_loc_flat = ball_loc.flat() ball_ground_speed = Vec3(gi.packet.game_ball.physics.velocity).flat().length() car_to_ball_dist = gi.car.location.flat().dist(ball_loc_flat) if ball_ground_speed > 300: future_seconds = car_to_ball_dist / 2000.0 ball_prediction = gi.bot.get_ball_prediction_struct() ball_loc_fut_flat = Vec3(find_slice_at_time(ball_prediction, gi.packet.game_info.seconds_elapsed + future_seconds).physics.location).flat() ideal_position = ball_loc_fut_flat + (ball_loc_fut_flat - target.flat()).rescale(80) # ideal_position = ball_loc_flat + (ball_loc_flat - target.flat()).rescale(80) else: future_seconds = -1 ideal_position = ball_loc_flat + (ball_loc_flat - target.flat()).rescale(80) with Renderer(gi.bot.renderer) as r: r.draw_line_3d(gi.car.location, ideal_position, r.white()) r.draw_string_3d(gi.car.location, 1, 1, f'Predicted Seconds: {future_seconds:.1f}', r.white()) r.draw_rect_3d(ideal_position, 8, 8, True, r.cyan(), centered=True) controls = SimpleControllerState( steer=gi.car.steer_toward_target(ideal_position) ) car_ground_speed = gi.car.velocity.flat().length() if ball_loc.z < 150 or car_to_ball_dist > 800: if abs(controls.steer) < 0.2: controls.throttle = 1.0 controls.boost = car_ground_speed < 2000 else: controls.throttle = 1.0 controls.handbrake = gi.car.angular_velocity.length() < 1 else: if car_ground_speed - ball_ground_speed > 525 and car_to_ball_dist < 500: controls.throttle = min(max((ball_ground_speed - car_ground_speed) / 3600, -1.0), 0) controls.boost = False else: controls.throttle = min(max((ball_ground_speed - car_ground_speed) / 525, 0), 1.0) controls.boost = ball_ground_speed - car_ground_speed > 992 or car_to_ball_dist > 800 return Sequence([SingleStep(controls)])
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
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
def clear(self,packet): #get vector of ball from the cone of own net ideal_shot = self.ball.location.flat() - Vec3(0,-8000,0) if self.bot_car.team==0 else self.ball.location.flat() - Vec3(0,8000,0) #find a future position based off the distance from the ball, using the current location as a backup future_location = self.ball.location future_velocity = self.ball.velocity #continue any strike after checking it if self.current_strike is not None and self.bot_car.stable: if check_strike(packet, self.ball_prediction, self.current_strike): self.active_sequence, strike_controls, strike_location, strike_time = execute_strike(packet,self.bot_car,self.current_strike,self.foes) self.controls = strike_controls #drive out of goal > priority in_goal = self.bot_car.location.within(self.goal_corners[self.bot_car.team][0],self.goal_corners[self.bot_car.team][1]) post0_ang = self.collision_posts[self.bot_car.team][0].__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) std_ang_to_target = self.current_strike.slice_location.__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) post1_ang = self.collision_posts[self.bot_car.team][1].__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) between_posts = post0_ang < std_ang_to_target < post1_ang if not between_posts and in_goal: target_location = Vec3(0,(2*self.team-1)*5000,0) self.controls.throttle = 1 self.steer_toward(self.bot_car, target_location) self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, target_location, self.renderer.white()) return self.renderer.draw_rect_3d(strike_location, 8, 8, True, self.renderer.red(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, strike_location, self.renderer.white()) self.renderer.draw_string_2d(20,20,3,3,f"throttle: {self.controls.throttle}",self.renderer.white()) return else: self.current_strike = None #try to find strikes if self.ball.velocity.length()!=0 and self.current_strike is None: strikes = find_strikes(packet,self.ball_prediction,self.bot_car,ideal_shot) for strike in strikes: if strike.strike_type==strike_types.simple_linear: #linear if (strike.slice_location - Vec3(0,5500*(self.bot_car.team*2-1),0)).ang_to(self.bot_car.orientation.forward) < 2.2: #if linear strike is not a massive angle from the goal if self.current_strike is not None: self.current_strike = strike if strike.slice_time<self.current_strike.slice_time else self.current_strike else: self.current_strike = strike elif strike.strike_type==strike_types.linear_jump: #long jump if (strike.slice_location - Vec3(0,5500*(self.bot_car.team*2-1),0)).ang_to(self.bot_car.orientation.forward) < 2: #if linear strike is not a massive angle from the goal if self.current_strike is not None: self.current_strike = strike if strike.slice_time<self.current_strike.slice_time else self.current_strike else: self.current_strike = strike elif strike.strike_type==strike_types.linear_dblj: #double jump if (strike.slice_location - Vec3(0,5500*(self.bot_car.team*2-1),0)).ang_to(self.bot_car.orientation.forward) < 2: #if linear strike is not a massive angle from the goal if self.current_strike is not None: self.current_strike = strike if strike.slice_time<self.current_strike.slice_time else self.current_strike else: self.current_strike = strike #execute straight away if one was chosen: #execute if self.current_strike is not None: #drive out of goal > priority in_goal = self.bot_car.location.within(self.goal_corners[self.bot_car.team][0],self.goal_corners[self.bot_car.team][1]) post0_ang = self.collision_posts[self.bot_car.team][0].__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) std_ang_to_target = self.current_strike.slice_location.__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) post1_ang = self.collision_posts[self.bot_car.team][1].__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) between_posts = post0_ang < std_ang_to_target < post1_ang if not between_posts and in_goal: target_location = Vec3(0,(2*self.team-1)*5000,0) self.controls.throttle = 1 self.steer_toward(self.bot_car, target_location) self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, target_location, self.renderer.white()) return #execute self.active_sequence, strike_controls, strike_location, strike_time = execute_strike(packet,self.bot_car,self.current_strike,self.foes) self.controls = strike_controls self.renderer.draw_rect_3d(strike_location, 8, 8, True, self.renderer.red(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, strike_location, self.renderer.white()) self.renderer.draw_string_2d(20,20,3,3,f"throttle: {self.controls.throttle}",self.renderer.white()) return #position for a better shot future_location, future_velocity = Vec3(self.ball.location), Vec3(self.ball.velocity) future_slice = find_slice_at_time(self.ball_prediction,packet.game_info.seconds_elapsed + 2) if future_slice is not None: future_location = Vec3(future_slice.physics.location) future_velocity = Vec3(future_slice.physics.velocity) self.renderer.draw_line_3d(self.ball.location, future_location, self.renderer.cyan()) target_location = self.point_in_field(future_location.flat()+ideal_shot.rescale(-500)) #drive out of goal > priority in_goal = self.bot_car.location.within(self.goal_corners[self.bot_car.team][0],self.goal_corners[self.bot_car.team][1]) post0_ang = self.collision_posts[self.bot_car.team][0].__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) std_ang_to_target = target_location.__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) post1_ang = self.collision_posts[self.bot_car.team][1].__sub__(self.bot_car.location).flat().ang_to(Vec3(1,0,0)) between_posts = post0_ang < std_ang_to_target < post1_ang if not between_posts and in_goal: target_location = Vec3(0,(2*self.team-1)*5000,0) self.controls.throttle = 1 self.steer_toward(self.bot_car, target_location) self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, target_location, self.renderer.white()) return self.controls.throttle = 1.0 self.steer_toward(self.bot_car, target_location) self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, target_location, self.renderer.white()) return
def shoot(self,packet): #get vector of ball to the back of other net ideal_shot = Vec3(0,6000,0) - self.ball.location.flat() if self.bot_car.team==0 else Vec3(0,-6000,0) - self.ball.location.flat() #continue any strike after checking it if self.current_strike is not None: if check_strike(packet, self.ball_prediction, self.current_strike): self.active_sequence, strike_controls, strike_location, strike_time = execute_strike(packet,self.bot_car,self.current_strike,self.foes) self.controls = strike_controls self.renderer.draw_rect_3d(strike_location, 8, 8, True, self.renderer.red(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, strike_location, self.renderer.white()) self.renderer.draw_string_2d(20,20,3,3,f"throttle: {self.controls.throttle}",self.renderer.white()) return else: self.current_strike = None #try to find strikes if self.ball.velocity.length()!=0 and self.current_strike is None and self.bot_car.stable: strikes = find_strikes(packet, self.ball_prediction, self.bot_car, ideal_shot) for strike in strikes: if strike.strike_type==strike_types.simple_linear: #linear if (Vec3(0,6000*(1-self.bot_car.team*2),0) - strike.slice_location).ang_to(self.bot_car.orientation.forward) < 2: #if linear strike is not a massive angle from the goal if self.current_strike is not None: self.current_strike = strike if strike.slice_time<self.current_strike.slice_time else self.current_strike else: self.current_strike = strike elif strike.strike_type==strike_types.linear_jump: #long jump if (Vec3(0,6000*(1-self.bot_car.team*2-1),0) - strike.slice_location).ang_to(self.bot_car.orientation.forward) < 2: #if linear strike is not a massive angle from the goal if self.current_strike is not None: self.current_strike = strike if strike.slice_time<self.current_strike.slice_time else self.current_strike else: self.current_strike = strike elif strike.strike_type==strike_types.linear_dblj: #double jump if (Vec3(0,6000*(1-self.bot_car.team*2-1),0) - strike.slice_location).ang_to(self.bot_car.orientation.forward) < 2: #if linear strike is not a massive angle from the goal if self.current_strike is not None: self.current_strike = strike if strike.slice_time<self.current_strike.slice_time else self.current_strike else: self.current_strike = strike #execute straight away if one was chosen if self.current_strike is not None: self.active_sequence, strike_controls, strike_location, strike_time = execute_strike(packet,self.bot_car,self.current_strike,self.foes) self.controls = strike_controls self.renderer.draw_rect_3d(strike_location, 8, 8, True, self.renderer.red(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, strike_location, self.renderer.white()) self.renderer.draw_string_2d(20,20,3,3,f"throttle: {self.controls.throttle}",self.renderer.white()) return #position to get a shot on the ball future_location, future_velocity = Vec3(self.ball.location), Vec3(self.ball.velocity) future_slice = find_slice_at_time(self.ball_prediction,packet.game_info.seconds_elapsed + 2) if future_slice is not None: future_location = Vec3(future_slice.physics.location) future_velocity = Vec3(future_slice.physics.velocity) self.renderer.draw_line_3d(self.ball.location, future_location, self.renderer.cyan()) target_location = self.point_in_field(future_location.flat()+ideal_shot.rescale(-500)) self.controls.throttle = 1.0 self.steer_toward(self.bot_car, target_location) self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True) self.renderer.draw_line_3d(self.bot_car.location, target_location, self.renderer.white()) return
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) ball_velocity = Vec3(packet.game_ball.physics.velocity) # By default we will chase the ball, but target_location can be changed later target_location = ball_location ball_on_floor = target_location ball_prediction = self.get_ball_prediction_struct() # This can predict bounces, etc # dynamic time to the ball depending on the car's speed time_in_future = self.time_to_ball(car_location, car_velocity.length(), ball_location) seconds_in_future = packet.game_info.seconds_elapsed + time_in_future ball_in_future = find_slice_at_time(ball_prediction, seconds_in_future) ball_on_floor = find_matching_slice(ball_prediction, 0, lambda s: s.physics.location.z < 150 and s.game_seconds >= packet.game_info.seconds_elapsed + time_in_future, search_increment=1) time_to_floor = 0 # 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) time_in_future = self.time_to_ball(car_location, car_velocity.length(), target_location) self.renderer.draw_line_3d(ball_location, target_location, self.renderer.cyan()) # gets the next time when the ball is on the floor if ball_on_floor is not None: floor_location = Vec3(ball_on_floor.physics.location) time_to_floor = ball_on_floor.game_seconds - packet.game_info.seconds_elapsed self.renderer.draw_line_3d(ball_location, floor_location, self.renderer.orange()) self.renderer.draw_rect_3d(floor_location, 8, 8, True, self.renderer.orange(), centered=True) # 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_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True) orientation = Orientation(my_car.physics.rotation) relative = relative_location(car_location, orientation, ball_location) controls = SimpleControllerState() self.renderer.draw_string_2d(10, 10 + self.team * 100, 5, 5, f"{controls.throttle}", self.renderer.team_color()) # makes the car rotate to be more straight if not my_car.has_wheel_contact: # roll to land on all four wheels if orientation.roll < -0.1: controls.roll = 1 elif orientation.roll > 0.1: controls.roll = -1 # pitch to land on all four wheels if orientation.pitch < -0.1: controls.pitch = 1 elif orientation.pitch > 0.1: controls.pitch = -1 deg = math.degrees(car_location.ang_to(ball_location)) # yaw to correct angle towards ball if deg < 85: controls.yaw = 1 elif deg > 95: controls.yaw = -1 # jump if another car is close to not get stuck if self.location_to_nearest_car(car_location, my_car.team, packet).dist(car_location) < 200 and car_velocity.length() < 50: controls.jump = True self.set_kickoff_state(car_velocity, ball_location, ball_velocity) self.decide_state(controls, packet, my_car, car_location, car_velocity, ball_location, ball_velocity, target_location, ball_prediction, orientation, relative, time_in_future, time_to_floor) return controls
def run(agent): if len(agent.friends) == 0: if agent.team > 0.1: team_multiplier = 1 if agent.team < 0.1: team_multiplier = -1 if agent.team == 0: team_lol = 0 else: team_lol = 1 left_field = Vector3( 4200 * -side(agent.team), agent.ball.location.y + (1000 * -side(agent.team)), 0) right_field = Vector3( 4200 * side(agent.team), agent.ball.location.y + (1000 * side(agent.team)), 0) future_ball = Vec3(0, 0, 0) future_ball_2 = 0 ball_in_future = 0 ball_in_future_2 = 0 packet = GameTickPacket() ball_prediction = agent.get_ball_prediction_struct() ball_in_future = find_slice_at_time(ball_prediction, agent.time + 1) ball_in_future_2 = find_slice_at_time(ball_prediction, agent.time + 2) if ball_in_future is not None: future_ball = Vec3(ball_in_future.physics.location) elif ball_in_future_2 is not None: future_ball = Vec3(ball_in_future_2.physics.location) my_goal_to_ball, my_ball_distance = ( agent.ball.location - agent.friend_goal.location).normalize(True) goal_to_me = agent.me.location - agent.friend_goal.location my_distance = my_goal_to_ball.dot(goal_to_me) large_boosts = [ boost for boost in agent.boosts if boost.large and boost.active ] foe_goal_to_ball, foe_ball_distance = ( agent.ball.location - agent.foe_goal.location).normalize(True) foe_goal_to_foe = agent.foes[0].location - agent.foe_goal.location foe_distance = foe_goal_to_ball.dot(foe_goal_to_foe) closest_foe_to_ball = agent.foes[0] for foe in agent.foes: if (closest_foe_to_ball.location - agent.ball.location).magnitude() > ( foe.location - agent.ball.location).magnitude(): closest_foe = foe left_field = Vector3( 4200 * -side(agent.team), agent.ball.location.y + (1000 * -side(agent.team)), 0) right_field = Vector3( 4200 * side(agent.team), agent.ball.location.y + (1000 * side(agent.team)), 0) targets = { "goal": (agent.foe_goal.left_post, agent.foe_goal.right_post), "upfield": (left_field, right_field), "not_my_net": (agent.friend_goal.right_post, agent.friend_goal.left_post) } shots = find_hits(agent, targets) x = 1 me_onside = my_distance - 200 < my_ball_distance foe_onside = foe_distance - 200 < foe_ball_distance close = (agent.me.location - agent.ball.location).magnitude() < 3000 foe_close = (closest_foe_to_ball.location - agent.ball.location).magnitude() < 3000 have_boost = agent.me.boost > 20 defense_location = Vector3( agent.ball.location.x, agent.ball.location.y + (4000 * team_multiplier), 0) closest_foe = agent.foes[0] for foe in agent.foes: if (closest_foe.location - agent.me.location).magnitude() > ( foe.location - agent.me.location).magnitude(): closest_foe = foe x = 1 if agent.team == 0: agent.debug_stack() agent.line(agent.friend_goal.location, agent.ball.location, [255, 255, 255]) my_point = agent.friend_goal.location + (my_goal_to_ball * my_distance) agent.line(my_point - Vector3(0, 0, 100), my_point + Vector3(0, 0, 100), [0, 255, 0]) def get_closest_boost(agent): large_boosts = [ boost for boost in agent.boosts if boost.large and boost.active ] closest_boost = large_boosts[0] for item in large_boosts: if (closest_boost.location - agent.me.location).magnitude() > ( item.location - agent.me.location).magnitude(): closest_boost = item agent.stack = [] agent.push(goto_boost(closest_boost)) def demo(agent): relative_target = closest_foe.location - agent.me.location local_target = agent.me.local(relative_target) defaultPD(agent, local_target) defaultThrottle(agent, 2300) if (agent.me.location - closest_foe.location).magnitude() < 200: agent.push( flip( agent.me.local(closest_foe.location - agent.me.location))) if agent.team == 0: agent.debug_stack() agent.line(agent.friend_goal.location, agent.ball.location, [255, 255, 255]) my_point = agent.friend_goal.location + (my_goal_to_ball * my_distance) agent.line(my_point - Vector3(0, 0, 100), my_point + Vector3(0, 0, 100), [0, 255, 0]) if agent.team == 0: agent.debug_stack() if len(agent.stack) < 1: if agent.kickoff_flag: if agent.me.location.x > 300 or agent.me.location.x < -300: agent.push(kickoff()) else: agent.controller.throttle = 0 elif (agent.me.location - agent.friend_goal.location).magnitude( ) < 2000 and -1000 < agent.ball.location.x < 1000 and -1000 < closest_foe_to_ball.location.x < 1000: if len(shots["not_my_net"]) > 0: agent.push(shots["not_my_net"][0]) elif (close and me_onside) and (foe_onside and foe_close) and ( agent.me.location - agent.ball.location ).magnitude() > 50 and agent.ball.location.z < 200: while (agent.me.location - agent.ball.location).magnitude() > 50: relative_target = agent.ball.location - agent.me.location local_target = agent.me.local(relative_target) defaultPD(agent, local_target) defaultThrottle(agent, 2300) break elif (close and me_onside) or me_onside and ( closest_foe_to_ball.location - agent.ball.location ).magnitude() > (agent.me.location - agent.ball.location).magnitude(): if len(shots["goal"]) > 0: agent.push(shots["goal"][0]) elif len(shots["upfield"]) > 0: agent.push(shots["upfield"][0]) elif (agent.ball.location - agent.friend_goal.location).magnitude() > 6000: agent.push(goto(defense_location)) elif (agent.ball.location - agent.friend_goal.location).magnitude() > 4000 and ( closest_foe.location - agent.ball.location ).magnitude() > 3000 and agent.me.boost < 30 or ( agent.ball.location - agent.friend_goal.location ).magnitude() > 8000 and agent.me.boost < 30: closest_boost = large_boosts[0] for item in large_boosts: if (closest_boost.location - agent.me.location ).magnitude() > (item.location - agent.me.location).magnitude(): closest_boost = item agent.stack = [] agent.push(goto_boost(closest_boost)) elif (agent.ball.location - agent.friend_goal.location ).magnitude() < 5000 and len(shots["not_my_net"]) > 0: agent.push(shots["not_my_net"][0]) else: demo(agent) elif len(agent.friends) > 0: if agent.team > 0.1: team_multiplier = 1 if agent.team < 0.1: team_multiplier = -1 if agent.team == 0: team_lol = 0 else: team_lol = 1 if len(agent.friends) > 0: for friend in agent.friends: if (agent.me.location - agent.ball.location).magnitude( ) > (friend.location - agent.ball.location).magnitude(): is_closest_friend_to_ball = False else: is_closest_friend_to_ball = True closest_foe = agent.foes[0] for foe in agent.foes: if (closest_foe.location - agent.me.location).magnitude() > ( foe.location - agent.me.location).magnitude(): closest_foe = foe left_field = Vector3( 4200 * -side(agent.team), agent.ball.location.y + (1000 * -side(agent.team)), 0) right_field = Vector3( 4200 * side(agent.team), agent.ball.location.y + (1000 * side(agent.team)), 0) future_ball = Vec3(0, 0, 0) future_ball_2 = 0 ball_in_future = 0 ball_in_future_2 = 0 packet = GameTickPacket() ball_prediction = agent.get_ball_prediction_struct() ball_in_future = find_slice_at_time(ball_prediction, agent.time + 1) ball_in_future_2 = find_slice_at_time(ball_prediction, agent.time + 2) if ball_in_future is not None: future_ball = Vec3(ball_in_future.physics.location) elif ball_in_future_2 is not None: future_ball = Vec3(ball_in_future_2.physics.location) my_goal_to_ball, my_ball_distance = ( agent.ball.location - agent.friend_goal.location).normalize(True) goal_to_me = agent.me.location - agent.friend_goal.location my_distance = my_goal_to_ball.dot(goal_to_me) large_boosts = [ boost for boost in agent.boosts if boost.large and boost.active ] foe_goal_to_ball, foe_ball_distance = ( agent.ball.location - agent.foe_goal.location).normalize(True) foe_goal_to_foe = agent.foes[0].location - agent.foe_goal.location foe_distance = foe_goal_to_ball.dot(foe_goal_to_foe) closest_foe_to_ball = agent.foes[0] for foe in agent.foes: if (closest_foe_to_ball.location - agent.ball.location).magnitude() > ( foe.location - agent.ball.location).magnitude(): closest_foe_to_ball = foe if len(agent.friends) > 0: closest_friend_to_ball = agent.friends[0] for friend in agent.friends: if (closest_friend_to_ball.location - agent.ball.location ).magnitude() > (friend.location - agent.ball.location).magnitude(): closest_friend_to_ball = friend closest_friend_to_goal = agent.friends[0] for friend in agent.friends: if (closest_friend_to_goal.location - agent.friend_goal.location).magnitude() > ( friend.location - agent.friend_goal.location).magnitude(): closest_friend_to_goal = friend closest_friend = agent.friends[0] for friend in agent.friends: if (closest_friend.location - agent.me.location).magnitude( ) > (friend.location - agent.me.location).magnitude(): closest_friend = friend closest_foe = agent.foes[0] for foe in agent.foes: if (closest_foe_to_ball.location - agent.me.location).magnitude() > ( foe.location - agent.me.location).magnitude(): closest_foe = foe left_field = Vector3( 4200 * -side(agent.team), agent.ball.location.y + (1000 * -side(agent.team)), 0) right_field = Vector3( 4200 * side(agent.team), agent.ball.location.y + (1000 * side(agent.team)), 0) targets = { "goal": (agent.foe_goal.left_post, agent.foe_goal.right_post), "upfield": (left_field, right_field), "not_my_net": (agent.friend_goal.right_post, agent.friend_goal.left_post) } shots = find_hits(agent, targets) x = 1 me_onside = my_distance - 200 < my_ball_distance foe_onside = foe_distance - 200 < foe_ball_distance close = (agent.me.location - agent.ball.location).magnitude() < 3000 foe_close = (closest_foe_to_ball.location - agent.ball.location).magnitude() < 3000 have_boost = agent.me.boost > 20 defense_location = Vector3( agent.ball.location.x, agent.ball.location.y + (4000 * team_multiplier), 0) x = 1 if agent.team == 0: agent.debug_stack() agent.line(agent.friend_goal.location, agent.ball.location, [255, 255, 255]) my_point = agent.friend_goal.location + (my_goal_to_ball * my_distance) agent.line(my_point - Vector3(0, 0, 100), my_point + Vector3(0, 0, 100), [0, 255, 0]) def get_closest_boost(agent): large_boosts = [ boost for boost in agent.boosts if boost.large and boost.active ] closest_boost = large_boosts[0] for item in large_boosts: if (closest_boost.location - agent.me.location).magnitude() > ( item.location - agent.me.location).magnitude(): closest_boost = item agent.stack = [] agent.push(goto_boost(closest_boost)) def demo(agent): relative_target = closest_foe.location - agent.me.location local_target = agent.me.local(relative_target) defaultPD(agent, local_target) defaultThrottle(agent, 2300) if (agent.me.location - closest_foe.location).magnitude() < 200: agent.push( flip( agent.me.local(closest_foe.location - agent.me.location))) if agent.team == 0: agent.debug_stack() agent.line(agent.friend_goal.location, agent.ball.location, [255, 255, 255]) my_point = agent.friend_goal.location + (my_goal_to_ball * my_distance) agent.line(my_point - Vector3(0, 0, 100), my_point + Vector3(0, 0, 100), [0, 255, 0]) if agent.team == 0: agent.debug_stack() if len(agent.stack) < 1: if agent.kickoff_flag: if (closest_friend_to_ball.location - agent.ball.location ).magnitude() > ( agent.me.location - agent.ball.location ).magnitude() or ( closest_friend_to_ball.location - agent.ball.location ).magnitude() == ( agent.me.location - agent .ball. location ).magnitude( ) and closest_friend_to_ball.location.x < agent.me.location.x: agent.push(kickoff()) else: get_closest_boost(agent) elif (close and me_onside) and (foe_onside and foe_close) and ( agent.me.location - agent.ball.location ).magnitude() > 50 and agent.ball.location.z < 200 and ( closest_friend_to_ball.location - agent.ball.location).magnitude() > 1000: while (agent.me.location - agent.ball.location).magnitude() > 50: relative_target = agent.ball.location - agent.me.location local_target = agent.me.local(relative_target) defaultPD(agent, local_target) defaultThrottle(agent, 2300) break elif (close and me_onside) or ( not foe_onside and me_onside ) or (agent.me.location - agent.ball.location).magnitude() < ( closest_friend_to_ball.location - agent.ball.location).magnitude() and me_onside: if len(shots["goal"]) > 0: agent.push(shots["goal"][0]) elif len(shots["upfield"]) > 0: agent.push(shots["upfield"][0]) elif (agent.ball.location - agent.friend_goal.location).magnitude() > 4000 and ( closest_foe.location - agent.ball.location ).magnitude() > 3000 and agent.me.boost < 30 or ( agent.ball.location - agent.friend_goal.location ).magnitude() > 8000 and agent.me.boost < 30: get_closest_boost(agent) elif (agent.ball.location - agent.friend_goal.location).magnitude() > 5000 and ( closest_friend_to_ball.location - agent.ball.location ).magnitude() < (agent.me.location - agent.ball.location).magnitude(): demo(agent) elif (agent.ball.location.y - agent.friend_goal.location.y) > 4000: agent.push(goto(defense_location)) elif (agent.ball.location - agent.friend_goal.location ).magnitude() < 4000 and len(shots["not_my_net"]) > 0: agent.push(shots["not_my_net"][0]) else: demo(agent)
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) #self.info = self.info.read_packet(packet) self.car.updateCar(packet, self.index) self.info.read_packet(packet, self.get_ball_prediction_struct().slices) #print("in main target: {}".format(self.get_ball_prediction_struct().slices[0].physics.location)) #self.renderer.draw_line_3d(self.car.loc, target_location, self.renderer.white()) #self.renderer.draw_rect_3d(target_location, 8, 8, True, self.renderer.cyan(), centered=True) #cg = ChallengeGame(self.car, bp_struct) #print(cg.get_time_to_loc(cg.challenge_loc)) # 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.action is None: self.action = self.strat.chooseAction(self.info) controls = self.action.tick(self.info) print(controls.steer) return controls self.renderer.draw_string_3d(self.car.loc, 1, 1, f'Speed: {self.car.vel.length():.1f}', self.renderer.white()) if self.action.name: self.renderer.draw_string_3d(self.car.loc + Vec3(0, 0, 20), 1, 1, self.action.name, self.renderer.white()) if packet.game_info.is_kickoff_pause and not isinstance(self.action, kickoff): #self.logger.info(self.action) self.action = kickoff(self.car.loc) #print("Sequence is: {}".format(self.action)) #print("Sequence finished: {}".format(self.action.done)) controls = self.action.tick(self.info) return controls if self.action and not self.action.done: controls = self.action.tick(self.info) #print("action is: {}".format(self.action.name)) if controls is not None: return controls elif self.action.done: print("choosing new action") self.action = self.strat.chooseAction(self.info) controls = self.action.tick(self.info) return controls # Gather some information about our car and the ball ball_location = Vec3(packet.game_ball.physics.location) if self.car.loc.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 # Draw some things to help understand what the bot is thinking #self.renderer.draw_string_2d(100, 100, 1, 1, f'Ball at: {ball_location}', self.renderer.white()) ''' if 750 < self.car.vel.length() < 800: # We'll do a front flip if the car is moving at a certain speed. return self.begin_front_flip(packet) #controls = self.action.controls controls = SimpleControllerState() controls.steer = steer_toward_target(self.car, target_location) controls.throttle = 1.0 # You can set more controls if you want, like controls.boost. ''' print("the f**k we doin here?!?!?!?") return controls