def rendezvous_prediction(game_info, min_time, persistent): ''' Updates the place and time we will be contacting the ball ''' prediction = game_info.ball_prediction for i in range(0, len(prediction.slices), 2): aerial = Aerial(game_info.utils_game.my_car) #if prediction.slices[i].pos.z > 150:# and prediction.slices[i].time > min_time: aerial.target = Vec3_to_vec3(prediction.slices[i].pos, game_info.team_sign) aerial.arrival_time = prediction.slices[i].time simulation = aerial.simulate() if (vec3_to_Vec3(simulation.location, game_info.team_sign) - vec3_to_Vec3(aerial.target, game_info.team_sign)).magnitude() < 30: persistent.aerial.target_location = prediction.slices[i].pos persistent.aerial.target_time = prediction.slices[i].time break #else: ''' This currently isn't defined, so we're going to skip it for now. if prediction.time - game_info.game_time > drive_time(game_info, prediction.location, game_info.me.boost): persistent.hit_ball.action.target = prediction.location persistent.hit_ball.action.arrival_time = prediction.time break ''' return persistent
def choose_stationary_takeoff_time(game_info, target_loc, target_time): ''' Decides when to take off for an aerial based on a given target time and place. Assumes we're sitting still to start with. ''' aerial = Aerial(game_info.utils_game.my_car) aerial.target = Vec3_to_vec3(target_loc, game_info.team_sign) current_time = game_info.game_time test_interval = [current_time, target_time] while abs(test_interval[1] - test_interval[0]) > 1 / 30: test_time = (test_interval[0] + test_interval[1]) / 2 aerial.arrival_time = test_time simulation = aerial.simulate() if vec3_to_Vec3(simulation.location - aerial.target, game_info.team_sign).magnitude() < 100: test_interval = [test_interval[0], test_time] else: test_interval = [test_time, test_interval[1]] return target_time - (test_interval[1] - current_time)
class Agent(BaseAgent): def __init__(self, name, team, index): Game.set_mode("soccar") self.game = Game(index, team) self.controls = SimpleControllerState() self.timer = 0.0 self.timeout = 5.0 self.aerial = None self.turn = None self.state = State.RESET self.ball_predictions = None self.target_ball = None self.log = open("../../analysis/aerial/info.ndjson", "w") 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 b_position = Vector3(random.uniform(-1500, 1500), random.uniform( 2500, 3500), random.uniform( 300, 500)) b_velocity = Vector3(random.uniform(-300, 300), random.uniform(-100, 100), random.uniform(1000, 1500)) ball_state = BallState(physics=Physics( location=b_position, velocity=b_velocity, rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0) )) # this just initializes the car and ball # to different starting points each time c_position = Vector3(b_position.x, 0 * random.uniform(-1500, -1000), 25) #c_position = Vector3(200, -1000, 25) car_state = CarState(physics=Physics( location=c_position, velocity=Vector3(0, 800, 0), rotation=Rotator(0, 1.6, 0), angular_velocity=Vector3(0, 0, 0) ), boost_amount=100) 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.aerial = Aerial(self.game.my_car) # self.aerial.up = normalize(vec3( # random.uniform(-1, 1), # random.uniform(-1, 1), # random.uniform(-1, 1))) self.turn = AerialTurn(self.game.my_car) # predict where the ball will be prediction = Ball(self.game.ball) self.ball_predictions = [vec3(prediction.location)] for i in range(100): prediction.step(0.016666) prediction.step(0.016666) self.ball_predictions.append(vec3(prediction.location)) # if the ball is in the air if prediction.location[2] > 500: self.aerial.target = prediction.location self.aerial.arrival_time = prediction.time simulation = self.aerial.simulate() # # check if we can reach it by an aerial if norm(simulation.location - self.aerial.target) < 100: prediction.step(0.016666) prediction.step(0.016666) self.aerial.target = prediction.location self.aerial.arrival_time = prediction.time self.target_ball = Ball(prediction) break next_state = State.RUNNING if self.state == State.RUNNING: self.log.write(f"{{\"car\":{self.game.my_car.to_json()}," f"\"ball\":{self.game.ball.to_json()}}}\n") self.aerial.step(self.game.time_delta) self.controls = self.aerial.controls if self.timer > self.timeout: next_state = State.RESET self.aerial = None self.turn = None self.timer += self.game.time_delta self.state = next_state self.renderer.begin_rendering() red = self.renderer.create_color(255, 230, 30, 30) purple = self.renderer.create_color(255, 230, 30, 230) white = self.renderer.create_color(255, 230, 230, 230) if self.aerial: r = 200 x = vec3(r, 0, 0) y = vec3(0, r, 0) z = vec3(0, 0, r) target = self.aerial.target self.renderer.draw_line_3d(target - x, target + x, purple) self.renderer.draw_line_3d(target - y, target + y, purple) self.renderer.draw_line_3d(target - z, target + z, purple) if self.ball_predictions: self.renderer.draw_polyline_3d(self.ball_predictions, purple) self.renderer.end_rendering() return self.controls
class AerialHandler(): def __init__(self, agent): self.agent = agent self.active = False self.timer = time.time() self.setup() self.threshold = 300 def setup(self): self.aerial = Aerial(self.agent.game.my_car) self.turn = AerialTurn(self.agent.game.my_car) myGoal = center = Vector([0, 5120 * sign(self.agent.team), 200]) enemyGoal = center = Vector([0, 5120 * -sign(self.agent.team), 200]) aboveThreshold = False if self.agent.me.boostLevel > 0: for i in range(0, self.agent.ballPred.num_slices): targetVec = Vector([ self.agent.ballPred.slices[i].physics.location.x, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z ]) if self.agent.ballPred.slices[i].physics.location.z >= 300: if not aboveThreshold: aboveThreshold = True goalDist = distance2D(center, targetVec) acceptable = False if self.agent.team == 0: if self.agent.me.location[1] < targetVec[1]: acceptable = True else: if self.agent.me.location[1] > targetVec[1]: acceptable = True if acceptable: zOffset = -10 if goalDist < 1500: if targetVec[2] > 600: zOffset = 70 shotAngle = correctAngle( math.degrees(angle2(targetVec, enemyGoal)) + 90 * -sign(self.agent.team)) if self.agent.team == 0: if targetVec[1] >= 0: if abs(targetVec[0]) > 893: if targetVec[0] > 0: closePost = Vector([ 893, 5120 * -sign(self.agent.team), 200 ]) else: closePost = Vector([ -893, 5120 * -sign(self.agent.team), 200 ]) attackAngle = correctAngle( math.degrees( angle2(targetVec, closePost)) + 90 * -sign(self.agent.team)) targetLocal = toLocal( Vector([ self.agent.ballPred.slices[i]. physics.location.x, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred.slices[i]. physics.location.z ]), self.agent.me) carToBallAngle = correctAngle( math.degrees( math.atan2(targetLocal[1], targetLocal[0]))) totalAngle = correctAngle( math.degrees( math.tan(attackAngle) + math.tan(carToBallAngle) / (1 - (math.tan(attackAngle) * math.tan(carToBallAngle))))) if abs(totalAngle) > 60: continue elif self.agent.team == 1: if targetVec[1] <= 0: if abs(targetVec[0]) > 893: if targetVec[0] > 0: closePost = Vector([ 893, 5120 * -sign(self.agent.team), 200 ]) else: closePost = Vector([ -893, 5120 * -sign(self.agent.team), 200 ]) attackAngle = correctAngle( math.degrees( angle2(targetVec, closePost)) + 90 * -sign(self.agent.team)) targetLocal = toLocal( Vector([ self.agent.ballPred.slices[i]. physics.location.x, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred.slices[i]. physics.location.z ]), self.agent.me) carToBallAngle = correctAngle( math.degrees( math.atan2(targetLocal[1], targetLocal[0]))) totalAngle = correctAngle(carToBallAngle + attackAngle) if abs(totalAngle) > 60: continue if abs(shotAngle) <= 75: xOffset = clamp(80, -80, (shotAngle * 2) * -sign(self.agent.team)) self.aerial.target = vec3( self.agent.ballPred.slices[i].physics.location. x + xOffset, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred. slices[i].physics.location.z + zOffset) self.aerial.arrival_time = self.agent.ballPred.slices[ i].game_seconds simulation = self.aerial.simulate() if norm(simulation.location - self.aerial.target) < 100: self.target_ball = self.agent.ballPred.slices[ i] self.xOffset = xOffset self.zOffset = zOffset self.active = True if self.agent.onSurface: if self.agent.ballPred.slices[ i].physics.location.z >= 400: targetLocal = toLocal( Vector([ self.agent.ballPred.slices[i]. physics.location.x + xOffset, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred.slices[i]. physics.location.z + zOffset ]), self.agent.me) carToBallAngle = correctAngle( math.degrees( math.atan2( targetLocal[1], targetLocal[0]))) if abs(carToBallAngle) < 45: if distance2D( self.agent.me.location, targetLocal) > 1500: if self.agent.ballPred.slices[ i].physics.location.z >= 900: self.agent.activeState = airLaunch( self.agent) self.active = False return self.agent.activeState.update( ) break else: if aboveThreshold: break def stillValid(self): for i in range(0, self.agent.ballPred.num_slices): if self.agent.ballPred.slices[i].physics.location.z >= 300: if abs(self.target_ball.game_seconds - self.agent.ballPred.slices[i].game_seconds ) < self.agent.deltaTime * 3: difference = 0 difference += abs( (self.agent.ballPred.slices[i].physics.location.x + self.xOffset) - (self.target_ball.physics.location.x + self.zOffset)) difference += abs( self.agent.ballPred.slices[i].physics.location.y - self.target_ball.physics.location.y) difference += abs( (self.agent.ballPred.slices[i].physics.location.z + self.zOffset) - (self.target_ball.physics.location.z + self.zOffset)) if difference < 10: self.aerial.target = vec3( self.agent.ballPred.slices[i].physics.location.x + self.xOffset, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z + self.zOffset) self.aerial.arrival_time = self.agent.ballPred.slices[ i].game_seconds self.target_ball = self.agent.ballPred.slices[i] simulation = self.aerial.simulate() return self.active = False self.setup() def update(self): if self.agent.me.boostLevel > 0: self.setup() self.aerial.step(self.agent.deltaTime) self.controls = self.aerial.controls self.controls.jump = True if self.aerial.finished: self.active = False else: self.active = False if time.time() - self.timer > 0.5: if self.agent.onSurface: self.active = False return self.controls
class AerialHandler(): def __init__(self,agent): self.agent = agent self.active = False self.setup() def setup(self): self.aerial = Aerial(self.agent.game.my_car) self.turn = AerialTurn(self.agent.game.my_car) myGoal = center = Vector([0, 5200 * sign(self.agent.team), 200]) enemyGoal = center = Vector([0, 5200 * -sign(self.agent.team), 200]) if self.agent.me.boostLevel > 0: for i in range(0, self.agent.ballPred.num_slices): targetVec = Vector([self.agent.ballPred.slices[i].physics.location.x, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z]) # interferenceTimer += self.agent.deltaTime # if interferenceTimer < 1: # if findEnemyClosestToLocation(self.agent,targetVec)[1] < 150: # break if self.agent.ballPred.slices[i].physics.location.z >= 300: goalDist = distance2D(center, targetVec) #if distance2D(myGoal, targetVec) > distance2D(myGoal, self.agent.me.location): if self.agent.me.location[1] * sign(self.agent.team) > self.agent.ballPred.slices[i].physics.location.y * sign(self.agent.team): zOffset = 0 if goalDist < 1500: if targetVec[2] > 600: zOffset = 70 shotAngle = correctAngle(math.degrees(angle2(targetVec, enemyGoal)) + 90 * -sign(self.agent.team)) if abs(shotAngle) <=80: xOffset = clamp(80,-80,(shotAngle*2)*-sign(self.agent.team)) self.aerial.target = vec3(self.agent.ballPred.slices[i].physics.location.x+xOffset, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z+zOffset) self.aerial.arrival_time = self.agent.ballPred.slices[i].game_seconds simulation = self.aerial.simulate() # # check if we can reach it by an aerial if norm(simulation.location - self.aerial.target) < 100: self.target_ball = self.agent.ballPred.slices[i] self.xOffset = xOffset self.zOffset = zOffset self.active = True break def stillValid(self): for i in range(0, self.agent.ballPred.num_slices): if self.agent.ballPred.slices[i].physics.location.z >= 300: if abs(self.target_ball.game_seconds - self.agent.ballPred.slices[i].game_seconds) < self.agent.deltaTime*3: difference = 0 difference+= abs((self.agent.ballPred.slices[i].physics.location.x+self.xOffset) - (self.target_ball.physics.location.x+self.zOffset)) difference += abs(self.agent.ballPred.slices[i].physics.location.y - self.target_ball.physics.location.y) difference += abs((self.agent.ballPred.slices[i].physics.location.z+self.zOffset) - (self.target_ball.physics.location.z+self.zOffset)) if difference < 10: self.aerial.target = vec3(self.agent.ballPred.slices[i].physics.location.x + self.xOffset, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z + self.zOffset) self.aerial.arrival_time = self.agent.ballPred.slices[i].game_seconds self.target_ball = self.agent.ballPred.slices[i] simulation = self.aerial.simulate() return self.active = False self.setup() def update(self): if self.agent.me.boostLevel > 0: self.setup() self.aerial.step(self.agent.deltaTime) self.controls = self.aerial.controls self.controls.jump = True if self.aerial.finished: self.active = False else: self.active = False return self.controls