def initialize_agent(self): # This runs once before the bot starts up self.controllerState = SimpleControllerState() self.stateMachine = StateMachine(self) self.spikeWatcher = SpikeWatcher() self.lastTime = 0 self.realLastTime = 0 self.doneTicks = 0 self.skippedTicks = 0 self.ticksThisPacket = 0 self.FPS = 120 self.lastQuickChatTime = 0 self.secondMessage = None self.currentTick = 0 self.firstTpsReport = True self.game = Game() self.game.set_mode("soccar") self.car = self.game.cars[self.index] self.reorientML = ReorientML(self.car) self.lastJumpTick = -math.inf self.maxDodgeTick = 0 self.jumpReleased = True self.lastDodgeTick = -math.inf self.lastController = SimpleControllerState()
def initialize_agent(self): # This runs once before the bot starts up self.controller_state = SimpleControllerState() self.active_sequence: Sequence = None self.spike_watcher = SpikeWatcher()
class Puffy(BaseAgent): def initialize_agent(self): # This runs once before the bot starts up self.controllerState = SimpleControllerState() self.stateMachine = StateMachine(self) self.spikeWatcher = SpikeWatcher() self.lastTime = 0 self.realLastTime = 0 self.doneTicks = 0 self.skippedTicks = 0 self.ticksThisPacket = 0 self.FPS = 120 self.lastQuickChatTime = 0 self.secondMessage = None self.currentTick = 0 self.firstTpsReport = True self.game = Game() self.game.set_mode("soccar") self.car = self.game.cars[self.index] self.reorientML = ReorientML(self.car) self.lastJumpTick = -math.inf self.maxDodgeTick = 0 self.jumpReleased = True self.lastDodgeTick = -math.inf self.lastController = SimpleControllerState() def get_output(self, packet: GameTickPacket) -> SimpleControllerState: # self.renderer.begin_rendering() self.packet = packet self.handleTime() self.game.read_game_information(packet, self.get_field_info()) self.spikeWatcher.read_packet(packet) ballY = packet.game_ball.physics.location.y if abs( ballY ) > 5120 + 60 and packet.game_info.seconds_elapsed - self.lastQuickChatTime > 15: teamDirection = 1 if packet.game_ball.latest_touch.team == 0 else -1 firstByToucher = True if ballY * teamDirection > 0: if packet.game_ball.latest_touch.team == packet.game_cars[ self.index].team: firstMessage, secondMessage = QuickChats.Compliments_NiceShot, QuickChats.Compliments_Thanks firstByToucher = False else: firstMessage, secondMessage = QuickChats.Apologies_Whoops, QuickChats.Apologies_NoProblem else: if packet.game_ball.latest_touch.team == packet.game_cars[ self.index].team: firstMessage, secondMessage = QuickChats.Compliments_WhatASave, QuickChats.Apologies_NoProblem firstByToucher = False else: firstMessage, secondMessage = QuickChats.Compliments_WhatASave, QuickChats.Reactions_Savage bribbleBots = [] latestTouchIsBribble = False for carIndex in range(packet.num_cars): car = packet.game_cars[carIndex] if car.team == self.team and "Puffy" in car.name: bribbleBots.append(carIndex) if packet.game_ball.latest_touch.player_index == carIndex: latestTouchIsBribble = True if len(bribbleBots) == 1: self.send_quick_chat(QuickChats.CHAT_EVERYONE, firstMessage) self.secondMessage = secondMessage else: sendFirst = packet.game_ball.latest_touch.player_index == self.index or ( not latestTouchIsBribble and self.index == min(bribbleBots)) if not sendFirst ^ firstByToucher: self.send_quick_chat(QuickChats.CHAT_EVERYONE, firstMessage) else: self.secondMessage = secondMessage self.lastQuickChatTime = packet.game_info.seconds_elapsed elif packet.game_info.seconds_elapsed - self.lastQuickChatTime > 0.2 and self.secondMessage != None: self.send_quick_chat(QuickChats.CHAT_EVERYONE, self.secondMessage) self.secondMessage = None self.stateMachine.tick(packet) self.trackJump(self.stateMachine.currentState.controller) # self.renderer.end_rendering() return self.stateMachine.currentState.controller def trackJump(self, controller: SimpleControllerState): if controller.jump and not self.lastController.jump and self.car.on_ground and self.currentTick - self.lastJumpTick > 28: self.lastJumpTick = self.currentTick self.jumpReleased = False if self.car.on_ground: self.maxDodgeTick = math.inf self.lastJumpTick = -math.inf self.lastDodgeTick = -math.inf elif self.lastController.jump and self.currentTick - self.lastJumpTick > 28: if not controller.jump: self.maxDodgeTick = self.currentTick + 1.25 * 120 elif self.lastJumpTick == -math.inf: self.maxDodgeTick = math.inf else: self.maxDodgeTick = self.lastJumpTick + 1.45 * 120 if not self.car.on_ground and controller.jump and not self.car.double_jumped and self.currentTick <= self.maxDodgeTick: self.lastDodgeTick = self.currentTick if not self.jumpReleased and not controller.jump: self.jumpReleased = True self.lastController = controller def handleTime(self): # this is the most conservative possible approach, but it could lead to having a "backlog" of ticks if seconds_elapsed # isnt perfectly accurate. if not self.lastTime: self.lastTime = self.packet.game_info.seconds_elapsed else: if self.realLastTime == self.packet.game_info.seconds_elapsed: return if int(self.lastTime) != int( self.packet.game_info.seconds_elapsed): # if self.skippedTicks > 0: print(f"did {self.doneTicks}, skipped {self.skippedTicks}") if self.firstTpsReport or self.packet.game_ball.physics.location.x == 0 and self.packet.game_ball.physics.location.y == 0: self.firstTpsReport = False elif self.doneTicks < 110: self.send_quick_chat(QuickChats.CHAT_EVERYONE, QuickChats.Custom_Excuses_Lag) self.skippedTicks = self.doneTicks = 0 ticksPassed = round( max(1, (self.packet.game_info.seconds_elapsed - self.lastTime) * self.FPS)) self.lastTime = min(self.packet.game_info.seconds_elapsed, self.lastTime + ticksPassed) self.realLastTime = self.packet.game_info.seconds_elapsed self.currentTick += ticksPassed if ticksPassed > 1: # print(f"Skipped {ticksPassed - 1} ticks!") self.skippedTicks += ticksPassed - 1 self.doneTicks += 1
class MyBot(BaseAgent): def initialize_agent(self): # This runs once before the bot starts up self.controller_state = SimpleControllerState() self.active_sequence: Sequence = None self.spike_watcher = SpikeWatcher() 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 def start_aerial(self, target: Vec3, arrival_time: float): self.active_sequence = Sequence([ LineUpForAerialStep(target, arrival_time, self.index), AerialStep(target, arrival_time, self.index) ])