def shooting(agent): """"Method that gives the output for the shooting strategy""" ball = agent.info.ball car = agent.info.my_car target = shooting_target(agent) agent.drive.target = target distance = distance_2d(car.position, target) vf = velocity_forward(car) dodge_overshoot = distance < (abs(vf) + 500) * 1.5 agent.drive.speed = get_speed(agent, target) agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if agent.defending: agent.step = Step.Defending elif should_dodge(agent): agent.step = Step.Dodge agent.dodge = Dodge(car) agent.dodge.duration = 0.1 agent.dodge.target = ball.position elif agent.ball_bouncing and not (abs(ball.velocity[2]) < 100 and sign(agent.team) * ball.velocity[1] < 0) and get_bounce(agent) is not None: agent.step = Step.Catching agent.drive.target = ball.position agent.drive.speed = 1399 elif vf < -900 and (not dodge_overshoot or distance < 600): agent.step = Step.HalfFlip agent.halfflip = HalfFlip(car) elif not dodge_overshoot and car.position[2] < 80 and \ (agent.drive.speed > abs(vf) + 300 and 1200 < abs(vf) < 2000 and car.boost <= 25): # Dodge towards the target for speed agent.step = Step.Dodge agent.dodge = Dodge(car) agent.dodge.duration = 0.1 agent.dodge.target = target
def step(self, dt): car = self.car target = ground(self.target) car_speed = norm(car.velocity) time_left = (ground_distance(car, target) - self.finish_distance) / max(car_speed + 500, 1400) forward_speed = dot(car.forward(), car.velocity) if self.driving and car.on_ground: self.action.target_pos = target self._time_on_ground += dt # check if it's a good idea to dodge, wavedash or halfflip if (self._time_on_ground > 0.2 and car.position[2] < 200 and angle_to(car, target, forward_speed < 0) < 0.1): # if going forward, use a dodge or a wavedash if forward_speed > 0: use_boost_instead = self.waste_boost and car.boost > 20 if car_speed > 1200 and not use_boost_instead: if time_left > self.DODGE_DURATION: dodge = Dodge(car) dodge.duration = 0.05 dodge.direction = vec2(direction(car, target)) self.action = dodge self.driving = False elif time_left > self.WAVEDASH_DURATION: wavedash = Wavedash(car) wavedash.direction = vec2(direction(car, target)) self.action = wavedash self.driving = False # if going backwards, use a halfflip elif time_left > self.HALFFLIP_DURATION and car_speed > 800: self.action = HalfFlip(car, self.waste_boost and time_left > 3) self.driving = False self.action.step(dt) self.controls = self.action.controls # make sure we're not boosting airborne if self.driving and not car.on_ground: self.controls.boost = False # make sure we're not stuck turtling if not car.on_ground: self.controls.throttle = 1 if self.action.finished and not self.driving: self.driving = True self._time_on_ground = 0 self.action = self.drive self.drive.backwards = False if ground_distance(car, target) < self.finish_distance and self.driving: self.finished = True
def defending(agent): """"Method that gives output for the defending strategy""" target = defending_target(agent) agent.drive.target = target distance = distance_2d(agent.info.my_car.position, target) vf = velocity_forward(agent.info.my_car) dodge_overshoot = distance < (abs(vf) + 500) * 1.5 agent.drive.speed = get_speed(agent, target) agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls t = time.time() can_dodge, simulated_duration, simulated_target = agent.simulate() # print(time.time() - t) if can_dodge: agent.dodge = Dodge(agent.info.my_car) agent.turn = AerialTurn(agent.info.my_car) agent.dodge.duration = simulated_duration - 0.1 agent.dodge.target = simulated_target agent.dodge.preorientation = look_at(simulated_target, vec3(0, 0, 1)) agent.timer = 0 agent.step = Step.Dodge if not agent.should_defend(): agent.step = Step.Shooting elif vf < -900 and (not dodge_overshoot or distance < 600): agent.step = Step.HalfFlip agent.halfflip = HalfFlip(agent.info.my_car) elif not dodge_overshoot and agent.info.my_car.position[2] < 80 and \ (agent.drive.speed > abs(vf) + 300 and 1200 < abs(vf) < 2000 and agent.info.my_car.boost <= 25): # Dodge towards the target for speed agent.step = Step.Dodge agent.dodge = Dodge(agent.info.my_car) agent.dodge.duration = 0.1 agent.dodge.target = target
def step(self, dt): if self.phase == 0: self.controls.throttle = 1 self.controls.boost = 1 if ground_distance(self.car, self.info.ball) < 2950: print("entering phase 1") self.phase = 1 if self.phase == 1: self.dodge.step(dt) self.controls = self.dodge.controls if self.dodge.finished and self.car.on_ground: print("entering phase 2") self.phase = 2 self.dodge = Dodge(self.car) self.dodge.duration = 0.18 self.dodge.direction = direction(self.car.position, self.info.ball.position) if self.phase == 2: self.drive.step(dt) self.controls = self.drive.controls if distance(self.car, self.info.ball) < 850: print("entering phase 3") self.phase = 3 if self.phase == 3: self.dodge.step(dt) self.controls = self.dodge.controls self.finished = self.info.ball.position[0] != 0 and self.dodge.finished
def defending(agent): """"Method that gives output for the defending strategy""" target = defending_target(agent) agent.drive.target = target distance = distance_2d(agent.info.my_car.location, target) vf = velocity_forward(agent.info.my_car) dodge_overshoot = distance < (abs(vf) + 500) * 1.5 agent.drive.speed = get_speed(agent, target) agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if can_dodge(agent, target): agent.step = Step.Dodge agent.dodge = Dodge(agent.info.my_car) agent.dodge.duration = 0.1 agent.dodge.target = target if not agent.defending: agent.step = (Step.Catching if agent.ball_bouncing else Step.Shooting) elif vf < -900 and (not dodge_overshoot or distance < 600): agent.step = Step.HalfFlip agent.halfflip = HalfFlip(agent.info.my_car) elif not dodge_overshoot and agent.info.my_car.location[2] < 80 and\ (agent.drive.speed > abs(vf) + 300 and 1200 < abs(vf) < 2000 and agent.info.my_car.boost <= 25): # Dodge towards the target for speed agent.step = Step.Dodge agent.dodge = Dodge(agent.info.my_car) agent.dodge.duration = 0.1 agent.dodge.target = target
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.game.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state if self.state == State.RESET: self.timer = 0.0 # put the car in the middle of the field car_state = CarState( physics=Physics(location=Vector3(0, 0, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0))) theta = random.uniform(0, 6.28) pos = Vector3(sin(theta) * 1000.0, cos(theta) * 1000.0, 100.0) # put the ball somewhere out of the way ball_state = BallState( physics=Physics(location=pos, velocity=Vector3(0, 0, 0), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0))) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) next_state = State.WAIT if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE if self.state == State.INITIALIZE: self.action = Dodge(self.game.my_car) self.action.duration = 0.1 self.action.direction = vec2(self.game.ball.location) next_state = State.RUNNING if self.state == State.RUNNING: self.action.step(self.game.time_delta) self.controls = self.action.controls if self.timer > self.timeout: next_state = State.RESET self.timer += self.game.time_delta self.state = next_state return self.controls
class CarryAndFlick(Maneuver): """ Carry the ball on roof, and flick it if an opponent is close or if fast enough and facing the target. """ def __init__(self, car: Car, info: GameInfo, target: vec3): super().__init__(car) self.target = target self.info = info self.carry = Carry(car, info.ball, target) self.flick = Dodge(car) self.flick.duration = 0.15 self.flick.target = target self.flicking = False def interruptible(self) -> bool: return not self.flicking def step(self, dt): if not self.flicking: self.carry.step(dt) self.controls = self.carry.controls self.finished = self.carry.finished car = self.car ball = self.info.ball # check if it's a good idea to flick dir_to_target = ground_direction(car, self.target) if ( distance(car, ball) < 150 and ground_distance(car, ball) < 100 and dot(car.forward(), dir_to_target) > 0.7 and norm(car.velocity) > clamp(distance(car, self.target) / 3, 1000, 1700) and dot(dir_to_target, ground_direction(car, ball)) > 0.9 ): self.flicking = True # flick if opponent is close for opponent in self.info.get_opponents(): if ( distance(opponent.position + opponent.velocity, car) < max(300.0, norm(opponent.velocity) * 0.5) and dot(opponent.velocity, direction(opponent, self.info.ball)) > 0.5 ): if distance(car.position, self.info.ball.position) < 200: self.flicking = True else: self.finished = True else: self.flick.step(dt) self.controls = self.flick.controls self.finished = self.flick.finished def render(self, draw: DrawingTool): if not self.flicking: self.carry.render(draw)
def initialize_agent(self): """Initializing all parameters which require the field info""" self.my_goal = Goal(self.team, self.get_field_info()) self.their_goal = Goal(1 - self.team, self.get_field_info()) init_boostpads(self) """Setting all the mechanics to not none""" self.drive = Drive(self.info.my_car) self.dodge = Dodge(self.info.my_car) self.halfflip = HalfFlip(self.info.my_car)
def dodge_simulation(end_condition=None, car=None, hitbox_class=None, dodge=None, ball=None, game_info=None, boost=True): ''' Simulates an RLU dodge until the dodge ends, or one of pass_condition or fail_condtion are met. pass_condition means that the dodge does what we wanted. Returns True and the RLU car state at the end fail_condition returns (False, None), meaning the dodge doesn't achieve the desired result. ''' #Copy everything we need and set constants time = 0 dt = 1 / 60 car_copy = RLU_Car(car) dodge_copy = RLU_Dodge(car_copy) if dodge.target != None: dodge_copy.target = dodge.target if dodge.direction != None: dodge_copy.direction = dodge.direction if dodge.preorientation != None: dodge_copy.preorientation = dodge.preorientation if dodge.duration != None: dodge_copy.duration = dodge.duration else: dodge_copy.duration = 0 #Make sure there's time between the jump and the dodge so that we don't just keep holding jump if dodge.delay != None: dodge_copy.delay = dodge.delay else: dodge_copy.delay = max(dodge_copy.duration + 2 * dt, 0.05) #Adjust for non-octane hitboxes box = update_hitbox(car_copy, hitbox_class) #Loop until we hit end_condition or the dodge is over. while not end_condition(time, box, ball, game_info.team_sign): #Update simulations and adjust hitbox again time += dt dodge_copy.step(dt) controls = dodge_copy.controls if boost: controls.boost = 1 car_copy.step(controls, dt) box = update_hitbox(car_copy, hitbox_class) if dodge_copy.finished: #If the dodge never triggers condition, give up and move on #TODO: give up sooner to save computation time return Simulation() return Simulation(ball_contact=True, car=car_copy, box=box, time=time)
def __init__(self, car: Car, info: GameInfo, target: vec3): super().__init__(car) self.target = target self.info = info self.carry = Carry(car, info.ball, target) self.flick = Dodge(car) self.flick.duration = 0.15 self.flick.target = target self.flicking = False
def __init__(self, car: Car, info: GameInfo): super().__init__(car) self.info = info self.drive = Drive(car) self.drive.target_speed = 2300 self.dodge = Dodge(car) self.dodge.duration = 0.1 self.dodge.direction = normalize(info.their_goal) self.phase = 0
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.game.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state if self.state == State.RESET: self.timer = 0.0 self.set_gamestate_straight_moving() # self.set_gamestate_angled_stationary() # self.set_gamestate_straight_moving_towards() next_state = State.WAIT if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE if self.state == State.INITIALIZE: self.drive = Drive(self.game.my_car) self.drive.target, self.drive.speed = self.game.ball.location, 2300 next_state = State.DRIVING if self.state == State.DRIVING: self.drive.target = self.game.ball.location self.drive.step(self.game.time_delta) self.controls = self.drive.controls can_dodge, simulated_duration, simulated_target = self.simulate() if can_dodge: self.dodge = Dodge(self.game.my_car) self.turn = AerialTurn(self.game.my_car) print("============") print(simulated_duration) self.dodge.duration = simulated_duration - 0.1 self.dodge.target = simulated_target self.timer = 0 next_state = State.DODGING if self.state == State.DODGING: self.dodge.step(self.game.time_delta) self.controls = self.dodge.controls if self.game.time == packet.game_ball.latest_touch.time_seconds: print(self.timer) if self.dodge.finished and self.game.my_car.on_ground: next_state = State.RESET self.timer += self.game.time_delta self.state = next_state return self.controls
class HalfFlip: """ """ def __init__(self, car: Car, use_boost=False): self.car = car self.use_boost = use_boost self.controls = Input() self.dodge = Dodge(car) self.dodge.jump_duration = 0.12 self.dodge.direction = vec2(car.forward() * (-1)) self.s = 0.95 * sgn( dot(self.car.angular_velocity, self.car.up()) + 0.01) self.timer = 0.0 self.finished = False def interruptible(self) -> bool: return False def step(self, dt): boost_delay = 0.4 stall_start = 0.50 stall_end = 0.70 timeout = 2.0 self.dodge.step(dt) self.controls = self.dodge.controls if stall_start < self.timer < stall_end: self.controls.roll = 0.0 self.controls.pitch = -1.0 self.controls.yaw = 0.0 if self.timer > stall_end: self.controls.roll = self.s self.controls.pitch = -1.0 self.controls.yaw = self.s if self.use_boost and self.timer > boost_delay: self.controls.boost = 1 else: self.controls.boost = 0 self.timer += dt self.finished = (self.timer > timeout) or (self.car.on_ground and self.timer > 0.5)
def step(self, dt): car = self.car target = ground(self.target) car_vel = norm(car.velocity) time_left = (distance(car, target) - self.finish_distance) / max(car_vel + 500, 1400) vf = dot(car.forward(), car.velocity) if self.driving and car.on_ground: self.action.target_pos = target self._time_on_ground += dt if self._time_on_ground > 0.2 and car.position[2] < 200 and angle_to(car, target, vf < 0) < 0.1: if vf > 0: if car_vel > 1000 and (not self.waste_boost or car.boost < 10): if time_left > self.dodge_duration: dodge = Dodge(car) dodge.duration = 0.05 dodge.direction = vec2(direction(car, target)) self.action = dodge self.driving = False elif time_left > self.wavedash_duration: wavedash = Wavedash(car) wavedash.direction = vec2(direction(car, target)) self.action = wavedash self.driving = False elif time_left > self.halflip_duration and car_vel > 800: self.action = HalfFlip(car, self.waste_boost and time_left > 3) self.driving = False self.action.step(dt) self.controls = self.action.controls if self.driving and not car.on_ground: self.controls.boost = False if self.action.finished and not self.driving: self.driving = True self._time_on_ground = 0 self.action = self.drive self.drive.backwards = False if distance(car, target) < self.finish_distance and self.driving: self.finished = True if not self.waste_boost and car.boost < 70: self.controls.boost = 0
def simulate(self): ball_prediction = self.get_ball_prediction_struct() duration_estimate = math.floor( get_time_at_height(self.game.ball.location[2], 0.2) * 10) / 10 for i in range(6): car = Car(self.game.my_car) ball = Ball(self.game.ball) batmobile = obb() batmobile.half_width = vec3(64.4098892211914, 42.335182189941406, 14.697200775146484) batmobile.center = car.location + dot(car.rotation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.rotation dodge = Dodge(car) dodge.duration = duration_estimate + i / 60 dodge.target = ball.location for j in range(round(60 * dodge.duration)): dodge.target = ball.location dodge.step(1 / 60) car.step(dodge.controls, 1 / 60) prediction_slice = ball_prediction.slices[j] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) dodge.target = ball_location batmobile.center = car.location + dot(car.rotation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.rotation if intersect(sphere(ball_location, 93.15), batmobile) and abs( ball_location[2] - car.location[2] ) < 25 and car.location[2] < ball_location[2]: return True, j / 60, ball_location return False, None, None
class DiagonalKickoff(Maneuver): '''Dodge forward once to get there faster.''' def __init__(self, car: Car, info: GameInfo): super().__init__(car) self.info = info self.drive = Drive(car) self.drive.target_speed = 2300 self.dodge = Dodge(car) self.dodge.duration = 0.1 self.dodge.direction = normalize(info.their_goal) self.phase = 0 def step(self, dt): if self.phase == 0: self.controls.throttle = 1 self.controls.boost = 1 if ground_distance(self.car, self.info.ball) < 2950: print("entering phase 1") self.phase = 1 if self.phase == 1: self.dodge.step(dt) self.controls = self.dodge.controls if self.dodge.finished and self.car.on_ground: print("entering phase 2") self.phase = 2 self.dodge = Dodge(self.car) self.dodge.duration = 0.18 self.dodge.direction = direction(self.car.position, self.info.ball.position) if self.phase == 2: self.drive.step(dt) self.controls = self.drive.controls if distance(self.car, self.info.ball) < 850: print("entering phase 3") self.phase = 3 if self.phase == 3: self.dodge.step(dt) self.controls = self.dodge.controls self.finished = self.info.ball.position[0] != 0 and self.dodge.finished def render(self, draw: DrawingTool): pass
def __init__(self, car: Car, use_boost=False): self.car = car self.use_boost = use_boost self.controls = Input() self.dodge = Dodge(car) self.dodge.duration = 0.12 self.dodge.direction = vec2(car.forward() * (-1)) self.s = 0.95 * sgn( dot(self.car.angular_velocity, self.car.up()) + 0.01) self.timer = 0.0 self.finished = False
def setup_first_dodge(agent, duration, delay, target, preorientation): agent.dodge = Dodge(agent.info.my_car) agent.turn = AerialTurn(agent.info.my_car) agent.dodge.duration = duration agent.dodge.delay = delay agent.dodge.target = target agent.dodge.preorientation = preorientation agent.timer = 0.0 agent.step = Step.Dodge_1
class Hypebot(BaseAgent): """Main bot class""" def __init__(self, name, team, index): """Initializing all parameters of the bot""" super().__init__(name, team, index) Game.set_mode("soccar") self.info = Game(index, team) self.team = team self.index = index self.drive = None self.dodge = None self.halfflip = None self.controls = SimpleControllerState() self.kickoff = False self.prev_kickoff = False self.in_front_off_ball = False self.conceding = False self.kickoff_Start = None self.step = Step.Shooting self.time = 0 self.my_goal = None self.their_goal = None self.teammates = [] self.has_to_go = False self.closest_to_ball = False self.defending = False self.set_state = False self.ball_prediction_np = [] def initialize_agent(self): """Initializing all parameters which require the field info""" self.my_goal = Goal(self.team, self.get_field_info()) self.their_goal = Goal(1 - self.team, self.get_field_info()) init_boostpads(self) """Setting all the mechanics to not none""" self.drive = Drive(self.info.my_car) self.dodge = Dodge(self.info.my_car) self.halfflip = HalfFlip(self.info.my_car) def get_output(self, packet: GameTickPacket) -> SimpleControllerState: """The main method which receives the packets and outputs the controls""" self.info.read_game_information(packet, self.get_field_info()) self.in_front_off_ball = in_front_off_ball(self.info.my_car.position, self.info.ball.position, self.my_goal.center) update_boostpads(self, packet) self.closest_to_ball = self.closest_to_the_ball() self.predict() self.time += self.info.time_delta if self.time > 5 and self.set_state: ball_state = BallState(Physics(location=Vector3(0, 5250, 250))) game_state = GameState(ball=ball_state) self.set_state = False self.set_game_state(game_state) dtype = [('physics', [('location', '<f4', 3), ('rotation', [('pitch', '<f4'), ('yaw', '<f4'), ('roll', '<f4')]), ('velocity', '<f4', 3), ('angular_velocity', '<f4', 3)]), ('game_seconds', '<f4')] self.ball_prediction_np = np.ctypeslib.as_array( self.get_ball_prediction_struct().slices).view( dtype)[:self.get_ball_prediction_struct().num_slices] self.teammates = [] for i in range(self.info.num_cars): if self.info.cars[i].team == self.team and i != self.index: self.teammates.append(i) self.time = packet.game_info.seconds_elapsed # self.handle_match_comms() self.prev_kickoff = self.kickoff self.kickoff = packet.game_info.is_kickoff_pause and distance_2d( self.info.ball.position, vec3(0, 0, 0)) < 100 if self.kickoff and not self.prev_kickoff: # if not self.close_to_kickoff_spawn(): # return if len(self.teammates) > 0: if self.closest_to_ball: init_kickoff(self) self.has_to_go = True else: self.drive.target = get_closest_big_pad(self).location self.drive.speed = 1399 else: init_kickoff(self) self.has_to_go = True if (self.kickoff or self.step == "Dodge2") and self.has_to_go: kick_off(self) elif self.kickoff and not self.has_to_go: self.drive.step(self.info.time_delta) self.controls = self.drive.controls else: if self.has_to_go: self.has_to_go = False self.get_controls() self.render_string(self.step.name) # Make sure there is no variance in kickoff setups if not packet.game_info.is_round_active: self.controls.steer = 0 return self.controls def predict(self): """Method which uses ball prediction to fill in future data""" self.bounces = [] self.ball_bouncing = False ball_prediction = self.get_ball_prediction_struct() if ball_prediction is not None: prev_ang_velocity = normalize(self.info.ball.angular_velocity) for i in range(ball_prediction.num_slices): prediction_slice = ball_prediction.slices[i] physics = prediction_slice.physics if physics.location.y * sign(self.team) > 5120: self.conceding = True if physics.location.z > 180: self.ball_bouncing = True continue current_ang_velocity = normalize( vec3(physics.angular_velocity.x, physics.angular_velocity.y, physics.angular_velocity.z)) if physics.location.z < 125 and prev_ang_velocity != current_ang_velocity: self.bounces.append( (vec3(physics.location.x, physics.location.y, physics.location.z), prediction_slice.game_seconds - self.time)) if len(self.bounces) > 15: return prev_ang_velocity = current_ang_velocity def closest_to_the_ball(self): dist_to_ball = math.inf for i in range(len(self.teammates)): teammate_car = self.info.cars[self.teammates[i]] if distance_2d(teammate_car.position, get_intersect(self, teammate_car)) < dist_to_ball: dist_to_ball = distance_2d(teammate_car.position, get_intersect(self, teammate_car)) return distance_2d(self.info.my_car.position, get_intersect(self, self.info.my_car)) <= dist_to_ball def get_controls(self): """Decides what strategy to uses and gives corresponding output""" if self.step == Step.Steer or self.step == Step.Dodge_2 or self.step == Step.Dodge_1 or self.step == Step.Drive: print("GETCONTROLS") # self.time = 0 # self.set_state = True self.step = Step.Shooting if self.step == Step.Shooting: target = get_intersect(self, self.info.my_car) self.drive.target = target self.drive.step(self.info.time_delta) self.controls = self.drive.controls t = time.time() can_dodge, simulated_duration, simulated_target = self.simulate( self.their_goal.center) # print(time.time() - t) if can_dodge: self.dodge = Dodge(self.info.my_car) self.turn = AerialTurn(self.info.my_car) self.dodge.duration = simulated_duration - 0.1 self.dodge.direction = vec2(self.their_goal.center - simulated_target) target = vec3(vec2(self.their_goal.center)) + vec3( 0, 0, jeroens_magic_number * simulated_target[2]) self.dodge.preorientation = look_at(target - simulated_target, vec3(0, 0, 1)) self.step = Step.Dodge if self.should_defend(): self.step = Step.Defending elif not self.closest_to_ball or self.in_front_off_ball: self.step = Step.Rotating elif should_halfflip(self, target): self.step = Step.HalfFlip self.halfflip = HalfFlip(self.info.my_car) elif should_dodge(self, target): self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.target = target self.dodge.duration = 0.1 elif self.step == Step.Rotating: target = 0.5 * (self.info.ball.position - self.my_goal.center) + self.my_goal.center self.drive.target = target self.drive.speed = 1410 self.drive.step(self.info.time_delta) self.controls = self.drive.controls in_position = not not_back(self.info.my_car.position, self.info.ball.position, self.my_goal.center) faster = self.closest_to_ball and in_position if len(self.teammates) == 0 and in_position: self.step = Step.Shooting elif len(self.teammates) == 1: teammate = self.info.cars[self.teammates[0]].position teammate_out_location = not_back(teammate, self.info.ball.position, self.my_goal.center) if teammate_out_location or faster: self.step = Step.Shooting elif len(self.teammates) == 2: teammate1 = self.info.cars[self.teammates[0]].position teammate2 = self.info.cars[self.teammates[0]].position teammate1_out_location = not_back(teammate1, self.info.ball.position, self.my_goal.center) teammate2_out_location = not_back(teammate2, self.info.ball.position, self.my_goal.center) if teammate1_out_location and teammate2_out_location: self.step = Step.Shooting elif (teammate1_out_location or teammate2_out_location) and faster or faster: self.step = Step.Shooting if self.should_defend(): self.step = Step.Defending elif should_halfflip(self, target): self.step = Step.HalfFlip self.halfflip = HalfFlip(self.info.my_car) elif should_dodge(self, target): self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.target = target self.dodge.duration = 0.1 elif self.step == Step.Defending: defending(self) elif self.step == Step.Dodge or self.step == Step.HalfFlip: halfflipping = self.step == Step.HalfFlip if halfflipping: self.halfflip.step(self.info.time_delta) else: self.dodge.step(self.info.time_delta) if (self.halfflip.finished if halfflipping else self.dodge.finished) and self.info.my_car.on_ground: self.step = Step.Shooting else: self.controls = (self.halfflip.controls if halfflipping else self.dodge.controls) if not halfflipping: self.controls.boost = False self.controls.throttle = velocity_2d( self.info.my_car.velocity) < 500 def handle_match_comms(self): try: msg = self.matchcomms.incoming_broadcast.get_nowait() except Empty: return if handle_set_attributes_message( msg, self, allowed_keys=['kickoff', 'prev_kickoff']): reply_to(self.matchcomms, msg) else: self.logger.debug('Unhandled message: {msg}') def render_string(self, string): """Rendering method mainly used to show the current state""" self.renderer.begin_rendering('The State') if self.step == Step.Dodge_1: self.renderer.draw_line_3d(self.info.my_car.position, self.dodge.target, self.renderer.black()) self.renderer.draw_line_3d(self.info.my_car.position, self.drive.target, self.renderer.blue()) if self.index == 0: self.renderer.draw_string_2d(20, 20, 3, 3, string, self.renderer.red()) else: self.renderer.draw_string_2d(20, 520, 3, 3, string, self.renderer.red()) self.renderer.end_rendering() # The miraculous simulate function # TODO optimize heavily in case I actually need it # Option one: estimate the time for the current height and look at that ball prediction. # If its heigher use that unless it gets unreachable and else compare with the lower one. # If duration_estimate = 0.8 and the ball is moving up there is not sense in even simulating it. # Might even lower it since the higher the duration estimate the longer the simulation takes. def simulate(self, global_target=None): lol = 0 # Initialize the ball prediction # Estimate the probable duration of the jump and round it down to the floor decimal ball_prediction = self.get_ball_prediction_struct() if self.info.my_car.boost < 6: duration_estimate = math.floor( get_time_at_height(self.info.ball.position[2]) * 10) / 10 else: adjacent = norm( vec2(self.info.my_car.position - self.info.ball.position)) opposite = (self.info.ball.position[2] - self.info.my_car.position[2]) theta = math.atan(opposite / adjacent) t = get_time_at_height_boost(self.info.ball.position[2], theta, self.info.my_car.boost) duration_estimate = (math.ceil(t * 10) / 10) # Loop for 6 frames meaning adding 0.1 to the estimated duration. Keeps the time constraint under 0.3s for i in range(6): # Copy the car object and reset the values for the hitbox car = Car(self.info.my_car) # Create a dodge object on the copied car object # Direction is from the ball to the enemy goal # Duration is estimated duration plus the time added by the for loop # preorientation is the rotation matrix from the ball to the goal # TODO make it work on both sides # Test with preorientation. Currently it still picks a low duration at a later time meaning it # wont do any of the preorientation. dodge = Dodge(car) prediction_slice = ball_prediction.slices[round( 60 * (duration_estimate + i / 60))] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) # ball_location = vec3(0, ball_y, ball_z) dodge.duration = duration_estimate + i / 60 if dodge.duration > 1.4: break if global_target is not None: dodge.direction = vec2(global_target - ball_location) target = vec3(vec2(global_target)) + vec3( 0, 0, jeroens_magic_number * ball_location[2]) dodge.preorientation = look_at(target - ball_location, vec3(0, 0, 1)) else: dodge.target = ball_location dodge.direction = vec2(ball_location) + vec2(ball_location - car.position) dodge.preorientation = look_at(ball_location, vec3(0, 0, 1)) # Loop from now till the end of the duration fps = 30 for j in range(round(fps * dodge.duration)): lol = lol + 1 # Get the ball prediction slice at this time and convert the location to RLU vec3 prediction_slice = ball_prediction.slices[round(60 * j / fps)] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) dodge.step(1 / fps) T = dodge.duration - dodge.timer if T > 0: if dodge.timer < 0.2: dodge.controls.boost = 1 dodge.controls.pitch = 1 else: xf = car.position + 0.5 * T * T * vec3( 0, 0, -650) + T * car.velocity delta_x = ball_location - xf if angle_between(vec2(car.forward()), dodge.direction) < 0.3: if norm(delta_x) > 50: dodge.controls.boost = 1 dodge.controls.throttle = 0.0 else: dodge.controls.boost = 0 dodge.controls.throttle = clip( 0.5 * (200 / 3) * T * T, 0.0, 1.0) else: dodge.controls.boost = 0 dodge.controls.throttle = 0.0 else: dodge.controls.boost = 0 car.step(dodge.controls, 1 / fps) succesfull = self.dodge_succesfull(car, ball_location, dodge) if succesfull is not None: if succesfull: return True, j / fps, ball_location else: break return False, None, None def dodge_succesfull(self, car, ball_location, dodge): batmobile = obb() batmobile.half_width = vec3(64.4098892211914, 42.335182189941406, 14.697200775146484) batmobile.center = car.position + dot(car.orientation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.orientation ball = sphere(ball_location, 93.15) b_local = dot(ball.center - batmobile.center, batmobile.orientation) closest_local = vec3( min(max(b_local[0], -batmobile.half_width[0]), batmobile.half_width[0]), min(max(b_local[1], -batmobile.half_width[1]), batmobile.half_width[1]), min(max(b_local[2], -batmobile.half_width[2]), batmobile.half_width[2])) hit_location = dot(batmobile.orientation, closest_local) + batmobile.center if norm(hit_location - ball.center) > ball.radius: return None # if abs(ball_location[2] - hit_location[2]) < 25 and hit_location[2] < ball_location[2]: if abs(ball_location[2] - hit_location[2]) < 25: if closest_local[0] > 35 and -12 < closest_local[2] < 12: hit_check = True else: print("local: ", closest_local) hit_check = True else: hit_check = False # Seems to work without angle_check. No clue why though angle_car_simulation = angle_between(car.orientation, self.info.my_car.orientation) angle_simulation_target = angle_between(car.orientation, dodge.preorientation) angle_check = angle_simulation_target < angle_car_simulation or angle_simulation_target < 0.1 return hit_check def should_defend(self): """Method which returns a boolean regarding whether we should defend or not""" ball = self.info.ball car = self.info.my_car car_to_ball = ball.position - car.position in_front_of_ball = self.in_front_off_ball backline_intersect = line_backline_intersect(self.my_goal.center[1], vec2(car.position), vec2(car_to_ball)) return (in_front_of_ball and abs(backline_intersect) < 2000) or self.conceding def close_to_kickoff_spawn(self): blue_one = distance_2d(self.info.my_car.position, vec3( -2048, -2560, 18)) < 10 blue_two = distance_2d(self.info.my_car.position, vec3( 2048, -2560, 18)) < 10 blue_three = distance_2d(self.info.my_car.position, vec3(-256, -3840, 18)) < 10 blue_four = distance_2d(self.info.my_car.position, vec3( 256, -3840, 18)) < 10 blue_five = distance_2d(self.info.my_car.position, vec3(0, -4608, 18)) < 10 blue = blue_one or blue_two or blue_three or blue_four or blue_five orange_one = distance_2d(self.info.my_car.position, vec3(-2048, 2560, 18)) < 10 orange_two = distance_2d(self.info.my_car.position, vec3( 2048, 2560, 18)) < 10 orange_three = distance_2d(self.info.my_car.position, vec3(-256, 3840, 18)) < 10 orange_four = distance_2d(self.info.my_car.position, vec3( 256, 3840, 18)) < 10 orange_five = distance_2d(self.info.my_car.position, vec3(0, 4608, 18)) < 10 orange = orange_one or orange_two or orange_three or orange_four or orange_five return orange or blue
def kick_off(agent): ball = agent.info.ball car = agent.info.my_car t = distance_2d(ball.position, car.position) / 2200 batmobile_resting = 18.65 robbies_constant = (ball.position - vec3(0, 0, 92.75 - batmobile_resting) - car.position - car.velocity * t) * 2 * t**-2 robbies_boost_constant = dot(normalize(xy( car.forward())), normalize( xy(robbies_constant))) > (0.3 if car.on_ground else 0.1) """"Module that performs the kickoffs""" if agent.kickoffStart == "Diagonal": if agent.step is Step.Drive: agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if agent.drive.finished: ball_location = ball.position + vec3( 0, -sign(agent.team) * 500, 0) target = car.position + 250 * normalize(ball_location - car.position) agent.drive = Drive(car) agent.drive.target = target agent.drive.speed = 2400 agent.step = Step.Drive_1 if agent.step is Step.Drive_1: agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if agent.drive.finished: target = vec3( dot( rotation( math.radians(-sign(agent.info.team) * sign(car.position[0]) * 60)), vec2(car.forward())) * 10000) preorientation = dot( axis_to_rotation( vec3( 0, 0, math.radians(-sign(agent.info.team) * -sign(car.position[0]) * 30))), car.orientation) setup_first_dodge(agent, 0.05, 0.3, target, preorientation) elif agent.step is Step.Dodge_1: agent.timer += agent.info.time_delta if agent.timer > 0.8: lerp_var = lerp( normalize(robbies_constant), normalize(ball.position - vec3(0, 0, 92.75 - batmobile_resting) - car.position), 0.8) agent.turn.target = look_at(lerp_var, vec3(0, 0, 1)) agent.turn.step(agent.info.time_delta) agent.controls = agent.turn.controls if car.on_ground: agent.time = 0 agent.set_state = True agent.step = Step.Shooting else: agent.dodge.step(agent.info.time_delta) agent.controls = agent.dodge.controls agent.controls.boost = robbies_boost_constant elif agent.kickoffStart == "Center": if agent.step is Step.Drive: agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if agent.drive.finished: target = vec3( dot(rotation(math.radians(-65)), vec2(car.forward())) * 10000) preorientation = dot( axis_to_rotation(vec3(0, 0, math.radians(45))), car.orientation) setup_first_dodge(agent, 0.05, 0.4, target, preorientation) elif agent.step is Step.Dodge_1: agent.timer += agent.info.time_delta if agent.timer > 0.8: agent.turn.target = look_at(xy(ball.position - car.position), vec3(0, 0, 1)) agent.turn.step(agent.info.time_delta) agent.controls = agent.turn.controls set_steer(agent) else: agent.dodge.step(agent.info.time_delta) agent.controls = agent.dodge.controls agent.controls.boost = robbies_boost_constant elif agent.step is Step.Steer: agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if distance_2d(car.position, ball.position) < 800: agent.step = Step.Dodge_2 agent.dodge = Dodge(car) agent.dodge.duration = 0.075 agent.dodge.target = ball.position elif agent.step is Step.Dodge_2: agent.dodge.step(agent.info.time_delta) agent.controls = agent.dodge.controls if agent.dodge.finished and car.on_ground: agent.time = 0 agent.set_state = True agent.step = Step.Shooting elif agent.kickoffStart == "offCenter": if agent.step is Step.Drive: agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if distance_2d(car.position, agent.drive.target) < 650: target = vec3( dot( rotation( math.radians(-sign(agent.info.team) * -sign(car.position[0]) * 100)), vec2(car.forward())) * 10000) preorientation = dot( axis_to_rotation( vec3( 0, 0, math.radians(-sign(agent.info.team) * sign(car.position[0]) * 30))), car.orientation) print("PYTHON: ", agent.info.my_car.position) print( "PYTHON: ", math.radians(-sign(agent.info.team) * -sign(car.position[0]) * 100)) setup_first_dodge(agent, 0.05, 0.4, target, preorientation) elif agent.step is Step.Dodge_1: agent.timer += agent.info.time_delta if agent.timer > 0.8: lerp_var = lerp( normalize(robbies_constant), normalize(ball.position - vec3(0, 0, 92.75 - batmobile_resting) - car.position), 0.25) agent.turn.target = look_at(lerp_var, vec3(0, 0, 1)) agent.turn.step(agent.info.time_delta) agent.controls = agent.turn.controls set_steer(agent) else: agent.dodge.step(agent.info.time_delta) agent.controls = agent.dodge.controls agent.controls.boost = robbies_boost_constant elif agent.step is Step.Steer: agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls if distance_2d(ball.position, car.position) < 800: agent.step = Step.Dodge_2 agent.dodge = Dodge(car) agent.dodge.duration = 0.075 agent.dodge.target = ball.position elif agent.step is Step.Dodge_2: agent.dodge.step(agent.info.time_delta) agent.controls = agent.dodge.controls if agent.dodge.finished and car.on_ground: agent.time = 0 agent.set_state = True agent.step = Step.Shooting
def get_controls(self): """Decides what strategy to uses and gives corresponding output""" if self.step == Step.Steer or self.step == Step.Dodge_2 or self.step == Step.Dodge_1 or self.step == Step.Drive: print("GETCONTROLS") # self.time = 0 # self.set_state = True self.step = Step.Shooting if self.step == Step.Shooting: target = get_intersect(self, self.info.my_car) self.drive.target = target self.drive.step(self.info.time_delta) self.controls = self.drive.controls t = time.time() can_dodge, simulated_duration, simulated_target = self.simulate( self.their_goal.center) # print(time.time() - t) if can_dodge: self.dodge = Dodge(self.info.my_car) self.turn = AerialTurn(self.info.my_car) self.dodge.duration = simulated_duration - 0.1 self.dodge.direction = vec2(self.their_goal.center - simulated_target) target = vec3(vec2(self.their_goal.center)) + vec3( 0, 0, jeroens_magic_number * simulated_target[2]) self.dodge.preorientation = look_at(target - simulated_target, vec3(0, 0, 1)) self.step = Step.Dodge if self.should_defend(): self.step = Step.Defending elif not self.closest_to_ball or self.in_front_off_ball: self.step = Step.Rotating elif should_halfflip(self, target): self.step = Step.HalfFlip self.halfflip = HalfFlip(self.info.my_car) elif should_dodge(self, target): self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.target = target self.dodge.duration = 0.1 elif self.step == Step.Rotating: target = 0.5 * (self.info.ball.position - self.my_goal.center) + self.my_goal.center self.drive.target = target self.drive.speed = 1410 self.drive.step(self.info.time_delta) self.controls = self.drive.controls in_position = not not_back(self.info.my_car.position, self.info.ball.position, self.my_goal.center) faster = self.closest_to_ball and in_position if len(self.teammates) == 0 and in_position: self.step = Step.Shooting elif len(self.teammates) == 1: teammate = self.info.cars[self.teammates[0]].position teammate_out_location = not_back(teammate, self.info.ball.position, self.my_goal.center) if teammate_out_location or faster: self.step = Step.Shooting elif len(self.teammates) == 2: teammate1 = self.info.cars[self.teammates[0]].position teammate2 = self.info.cars[self.teammates[0]].position teammate1_out_location = not_back(teammate1, self.info.ball.position, self.my_goal.center) teammate2_out_location = not_back(teammate2, self.info.ball.position, self.my_goal.center) if teammate1_out_location and teammate2_out_location: self.step = Step.Shooting elif (teammate1_out_location or teammate2_out_location) and faster or faster: self.step = Step.Shooting if self.should_defend(): self.step = Step.Defending elif should_halfflip(self, target): self.step = Step.HalfFlip self.halfflip = HalfFlip(self.info.my_car) elif should_dodge(self, target): self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.target = target self.dodge.duration = 0.1 elif self.step == Step.Defending: defending(self) elif self.step == Step.Dodge or self.step == Step.HalfFlip: halfflipping = self.step == Step.HalfFlip if halfflipping: self.halfflip.step(self.info.time_delta) else: self.dodge.step(self.info.time_delta) if (self.halfflip.finished if halfflipping else self.dodge.finished) and self.info.my_car.on_ground: self.step = Step.Shooting else: self.controls = (self.halfflip.controls if halfflipping else self.dodge.controls) if not halfflipping: self.controls.boost = False self.controls.throttle = velocity_2d( self.info.my_car.velocity) < 500
class MyAgent(BaseAgent): def __init__(self, name, team, index): super().__init__(name, team, index) self.game = Game(index, team) self.name = name self.controls = SimpleControllerState() self.timer = 0.0 self.drive = Drive(self.game.my_car) self.navigator = None self.dodge = None self.turn = None self.state = State.RESET def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.game.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state if self.state == State.RESET: self.timer = 0.0 self.set_gamestate_straight_moving() # self.set_gamestate_angled_stationary() # self.set_gamestate_straight_moving_towards() next_state = State.WAIT if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE if self.state == State.INITIALIZE: self.drive = Drive(self.game.my_car) self.drive.target, self.drive.speed = self.game.ball.location, 2300 next_state = State.DRIVING if self.state == State.DRIVING: self.drive.target = self.game.ball.location self.drive.step(self.game.time_delta) self.controls = self.drive.controls can_dodge, simulated_duration, simulated_target = self.simulate() if can_dodge: self.dodge = Dodge(self.game.my_car) self.turn = AerialTurn(self.game.my_car) print("============") print(simulated_duration) self.dodge.duration = simulated_duration - 0.1 self.dodge.target = simulated_target self.timer = 0 next_state = State.DODGING if self.state == State.DODGING: self.dodge.step(self.game.time_delta) self.controls = self.dodge.controls if self.game.time == packet.game_ball.latest_touch.time_seconds: print(self.timer) if self.dodge.finished and self.game.my_car.on_ground: next_state = State.RESET self.timer += self.game.time_delta self.state = next_state return self.controls def simulate(self): ball_prediction = self.get_ball_prediction_struct() duration_estimate = math.floor( get_time_at_height(self.game.ball.location[2], 0.2) * 10) / 10 for i in range(6): car = Car(self.game.my_car) ball = Ball(self.game.ball) batmobile = obb() batmobile.half_width = vec3(64.4098892211914, 42.335182189941406, 14.697200775146484) batmobile.center = car.location + dot(car.rotation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.rotation dodge = Dodge(car) dodge.duration = duration_estimate + i / 60 dodge.target = ball.location for j in range(round(60 * dodge.duration)): dodge.target = ball.location dodge.step(1 / 60) car.step(dodge.controls, 1 / 60) prediction_slice = ball_prediction.slices[j] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) dodge.target = ball_location batmobile.center = car.location + dot(car.rotation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.rotation if intersect(sphere(ball_location, 93.15), batmobile) and abs( ball_location[2] - car.location[2] ) < 25 and car.location[2] < ball_location[2]: return True, j / 60, ball_location return False, None, None def set_gamestate_straight_moving(self): # put the car in the middle of the field car_state = CarState( physics=Physics(location=Vector3(0, -1000, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, math.pi / 2, 0), angular_velocity=Vector3(0, 0, 0))) # put the ball in the middle of the field ball_state = BallState( physics=Physics(location=Vector3(0, 1500, 93), velocity=Vector3(0, random.randint(-250, 800), random.randint(700, 800)), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0))) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) def set_gamestate_straight_moving_towards(self): # put the car in the middle of the field car_state = CarState(physics=Physics( location=Vector3(0, 0, 18), velocity=Vector3(0, 0, 0), angular_velocity=Vector3(0, 0, 0), )) # put the ball in the middle of the field ball_state = BallState(physics=Physics( location=Vector3(0, 2500, 93), velocity=Vector3(0, -250, 700), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0), )) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) def set_gamestate_angled_stationary(self): # put the car in the middle of the field car_state = CarState( physics=Physics(location=Vector3(-1000, -1500, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, math.pi / 8, 0), angular_velocity=Vector3(0, 0, 0))) # put the ball in the middle of the field ball_state = BallState( physics=Physics(location=Vector3(0, 0, 750), velocity=Vector3(0, 0, 1), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0))) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state}))
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: # Update the game values and set the state self.game.read_game_information(packet, self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state # Reset everything if self.state == State.RESET: self.timer = 0.0 # self.set_gamestate_straight_moving() # self.set_gamestate_straight_moving_towards() self.set_state_stationary_angled() # self.set_gamestate_angled_stationary() # self.set_state_stationary() next_state = State.WAIT # Wait so everything can settle in, mainly for ball prediction if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE # Initialize the drive mechanic if self.state == State.INITIALIZE: self.drive = Drive(self.game.my_car) self.drive.target = self.game.ball.position self.drive.speed = 1400 next_state = State.DRIVING # Start driving towards the target and check whether a dodge is possible, if so initialize the dodge if self.state == State.DRIVING: self.drive.target = self.game.ball.position self.drive.step(self.game.time_delta) self.controls = self.drive.controls a = time.time() target = self.game.my_car.position + 1000000 * ( self.game.ball.position - self.game.my_car.position) can_dodge, simulated_duration, simulated_target = self.simulate() print(time.time() - a) if can_dodge: self.dodge = Dodge(self.game.my_car) self.turn = AerialTurn(self.game.my_car) self.dodge.duration = simulated_duration - 0.1 self.dodge.target = simulated_target self.dodge.preorientation = look_at(simulated_target, vec3(0, 0, 1)) self.timer = 0 next_state = State.DODGING # Perform the dodge if self.state == State.DODGING: self.dodge.step(self.game.time_delta) self.controls = self.dodge.controls T = self.dodge.duration - self.dodge.timer if T > 0: if self.dodge.timer < 0.2: self.controls.boost = 1 # self.controls.pitch = 1 else: xf = self.game.my_car.position + 0.5 * T * T * vec3( 0, 0, -650) + T * self.game.my_car.velocity delta_x = self.game.ball.position - xf if angle_between(vec2(self.game.my_car.forward()), self.dodge.direction) < 0.3: if norm(delta_x) > 50: self.controls.boost = 1 self.controls.throttle = 0.0 else: self.controls.boost = 0 self.controls.throttle = clip( 0.5 * (200 / 3) * T * T, 0.0, 1.0) else: self.controls.boost = 0 self.controls.throttle = 0.0 else: self.controls.boost = 0 # Great line # if self.game.time == packet.game_ball.latest_touch.time_seconds: # print(self.game.my_car.position) if self.dodge.finished and self.game.my_car.on_ground: next_state = State.RESET self.timer += self.game.time_delta self.state = next_state return self.controls
def get_controls(self): """Decides what strategy to uses and gives corresponding output""" self.drive.power_turn = False if self.step is Step.Steer or self.step is Step.Drive: self.step = Step.Catching if self.step is Step.Catching: # Enable power turning for catching, since we don't halfflip self.drive.power_turn = True target = get_bounce(self) if target is None: self.step = Step.Shooting else: self.catching.target = target[0] self.catching.speed = (distance_2d(self.info.my_car.location, target[0]) + 50) / target[1] self.catching.step(self.info.time_delta) self.controls = self.catching.controls ball = self.info.ball car = self.info.my_car if distance_2d(ball.location, car.location) < 150 and 65 < abs( ball.location[2] - car.location[2]) < 127: self.step = Step.Dribbling self.dribble = Dribbling(self.info.my_car, self.info.ball, self.their_goal) if self.defending: self.step = Step.Defending ball = self.info.ball if abs(ball.velocity[2]) < 100 and sign(self.team) * ball.velocity[1] < 0 and sign(self.team) * \ ball.location[1] < 0: self.step = Step.Shooting elif self.step is Step.Dribbling: self.dribble.step() self.controls = self.dribble.controls ball = self.info.ball car = self.info.my_car bot_to_opponent = self.info.cars[ 1 - self.index].location - self.info.my_car.location local_bot_to_target = dot(bot_to_opponent, self.info.my_car.rotation) angle_front_to_target = math.atan2(local_bot_to_target[1], local_bot_to_target[0]) opponent_is_near = norm(vec2(bot_to_opponent)) < 2000 opponent_is_in_the_way = math.radians( -10) < angle_front_to_target < math.radians(10) if not (distance_2d(ball.location, car.location) < 150 and 65 < abs(ball.location[2] - car.location[2]) < 127): self.step = Step.Catching if self.defending: self.step = Step.Defending if opponent_is_near and opponent_is_in_the_way: self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.duration = 0.25 self.dodge.target = self.their_goal.center elif self.step is Step.Defending: defending(self) elif self.step in [ Step.Dodge, Step.Dodge_1, Step.Dodge_2, Step.HalfFlip ]: halfflipping = self.step is Step.HalfFlip if halfflipping: self.halfflip.step(self.info.time_delta) else: self.dodge.step(self.info.time_delta) if self.halfflip.finished if halfflipping else self.dodge.finished: self.step = Step.Catching else: self.controls = (self.halfflip.controls if halfflipping else self.dodge.controls) elif self.step is Step.Shooting: shooting(self)
def simulate(self, global_target=None): lol = 0 # Initialize the ball prediction # Estimate the probable duration of the jump and round it down to the floor decimal ball_prediction = self.get_ball_prediction_struct() if self.info.my_car.boost < 6: duration_estimate = math.floor( get_time_at_height(self.info.ball.position[2]) * 10) / 10 else: adjacent = norm( vec2(self.info.my_car.position - self.info.ball.position)) opposite = (self.info.ball.position[2] - self.info.my_car.position[2]) theta = math.atan(opposite / adjacent) t = get_time_at_height_boost(self.info.ball.position[2], theta, self.info.my_car.boost) duration_estimate = (math.ceil(t * 10) / 10) # Loop for 6 frames meaning adding 0.1 to the estimated duration. Keeps the time constraint under 0.3s for i in range(6): # Copy the car object and reset the values for the hitbox car = Car(self.info.my_car) # Create a dodge object on the copied car object # Direction is from the ball to the enemy goal # Duration is estimated duration plus the time added by the for loop # preorientation is the rotation matrix from the ball to the goal # TODO make it work on both sides # Test with preorientation. Currently it still picks a low duration at a later time meaning it # wont do any of the preorientation. dodge = Dodge(car) prediction_slice = ball_prediction.slices[round( 60 * (duration_estimate + i / 60))] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) # ball_location = vec3(0, ball_y, ball_z) dodge.duration = duration_estimate + i / 60 if dodge.duration > 1.4: break if global_target is not None: dodge.direction = vec2(global_target - ball_location) target = vec3(vec2(global_target)) + vec3( 0, 0, jeroens_magic_number * ball_location[2]) dodge.preorientation = look_at(target - ball_location, vec3(0, 0, 1)) else: dodge.target = ball_location dodge.direction = vec2(ball_location) + vec2(ball_location - car.position) dodge.preorientation = look_at(ball_location, vec3(0, 0, 1)) # Loop from now till the end of the duration fps = 30 for j in range(round(fps * dodge.duration)): lol = lol + 1 # Get the ball prediction slice at this time and convert the location to RLU vec3 prediction_slice = ball_prediction.slices[round(60 * j / fps)] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) dodge.step(1 / fps) T = dodge.duration - dodge.timer if T > 0: if dodge.timer < 0.2: dodge.controls.boost = 1 dodge.controls.pitch = 1 else: xf = car.position + 0.5 * T * T * vec3( 0, 0, -650) + T * car.velocity delta_x = ball_location - xf if angle_between(vec2(car.forward()), dodge.direction) < 0.3: if norm(delta_x) > 50: dodge.controls.boost = 1 dodge.controls.throttle = 0.0 else: dodge.controls.boost = 0 dodge.controls.throttle = clip( 0.5 * (200 / 3) * T * T, 0.0, 1.0) else: dodge.controls.boost = 0 dodge.controls.throttle = 0.0 else: dodge.controls.boost = 0 car.step(dodge.controls, 1 / fps) succesfull = self.dodge_succesfull(car, ball_location, dodge) if succesfull is not None: if succesfull: return True, j / fps, ball_location else: break return False, None, None
class Hypebot(BaseAgent): """Main bot class""" def __init__(self, name, team, index): """Initializing all parameters of the bot""" super().__init__(name, team, index) Game.set_mode("soccar") self.info = Game(index, team) self.team = team self.index = index self.defending = False self.conceding = False self.bounces = [] self.drive = None self.catching = None self.dodge = None self.halfflip = None self.dribble = None self.controls = SimpleControllerState() self.kickoff = False self.prev_kickoff = False self.in_front_off_the_ball = False self.kickoff_Start = None self.step = Step.Catching self.time = 0 self.my_goal = None self.their_goal = None self.ball_bouncing = False def initialize_agent(self): """Initializing all parameters which require the field info""" self.my_goal = Goal(self.team, self.get_field_info()) self.their_goal = Goal(1 - self.team, self.get_field_info()) init_boostpads(self) """Setting all the mechanics to not none""" self.drive = Drive(self.info.my_car) self.catching = Drive(self.info.my_car) self.dodge = Dodge(self.info.my_car) self.dribble = Dribbling(self.info.my_car, self.info.ball, self.their_goal) def get_output(self, packet: GameTickPacket) -> SimpleControllerState: """The main method which receives the packets and outputs the controls""" self.time = packet.game_info.seconds_elapsed self.info.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info()) update_boostpads(self, packet) self.predict() # self.handle_match_comms() self.prev_kickoff = self.kickoff self.kickoff = packet.game_info.is_kickoff_pause and distance_2d( self.info.ball.location, vec3(0, 0, 0)) < 100 self.defending = self.should_defending() if self.kickoff and not self.prev_kickoff: # if not self.close_to_kickoff_spawn(): # return init_kickoff(self) self.prev_kickoff = True self.drive.kickoff = True elif self.kickoff or self.step is Step.Dodge_2: kick_off(self) self.drive.kickoff = True else: self.drive.kickoff = False self.get_controls() self.render_string(self.step.name) # Make sure there is no variance in kickoff setups if not packet.game_info.is_round_active: self.controls.steer = 0 return self.controls def predict(self): """Method which uses ball prediction to fill in future data""" self.bounces = [] self.ball_bouncing = False ball_prediction = self.get_ball_prediction_struct() if ball_prediction is not None: prev_ang_velocity = normalize(self.info.ball.angular_velocity) for i in range(ball_prediction.num_slices): prediction_slice = ball_prediction.slices[i] physics = prediction_slice.physics if physics.location.y * sign(self.team) > 5120: self.conceding = True if physics.location.z > 180: self.ball_bouncing = True continue current_ang_velocity = normalize( vec3(physics.angular_velocity.x, physics.angular_velocity.y, physics.angular_velocity.z)) if physics.location.z < 125 and prev_ang_velocity != current_ang_velocity: self.bounces.append( (vec3(physics.location.x, physics.location.y, physics.location.z), prediction_slice.game_seconds - self.time)) if len(self.bounces) > 15: return prev_ang_velocity = current_ang_velocity def get_controls(self): """Decides what strategy to uses and gives corresponding output""" self.drive.power_turn = False if self.step is Step.Steer or self.step is Step.Drive: self.step = Step.Catching if self.step is Step.Catching: # Enable power turning for catching, since we don't halfflip self.drive.power_turn = True target = get_bounce(self) if target is None: self.step = Step.Shooting else: self.catching.target = target[0] self.catching.speed = (distance_2d(self.info.my_car.location, target[0]) + 50) / target[1] self.catching.step(self.info.time_delta) self.controls = self.catching.controls ball = self.info.ball car = self.info.my_car if distance_2d(ball.location, car.location) < 150 and 65 < abs( ball.location[2] - car.location[2]) < 127: self.step = Step.Dribbling self.dribble = Dribbling(self.info.my_car, self.info.ball, self.their_goal) if self.defending: self.step = Step.Defending ball = self.info.ball if abs(ball.velocity[2]) < 100 and sign(self.team) * ball.velocity[1] < 0 and sign(self.team) * \ ball.location[1] < 0: self.step = Step.Shooting elif self.step is Step.Dribbling: self.dribble.step() self.controls = self.dribble.controls ball = self.info.ball car = self.info.my_car bot_to_opponent = self.info.cars[ 1 - self.index].location - self.info.my_car.location local_bot_to_target = dot(bot_to_opponent, self.info.my_car.rotation) angle_front_to_target = math.atan2(local_bot_to_target[1], local_bot_to_target[0]) opponent_is_near = norm(vec2(bot_to_opponent)) < 2000 opponent_is_in_the_way = math.radians( -10) < angle_front_to_target < math.radians(10) if not (distance_2d(ball.location, car.location) < 150 and 65 < abs(ball.location[2] - car.location[2]) < 127): self.step = Step.Catching if self.defending: self.step = Step.Defending if opponent_is_near and opponent_is_in_the_way: self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.duration = 0.25 self.dodge.target = self.their_goal.center elif self.step is Step.Defending: defending(self) elif self.step in [ Step.Dodge, Step.Dodge_1, Step.Dodge_2, Step.HalfFlip ]: halfflipping = self.step is Step.HalfFlip if halfflipping: self.halfflip.step(self.info.time_delta) else: self.dodge.step(self.info.time_delta) if self.halfflip.finished if halfflipping else self.dodge.finished: self.step = Step.Catching else: self.controls = (self.halfflip.controls if halfflipping else self.dodge.controls) elif self.step is Step.Shooting: shooting(self) def handle_match_comms(self): try: msg = self.matchcomms.incoming_broadcast.get_nowait() except Empty: return if handle_set_attributes_message( msg, self, allowed_keys=['kickoff', 'prev_kickoff']): reply_to(self.matchcomms, msg) else: self.logger.debug('Unhandled message: {msg}') def render_string(self, string): """Rendering method mainly used to show the current state""" self.renderer.begin_rendering('The State') if self.step is Step.Dodge_1: self.renderer.draw_line_3d(self.info.my_car.location, self.dodge.target, self.renderer.black()) self.renderer.draw_line_3d(self.info.my_car.location, self.drive.target, self.renderer.blue()) if self.kickoff_Start is None: self.renderer.draw_string_2d(20, 20, 3, 3, string, self.renderer.red()) else: self.renderer.draw_string_2d(20, 20, 3, 3, string + " " + self.kickoff_Start, self.renderer.red()) self.renderer.end_rendering() def should_defending(self): return False # Don't. """Method which returns a boolean regarding whether we should defend or not""" ball = self.info.ball car = self.info.my_car our_goal = self.my_goal.center car_to_ball = ball.location - car.location in_front_of_ball = distance_2d(ball.location, our_goal) < distance_2d( car.location, our_goal) backline_intersect = line_backline_intersect(self.my_goal.center[1], vec2(car.location), vec2(car_to_ball)) return (in_front_of_ball and abs(backline_intersect) < 2000) or self.conceding def close_to_kickoff_spawn(self): blue_one = distance_2d(self.info.my_car.location, vec3( -2048, -2560, 18)) < 10 blue_two = distance_2d(self.info.my_car.location, vec3( 2048, -2560, 18)) < 10 blue_three = distance_2d(self.info.my_car.location, vec3(-256, -3840, 18)) < 10 blue_four = distance_2d(self.info.my_car.location, vec3( 256, -3840, 18)) < 10 blue_five = distance_2d(self.info.my_car.location, vec3(0, -4608, 18)) < 10 blue = blue_one or blue_two or blue_three or blue_four or blue_five orange_one = distance_2d(self.info.my_car.location, vec3(-2048, 2560, 18)) < 10 orange_two = distance_2d(self.info.my_car.location, vec3( 2048, 2560, 18)) < 10 orange_three = distance_2d(self.info.my_car.location, vec3(-256, 3840, 18)) < 10 orange_four = distance_2d(self.info.my_car.location, vec3( 256, 3840, 18)) < 10 orange_five = distance_2d(self.info.my_car.location, vec3(0, 4608, 18)) < 10 orange = orange_one or orange_two or orange_three or orange_four or orange_five return orange or blue
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.game.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state if self.state == State.RESET: self.timer = 0.0 # put the car in the middle of the field car_state = CarState(physics=Physics( location=Vector3(-2000, 0, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0)), jumped=False, double_jumped=False) # put the ball somewhere out of the way ball_state = BallState( physics=Physics(location=Vector3(0, 5000, 0), velocity=Vector3(0, 0, 0), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0))) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) next_state = State.WAIT if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE if self.state == State.INITIALIZE: self.dodge = Dodge(self.game.my_car) self.turn = AerialTurn(self.game.my_car) f = self.game.my_car.forward() l = self.game.my_car.left() u = self.game.my_car.up() # musty flick if self.counter % 3 == 0: self.name = "Musty Flick" self.dodge.duration = 0.2 self.dodge.delay = 0.8 self.dodge.direction = vec2(f) self.dodge.preorientation = look_at(-0.1 * f - u, -1.0 * u) # diagonal forward dodge if self.counter % 3 == 1: self.name = "Fast Forward Dodge" self.dodge.duration = 0.15 self.dodge.delay = 0.4 self.dodge.direction = vec2(1.0, 0.0) self.dodge.preorientation = dot( axis_to_rotation(vec3(0, 0, 3)), self.game.my_car.rotation) # diagonal twist if self.counter % 3 == 2: self.name = "Air-Roll Dodge hit" self.dodge.duration = 0.15 self.dodge.delay = 0.5 self.dodge.direction = vec2(f - 0.3 * l) self.dodge.preorientation = dot( self.game.my_car.rotation, axis_to_rotation(vec3(-0.8, -0.4, 0))) self.counter += 1 next_state = State.RUNNING if self.state == State.RUNNING: if self.timer > 1.2: self.turn.target = look_at(xy(self.game.my_car.velocity), vec3(0, 0, 1)) self.turn.step(self.game.time_delta) self.controls = self.turn.controls else: self.dodge.step(self.game.time_delta) self.controls = self.dodge.controls if self.timer > self.timeout: next_state = State.RESET self.game.my_car.last_input.roll = self.controls.roll self.game.my_car.last_input.pitch = self.controls.pitch self.game.my_car.last_input.yaw = self.controls.yaw self.timer += self.game.time_delta self.state = next_state if self.name: self.renderer.begin_rendering() self.renderer.draw_string_2d(50, 50, 6, 6, self.name, self.renderer.red()) self.renderer.end_rendering() return self.controls
class MyAgent(BaseAgent): def __init__(self, name, team, index): super().__init__(name, team, index) Game.set_mode("soccar") self.game = Game(index, team) self.name = name self.controls = SimpleControllerState() self.timer = 0.0 self.drive = Drive(self.game.my_car) self.dodge = None self.turn = None self.state = State.RESET def get_output(self, packet: GameTickPacket) -> SimpleControllerState: # Update the game values and set the state self.game.read_game_information(packet, self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state # Reset everything if self.state == State.RESET: self.timer = 0.0 # self.set_gamestate_straight_moving() # self.set_gamestate_straight_moving_towards() self.set_state_stationary_angled() # self.set_gamestate_angled_stationary() # self.set_state_stationary() next_state = State.WAIT # Wait so everything can settle in, mainly for ball prediction if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE # Initialize the drive mechanic if self.state == State.INITIALIZE: self.drive = Drive(self.game.my_car) self.drive.target = self.game.ball.position self.drive.speed = 1400 next_state = State.DRIVING # Start driving towards the target and check whether a dodge is possible, if so initialize the dodge if self.state == State.DRIVING: self.drive.target = self.game.ball.position self.drive.step(self.game.time_delta) self.controls = self.drive.controls a = time.time() target = self.game.my_car.position + 1000000 * ( self.game.ball.position - self.game.my_car.position) can_dodge, simulated_duration, simulated_target = self.simulate() print(time.time() - a) if can_dodge: self.dodge = Dodge(self.game.my_car) self.turn = AerialTurn(self.game.my_car) self.dodge.duration = simulated_duration - 0.1 self.dodge.target = simulated_target self.dodge.preorientation = look_at(simulated_target, vec3(0, 0, 1)) self.timer = 0 next_state = State.DODGING # Perform the dodge if self.state == State.DODGING: self.dodge.step(self.game.time_delta) self.controls = self.dodge.controls T = self.dodge.duration - self.dodge.timer if T > 0: if self.dodge.timer < 0.2: self.controls.boost = 1 # self.controls.pitch = 1 else: xf = self.game.my_car.position + 0.5 * T * T * vec3( 0, 0, -650) + T * self.game.my_car.velocity delta_x = self.game.ball.position - xf if angle_between(vec2(self.game.my_car.forward()), self.dodge.direction) < 0.3: if norm(delta_x) > 50: self.controls.boost = 1 self.controls.throttle = 0.0 else: self.controls.boost = 0 self.controls.throttle = clip( 0.5 * (200 / 3) * T * T, 0.0, 1.0) else: self.controls.boost = 0 self.controls.throttle = 0.0 else: self.controls.boost = 0 # Great line # if self.game.time == packet.game_ball.latest_touch.time_seconds: # print(self.game.my_car.position) if self.dodge.finished and self.game.my_car.on_ground: next_state = State.RESET self.timer += self.game.time_delta self.state = next_state return self.controls # The miraculous simulate function # TODO optimize heavily in case I actually need it # Option one: estimate the time for the current height and look at that ball prediction. # If its heigher use that unless it gets unreachable and else compare with the lower one. # If duration_estimate = 0.8 and the ball is moving up there is not sense in even simulating it. # Might even lower it since the higher the duration estimate the longer the simulation takes. def simulate(self, global_target=None): lol = 0 # Initialize the ball prediction # Estimate the probable duration of the jump and round it down to the floor decimal ball_prediction = self.get_ball_prediction_struct() if self.game.my_car.boost < 6: duration_estimate = math.floor( get_time_at_height(self.game.ball.position[2]) * 10) / 10 else: adjacent = norm( vec2(self.game.my_car.position - self.game.ball.position)) opposite = (self.game.ball.position[2] - self.game.my_car.position[2]) theta = math.atan(opposite / adjacent) t = get_time_at_height_boost(self.game.ball.position[2], theta, self.game.my_car.boost) duration_estimate = (math.ceil(t * 10) / 10) # Loop for 6 frames meaning adding 0.1 to the estimated duration. Keeps the time constraint under 0.3s for i in range(6): # Copy the car object and reset the values for the hitbox car = Car(self.game.my_car) # Create a dodge object on the copied car object # Direction is from the ball to the enemy goal # Duration is estimated duration plus the time added by the for loop # preorientation is the rotation matrix from the ball to the goal # TODO make it work on both sides # Test with preorientation. Currently it still picks a low duration at a later time meaning it # wont do any of the preorientation. dodge = Dodge(car) prediction_slice = ball_prediction.slices[round( 60 * (duration_estimate + i / 60))] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) # ball_location = vec3(0, ball_y, ball_z) dodge.duration = duration_estimate + i / 60 if dodge.duration > 1.4: break if global_target is not None: dodge.direction = vec2(global_target - ball_location) target = vec3(vec2(global_target)) + vec3( 0, 0, jeroens_magic_number * ball_location[2]) dodge.preorientation = look_at(target - ball_location, vec3(0, 0, 1)) else: dodge.target = ball_location dodge.direction = vec2(ball_location) + vec2(ball_location - car.position) dodge.preorientation = look_at(ball_location, vec3(0, 0, 1)) # Loop from now till the end of the duration fps = 30 for j in range(round(fps * dodge.duration)): lol = lol + 1 # Get the ball prediction slice at this time and convert the location to RLU vec3 prediction_slice = ball_prediction.slices[round(60 * j / fps)] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) dodge.step(1 / fps) T = dodge.duration - dodge.timer if T > 0: if dodge.timer < 0.2: dodge.controls.boost = 1 dodge.controls.pitch = 1 else: xf = car.position + 0.5 * T * T * vec3( 0, 0, -650) + T * car.velocity delta_x = ball_location - xf if angle_between(vec2(car.forward()), dodge.direction) < 0.3: if norm(delta_x) > 50: dodge.controls.boost = 1 dodge.controls.throttle = 0.0 else: dodge.controls.boost = 0 dodge.controls.throttle = clip( 0.5 * (200 / 3) * T * T, 0.0, 1.0) else: dodge.controls.boost = 0 dodge.controls.throttle = 0.0 else: dodge.controls.boost = 0 car.step(dodge.controls, 1 / fps) succesfull = self.dodge_succesfull(car, ball_location, dodge) if succesfull is not None: if succesfull: return True, j / fps, ball_location else: break return False, None, None def dodge_succesfull(self, car, ball_location, dodge): batmobile = obb() batmobile.half_width = vec3(64.4098892211914, 42.335182189941406, 14.697200775146484) batmobile.center = car.position + dot(car.orientation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.orientation ball = sphere(ball_location, 93.15) b_local = dot(ball.center - batmobile.center, batmobile.orientation) closest_local = vec3( min(max(b_local[0], -batmobile.half_width[0]), batmobile.half_width[0]), min(max(b_local[1], -batmobile.half_width[1]), batmobile.half_width[1]), min(max(b_local[2], -batmobile.half_width[2]), batmobile.half_width[2])) hit_location = dot(batmobile.orientation, closest_local) + batmobile.center if norm(hit_location - ball.center) > ball.radius: return None # if abs(ball_location[2] - hit_location[2]) < 25 and hit_location[2] < ball_location[2]: if abs(ball_location[2] - hit_location[2]) < 25: if closest_local[0] > 35 and -12 < closest_local[2] < 12: hit_check = True else: print("local: ", closest_local) hit_check = True else: hit_check = False # Seems to work without angle_check. No clue why though angle_car_simulation = angle_between(car.orientation, self.game.my_car.orientation) angle_simulation_target = angle_between(car.orientation, dodge.preorientation) angle_check = angle_simulation_target < angle_car_simulation or angle_simulation_target < 0.1 return hit_check """" State setting methods for various situations""" def set_gamestate_straight_moving(self): # put the car in the middle of the field car_state = CarState( physics=Physics(location=Vector3(0, -1000, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, math.pi / 2, 0), angular_velocity=Vector3(0, 0, 0))) # put the ball in the middle of the field ball_state = BallState( physics=Physics(location=Vector3(0, 1500, 93), velocity=Vector3(200, 650, 750), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0))) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) def set_gamestate_straight_moving_towards(self): # put the car in the middle of the field car_state = CarState(physics=Physics( location=Vector3(0, 0, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, math.pi / 2, 0), angular_velocity=Vector3(0, 0, 0), ), boost_amount=50) # put the ball in the middle of the field ball_state = BallState(physics=Physics( location=Vector3(0, 2500, 93), velocity=Vector3(0, -250, 500), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0), )) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) def set_gamestate_angled_stationary(self): # put the car in the middle of the field car_state = CarState( physics=Physics(location=Vector3(-1000, -2000, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, math.pi / 8, 0), angular_velocity=Vector3(0, 0, 0))) # put the ball in the middle of the field ball_state = BallState( physics=Physics(location=Vector3(0, 0, 600), velocity=Vector3(0, 0, 1), rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0))) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) def set_state_stationary(self): # put the car in the middle of the field car_state = CarState(physics=Physics( location=Vector3(0, -2500, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, math.pi / 2, 0), angular_velocity=Vector3(0, 0, 0), ), boost_amount=100) # put the ball in the middle of the field ball_state = BallState(physics=Physics( location=Vector3(0, ball_y, ball_z), velocity=Vector3(0, 0, 0), angular_velocity=Vector3(0, 0, 0), )) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state})) def set_state_stationary_angled(self): # put the car in the middle of the field car_state = CarState(physics=Physics( location=Vector3(0, -2500, 18), velocity=Vector3(0, 0, 0), rotation=Rotator(0, math.pi / 2, 0), angular_velocity=Vector3(0, 0, 0), ), boost_amount=100) # put the ball in the middle of the field ball_state = BallState(physics=Physics( location=Vector3(1500, 0, 93), velocity=Vector3(0, 0, 750), angular_velocity=Vector3(0, 0, 0), )) self.set_game_state( GameState(ball=ball_state, cars={self.game.id: car_state}))
def initialize_agent(self): """Initializing all parameters which require the field info""" init_boostpads(self) self.drive = Drive(self.game.my_car) self.dodge = Dodge(self.game.my_car)
c.time = 0.0 c.location = vec3(1509.38, -686.19, 17.01) c.velocity = vec3(-183.501, 1398., 8.321) c.angular_velocity = vec3(0, 0, 0) c.rotation = mat3(-0.130158, -0.991493, -0.00117062, 0.991447, -0.130163, 0.00948812, -0.00955977, 0.0000743404, 0.999954) c.dodge_rotation = mat2(-0.130163, -0.991493, 0.991493, -0.130163) c.on_ground = True c.jumped = False c.double_jumped = False c.jump_timer = -1.0 c.dodge_timer = -1.0 dodge = Dodge(c) dodge.direction = vec2(-230.03, 463.42) dodge.duration = 0.1333 dodge.delay = 0.35 f = open("dodge_simulation.csv", "w") for i in range(300): dodge.step(0.008333) print(c.time, dodge.controls.jump, dodge.controls.pitch, dodge.controls.yaw) c.step(dodge.controls, 0.008333) f.write( f"{c.time}, {c.location[0]}, {c.location[1]}, {c.location[2]}, " f"{c.velocity[0]}, {c.velocity[1]}, {c.velocity[2]}, " f"{c.angular_velocity[0]}, {c.angular_velocity[1]}, {c.angular_velocity[2]}\n" )