def __init__(self, agent, packet: GameTickPacket, should_render=False): self.agent = agent if should_render: self.renderer = agent.renderer else: self.renderer = render.FakeRenderer() self.packet = packet self.ball = Ball().set_game_ball(packet.game_ball) self.car = Car(packet.game_cars[agent.index]) self.enemy = Car(packet.game_cars[1 - agent.index]) self.car.set_ball_dependent_variables(self.ball) self.enemy.set_ball_dependent_variables(self.ball) self.__decide_possession() # predictions self.time_till_hit = predict.time_till_reach_ball(self.ball, self.car) self.ball_when_hit = predict.move_ball(self.ball.copy(), self.time_till_hit) if self.ball_when_hit.location.z > 100: time_till_ground = predict.time_of_arrival_at_height( self.ball_when_hit, 100).time self.ball_when_hit = predict.move_ball(self.ball_when_hit, time_till_ground) self.time_till_hit += time_till_ground
def find_route_to_next_ball_landing(data: Data, look_towards=None): car_to_ball = data.ball.location - data.car.location dist = car_to_ball.length() vel_f = data.car.velocity.proj_onto_size(car_to_ball) drive_time = dist / max(1410, vel_f) ball = data.ball.copy() predict.move_ball(ball, drive_time) time_hit = predict.next_ball_ground_hit(ball).time time_total = drive_time + time_hit return get_route_to_ball(data, time_total, look_towards)
def execute(self, data): ball_land_eta = max(predict.time_of_arrival_at_height(data.ball, datalibs.BALL_RADIUS + 1).time, 0) ball_land_loc = predict.move_ball(data.ball.copy(), ball_land_eta).location bias = (ball_land_loc - datalibs.get_goal_location(data.enemy.team)).rescale(20) dest = ball_land_loc + bias data.renderer.draw_line_3d(data.car.location.tuple(), dest.tuple(), data.renderer.create_color(255, 255, 0, 255)) data.renderer.draw_line_3d(data.ball.location.tuple(), dest.tuple(), data.renderer.create_color(255, 255, 0, 255)) return moves.go_towards_point_with_timing(data, dest, ball_land_eta, True)
def execute(self, data): car_to_ball = data.ball_when_hit.location - data.car.location # Check dodge. A dodge happens after 0.18 sec ball_soon = predict.move_ball(data.ball.copy(), 0.15).location car_soon = predict.move_ball(datalibs.Ball().set(data.car), 0.25).location car_to_ball_soon = ball_soon - car_soon # Aim cone was calculated in utility if car_to_ball_soon.length() < 240+92 and self.aim_cone.contains_direction(car_to_ball_soon): if data.agent.dodge_control.can_dodge(data): data.agent.dodge_control.begin_dodge(data, lambda d: d.ball.location, True) data.agent.dodge_control.continue_dodge(data) goto, goto_time = self.aim_cone.get_goto_point(data, data.ball_when_hit.location) dist = car_to_ball.length() self.aim_cone.draw(data.renderer, data.ball_when_hit.location, b=0) if goto is None or dist < 450: # Avoid enemy corners. Just wait if data.ball_when_hit.location.y * datalibs.team_sign(data.enemy.team) > 4400 and abs(data.ball_when_hit.location.x) > 900 and not dist < 450: wait_point = data.ball_when_hit.location * 0.5 # a point 50% closer to the center of the field wait_point = wait_point.lerp(data.ball.location + Vec3(y=datalibs.team_sign(data.car.team) * 3000), 0.5) data.renderer.draw_line_3d(data.car.location.tuple(), wait_point.tuple(), self.color(data.renderer)) return moves.go_towards_point_with_timing(data, wait_point, 1, True) if datalibs.is_point_closer_to_goal(data.car.location, data.ball.location, data.car.team): # return home enemy_goal = datalibs.get_goal_location(data.enemy.team) goal_to_ball = (data.ball_when_hit.location - enemy_goal).normalized() offset_ball = data.ball_when_hit.location + goal_to_ball * 92 data.renderer.draw_line_3d(data.car.location.tuple(), offset_ball.tuple(), self.color(data.renderer)) return moves.go_towards_point(data, offset_ball, False, True) else: own_goal = datalibs.get_goal_location(data.car.team) if moves.consider_dodge(data, own_goal): return data.agent.dodge_control.continue_dodge(data) return moves.go_towards_point(data, own_goal, True, False) else: if moves.consider_dodge(data, goto): return data.agent.dodge_control.continue_dodge(data) return moves.go_towards_point_with_timing(data, goto, data.time_till_hit * goto_time * 0.95, True)
def utility(self, data): ball_soon = predict.move_ball(data.ball.copy(), 1) team_sign = datalibs.team_sign(data.car.team) own_half_01 = easing.fix(easing.remap(team_sign * datalibs.ARENA_LENGTH2, (-1 * team_sign) * datalibs.ARENA_LENGTH2, 0.0, 1.1, ball_soon.location.y)) self.ball_to_goal_right = self.enemy_goal_right - data.ball_when_hit.location self.ball_to_goal_left = self.enemy_goal_left - data.ball_when_hit.location self.aim_cone = route.AimCone(self.ball_to_goal_right.ang(), self.ball_to_goal_left.ang()) car_to_ball = data.ball_when_hit.location - data.car.location in_position = self.aim_cone.contains_direction(car_to_ball) return easing.fix(own_half_01 + 0.06 * in_position)
def get_route_to_ball(data: Data, time_offset=0, look_towards=None): dist_step_size = 1410 * 0.5 max_turn_ang = math.pi * 0.3 if look_towards is None: look_towards = datalibs.get_goal_location(data.enemy, data) ball = predict.move_ball(data.ball.copy(), time_offset) ball_init_loc = ball.location.flat() ball_to_goal = look_towards - ball_init_loc if ball_to_goal.flat().length2() == 0: ball_to_goal = datalibs.get_goal_location(data.enemy, data) - ball_init_loc ball_init_dir = ball_to_goal.flat().normalized() * -1 car_loc = data.car.location.flat() ball_to_car = car_loc - ball_init_loc ang = ball_init_dir.ang_to_flat(ball_to_car) good_route = abs(ang) < math.pi/2 if good_route: bx = ball_init_loc.x by = ball_init_loc.y cx = car_loc.x cy = car_loc.y dx = ball_init_dir.x dy = ball_init_dir.y t = - (bx*bx - 2*bx*cx + by*by - 2*by*cy + cx*cx + cy*cy) / (2*(bx*dx + by*dy - cx*dx - cy*dy)) t = min(max(-1400, t), 1400) point = ball_init_loc + t * ball_init_dir point.x = min(max(-4030, point.x), 4030) point.y = min(max(-5090, point.y), 5090) return Route([point, ball_init_loc], ball_init_dir, 1, 1410, car_loc, good_route, False) else: point = car_loc + 700 * ball_init_dir return Route([point, ball_init_loc], ball_init_dir, 1, 1410, car_loc, good_route, False)