def utility_score(self, bot) -> float: if self.temp_utility_desire_boost > 0: self.temp_utility_desire_boost = max(0, self.temp_utility_desire_boost - bot.info.dt) elif self.temp_utility_desire_boost < 0: self.temp_utility_desire_boost = min(0, self.temp_utility_desire_boost + bot.info.dt) car = bot.info.my_car ball_soon = predict.ball_predict(bot, 1) arena_length2 = bot.info.team_sign * Field.LENGTH2 own_half_01 = clip01(remap(arena_length2, -arena_length2, 0.0, 1.1, ball_soon.pos.y)) close_to_ball01 = clip01(1.0 - norm(car.pos - ball_soon.pos) / 3500) ** 0.5 reachable_ball = predict.ball_predict(bot, predict.time_till_reach_ball(bot.info.my_car, bot.info.ball)) self.ball_to_goal_right = bot.info.opp_goal.right_post - reachable_ball.pos self.ball_to_goal_left = bot.info.opp_goal.left_post - reachable_ball.pos self.aim_cone = AimCone(self.ball_to_goal_right, self.ball_to_goal_left) car_to_ball = reachable_ball.pos - bot.info.my_car.pos in_position = self.aim_cone.contains_direction(car_to_ball) # Chase ball right after kickoff. High right after kickoff kickoff_bias01 = max(0, 1 - bot.info.time_since_last_kickoff * 0.3) * float(bot.info.my_car.objective == Objective.UNKNOWN) obj_bonus = { Objective.UNKNOWN: 0, Objective.GO_FOR_IT: 0.2, Objective.FOLLOW_UP: 0, Objective.ROTATE_BACK_OR_DEF: -0.2, }[bot.info.my_car.objective] return clip01(close_to_ball01 * own_half_01 + 0.1 * in_position + self.temp_utility_desire_boost + kickoff_bias01) + obj_bonus
def utility_score(self, bot) -> float: car = bot.info.my_car ball = bot.info.ball car_to_ball = car.pos - ball.pos bouncing_b = ball.pos.z > 130 or abs(ball.vel.z) > 300 if not bouncing_b: return 0 dist_01 = clip01(1 - norm(car_to_ball) / 3000) head_dir = lerp(Vec3(0, 0, 1), car.forward, 0.1) ang = angle_between(head_dir, car_to_ball) ang_01 = clip01(1 - ang / (math.pi / 2)) obj_bonus = { Objective.UNKNOWN: 0, Objective.GO_FOR_IT: 0.2, Objective.FOLLOW_UP: 0, Objective.ROTATE_BACK_OR_DEF: 0, }[car.objective] return clip01(0.6 * ang_01 + 0.4 * dist_01 # - 0.3 * bot.analyzer.team_mate_has_ball_01 + self.is_dribbling * self.extra_utility_bias + obj_bonus)
def utility_score(self, bot) -> float: car = bot.info.my_car if len(bot.info.teammates) == 0: team_committed01 = 0 no_defence01 = 1 else: mates = bot.info.teammates sum_pos = mates[0].pos + mates[0].vel * 0.5 for mate in mates[1:]: sum_pos += mate.pos + mate.vel * 0.5 avg_pos = sum_pos / len(mates) team_committed01 = clip01(norm(avg_pos - bot.info.own_goal.pos) / Field.LENGTH2) no_defence01 = clip01(argmin(mates, lambda mate: norm(mate.pos - bot.info.own_goal.pos))[1] / 800) dist_to_ball01 = clip01(norm(car.pos - bot.info.ball.pos) / Field.LENGTH2) obj_bonus = { Objective.UNKNOWN: 0, Objective.GO_FOR_IT: 0, Objective.FOLLOW_UP: 0.1, Objective.ROTATE_BACK_OR_DEF: 0.3, }[car.objective] return 0.9 * team_committed01 * dist_to_ball01 * no_defence01 + obj_bonus
def update(self, bot): ball = bot.info.ball # Find closest foe to ball self.opp_closest_to_ball, self.opp_closest_to_ball_dist = argmin(bot.info.opponents, lambda opp: norm(opp.pos - ball.pos)) # Possession and on/off-site self.car_with_possession = None self.ally_with_possession = None self.opp_with_possession = None for car in bot.info.cars: # On site own_goal = bot.info.goals[car.team] ball_to_goal = own_goal.pos - ball.pos car_to_ball = ball.pos - car.pos car.onsite = dot(ball_to_goal, car_to_ball) < 0.1 # Reach ball time car.reach_ball_time = predict.time_till_reach_ball(car, ball) reach01 = clip01((5 - car.reach_ball_time) / 5) # Possession point_in_front = car.pos + car.vel * 0.6 ball_point_dist = norm(ball.pos - point_in_front) dist01 = 1500 / (1500 + ball_point_dist) # Halves every 1500 uu of dist car_to_ball = bot.info.ball.pos - car.pos car_to_ball_unit = normalize(car_to_ball) in_front01 = dot(car.forward, car_to_ball_unit) car.possession = dist01 * in_front01 * reach01 * 3 if self.car_with_possession is None or car.possession > self.car_with_possession.possession: self.car_with_possession = car if car.team == bot.team and (self.ally_with_possession is None or car.possession > self.ally_with_possession.possession): self.ally_with_possession = car if car.team != bot.team and (self.opp_with_possession is None or car.possession > self.opp_with_possession.possession): self.opp_with_possession = car # Objectives for car in bot.info.cars: car.last_objective = car.objective car.objective = Objective.UNKNOWN thirdman_index, _ = argmin(bot.info.team_cars, lambda ally: norm(ally.pos - bot.info.own_goal.pos)) attacker, attacker_score = argmax(bot.info.team_cars, lambda ally: ((0.09 if ally.last_objective == Objective.GO_FOR_IT else 0) + ally.boost / 490 - (0.21 if ally.index == thirdman_index else 0) - (0.4 if not ally.onsite else 0) + ally.possession * (10_000 - ally.team_sign * ally.pos.y) / 20_000)**2) attacker.objective = Objective.GO_FOR_IT follower_expected_pos = (ball.pos + bot.info.own_goal.pos) * 0.5 follower, follower_score = argmin([ally for ally in bot.info.team_cars if ally.objective == Objective.UNKNOWN], lambda ally: (-500 if ally.last_objective == Objective.FOLLOW_UP else 0) - ally.boost * 2 + (1100 if ally.index == thirdman_index else 0) + (200 if not ally.onsite else 0) + norm(ally.pos - follower_expected_pos)) follower.objective = Objective.FOLLOW_UP for car in bot.info.team_cars: if car.objective == Objective.UNKNOWN: car.objective = Objective.ROTATE_BACK_OR_DEF
def utility(self, bot) -> float: ball_soon = predict.ball_predict(bot, 1) arena_length2 = bot.info.team_sign * Field.LENGTH / 2 own_half_01 = clip01( remap(arena_length2, -arena_length2, 0.0, 1.1, ball_soon.pos.y)) reachable_ball = predict.ball_predict( bot, predict.time_till_reach_ball(bot.info.my_car, bot.info.ball)) self.ball_to_goal_right = bot.info.enemy_goal_right - reachable_ball.pos self.ball_to_goal_left = bot.info.enemy_goal_left - reachable_ball.pos self.aim_cone = AimCone(self.ball_to_goal_right, self.ball_to_goal_left) car_to_ball = reachable_ball.pos - bot.info.my_car.pos in_position = self.aim_cone.contains_direction(car_to_ball) return clip01(own_half_01 + 0.1 * in_position)
def utility(self, bot) -> float: car = bot.info.my_car ball = bot.info.ball car_to_ball = car.pos - ball.pos bouncing_b = ball.pos.z > 130 or abs(ball.vel.z) > 300 if not bouncing_b: return 0 dist_01 = clip01(1 - norm(car_to_ball) / 3000) head_dir = lerp(Vec3(0, 0, 1), car.forward, 0.1) ang = angle_between(head_dir, car_to_ball) ang_01 = clip01(1 - ang / (math.pi / 2)) return clip01(0.6 * ang_01 + 0.4 * dist_01 # - 0.3 * bot.analyzer.team_mate_has_ball_01 + self.is_dribbling * self.extra_utility_bias)
def utility(self, bot) -> float: team_sign = bot.info.team_sign length = team_sign * Field.LENGTH / 2 ball_own_half_01 = clip01( remap(-length, length, -0.2, 1.2, bot.info.ball.pos.y)) reachable_ball = predict.ball_predict( bot, predict.time_till_reach_ball(bot.info.my_car, bot.info.ball)) car_to_ball = reachable_ball.pos - bot.info.my_car.pos in_position = self.aim_cone.contains_direction(car_to_ball, math.pi / 8) return ball_own_half_01 * in_position
def utility_score(self, bot) -> float: car = bot.info.my_car ball = bot.info.ball half_way = lerp(bot.info.own_goal.pos, ball.pos, 0.5) _, missing_center_guy01 = argmin(bot.info.team_cars, lambda mate: 1.0 - clip01(norm(mate.pos - half_way) / Field.LENGTH2)) attack_in_front = any(is_closer_to_goal_than(car.pos, mate.pos, car.team) for mate in bot.info.teammates if mate.objective == Objective.GO_FOR_IT) ball_in_front = is_closer_to_goal_than(car.pos, ball.pos, car.team) obj_bonus = { Objective.UNKNOWN: 0, Objective.GO_FOR_IT: 0, Objective.FOLLOW_UP: 0.23, Objective.ROTATE_BACK_OR_DEF: 0, }[car.objective] return attack_in_front * ball_in_front * missing_center_guy01 + obj_bonus
def utility_score(self, bot) -> float: team_sign = bot.info.team_sign length = team_sign * Field.LENGTH / 2 ball_own_half_01 = clip01( remap(-length, length, -0.2, 1.2, bot.info.ball.pos.y)) reachable_ball = predict.ball_predict( bot, predict.time_till_reach_ball(bot.info.my_car, bot.info.ball)) car_to_ball = reachable_ball.pos - bot.info.my_car.pos in_position = self.aim_cone.contains_direction(car_to_ball, math.pi / 8) obj_bonus = { Objective.UNKNOWN: 0, Objective.GO_FOR_IT: 0.15, Objective.FOLLOW_UP: 0, Objective.ROTATE_BACK_OR_DEF: 0.0, }[bot.info.my_car.objective] return ball_own_half_01 * in_position + obj_bonus
def exec(self, bot): pred_ball = predict.ball_predict(bot, bot.info.my_car.reach_ball_time) # On a scale from 0 to 1, how much is this a clear? clear01 = clip01( norm(bot.info.opp_goal.pos - pred_ball.pos) / Field.LENGTH)**2 ts = bot.info.team_sign right = lerp(bot.info.opp_goal.right_post, Vec3(ts * Field.WIDTH2, ts * (Field.LENGTH2 + 300), 0), clear01) left = lerp(bot.info.opp_goal.left_post, Vec3(-ts * Field.WIDTH2, ts * (Field.LENGTH2 + 300), 0), clear01) ball_to_right = right - pred_ball.pos ball_to_left = left - pred_ball.pos aim_cone = AimCone(ball_to_right, ball_to_left) shot_ctrls = bot.shoot.with_aiming(bot, aim_cone, bot.info.my_car.reach_ball_time) if bot.do_rendering: if bot.shoot.can_shoot: aim_cone.draw(bot, bot.shoot.ball_when_hit.pos, b=0, r=0) if not bot.shoot.can_shoot: # We can't shoot on target if len(bot.info.teammates) != 0: # Consider passing for mate in bot.info.teammates: point_in_front_of_mate = lerp(mate.pos, bot.info.opp_goal.pos, 0.5) shot_ctrls = bot.shoot.towards( bot, point_in_front_of_mate, bot.info.my_car.reach_ball_time) if bot.shoot.can_shoot: if bot.do_rendering: rendering.draw_cross(bot, point_in_front_of_mate, bot.renderer.green()) return shot_ctrls # Atba with bias I guess if bot.do_rendering: bot.renderer.draw_line_3d(bot.info.my_car.pos, pred_ball.pos, bot.renderer.red()) return bot.shoot.any_touch(bot, bot.info.my_car.reach_ball_time) # # We are out of position, start rotating back # own_goal = lerp(bot.info.own_goal.pos, bot.info.ball.pos, 0.5) # return bot.drive.towards_point( # bot, # own_goal, # target_vel=1460, # slide=False, # boost_min=0, # can_keep_speed=True # ) else: # Shoot! if bot.shoot.using_curve and bot.do_rendering: rendering.draw_bezier(bot, [ bot.info.my_car.pos, bot.shoot.curve_point, bot.shoot.ball_when_hit.pos ]) return shot_ctrls