From 0bfdf8de82a886ed16117c892e96a9a8601eee85 Mon Sep 17 00:00:00 2001 From: pilkiad Date: Sat, 18 Jan 2025 11:39:36 +0100 Subject: [PATCH 1/6] (change #14) Improved kick-off formation By simply changing the target position for the two most offending players, the problem in issue #14 is fixed by this --- base/formation_dt/setplay_our_formation.conf | 4 ++-- base/generator_action.py | 7 +++++-- base/set_play/bhv_set_play.py | 3 +++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/base/formation_dt/setplay_our_formation.conf b/base/formation_dt/setplay_our_formation.conf index 537c4835..22a37661 100644 --- a/base/formation_dt/setplay_our_formation.conf +++ b/base/formation_dt/setplay_our_formation.conf @@ -20,12 +20,12 @@ Ball 0 0 3 -15.33 3.66 4 -9.29 -15.12 5 -10.84 13.69 -6 -0.71 -0.36 +6 -10.71 -0.36 7 0 -6.97 8 0.48 6.73 9 13.69 -20.13 10 10.73 24 -11 16.08 0 +11 -16.08 0 ----- 1 ----- Ball -54 0 1 -50 -0 diff --git a/base/generator_action.py b/base/generator_action.py index e408603f..265bb261 100644 --- a/base/generator_action.py +++ b/base/generator_action.py @@ -27,9 +27,12 @@ def __init__(self): self.min_opp_dist = 0.0 def calculate_min_opp_dist(self, wm: 'WorldModel' = None): - if wm is None or wm.opponents() is None or len(wm.opponents()) == 0: + try: + if wm is None or wm.opponents() is None or len(wm.opponents()) == 0: + return 0.0 + return min([opp.pos().dist(self.target_ball_pos) for opp in wm.opponents() if opp is not None and opp.unum() > 0]) + except: return 0.0 - return min([opp.pos().dist(self.target_ball_pos) for opp in wm.opponents() if opp is not None and opp.unum() > 0]) def evaluate(self, wm: 'WorldModel' = None): self.min_opp_dist = self.calculate_min_opp_dist(wm) diff --git a/base/set_play/bhv_set_play.py b/base/set_play/bhv_set_play.py index 0293171f..aac3787b 100644 --- a/base/set_play/bhv_set_play.py +++ b/base/set_play/bhv_set_play.py @@ -38,6 +38,7 @@ def execute(self, agent: 'PlayerAgent'): st = StrategyFormation.i() target = st.get_pos(wm.self().unum()) + if wm.game_mode().side() is wm.our_side(): nearest_tm_dist = 1000 nearest_tm = 0 @@ -50,8 +51,10 @@ def execute(self, agent: 'PlayerAgent'): if dist < nearest_tm_dist: nearest_tm_dist = dist nearest_tm = i + if nearest_tm is wm.self().unum(): target = wm.ball().pos() + if GoToPoint(target, 0.5, 100).execute(agent): agent.set_neck_action(NeckTurnToBallOrScan()) return True From 2b0dab0bcd7683d9cf9eaeded4394fb88916eff6 Mon Sep 17 00:00:00 2001 From: pilkiad Date: Tue, 21 Jan 2025 14:06:13 +0100 Subject: [PATCH 2/6] (change) Improved goalie behaviour --- base/bhv_move.py | 13 +++++++++++-- base/goalie_decision.py | 6 +++--- base/set_play/bhv_set_play.py | 2 +- lib/action/go_to_point.py | 9 +++++---- lib/action/stop_ball.py | 19 ++++++++++++------- lib/player/object_self.py | 2 +- lib/player/player_agent.py | 6 +++--- 7 files changed, 36 insertions(+), 21 deletions(-) diff --git a/base/bhv_move.py b/base/bhv_move.py index ed9e9c51..45a83bd3 100644 --- a/base/bhv_move.py +++ b/base/bhv_move.py @@ -52,13 +52,22 @@ def execute(self, agent: 'PlayerAgent'): agent.set_neck_action(NeckTurnToBall()) return True - if opp_min < min(tm_min, self_min): + if opp_min < min(tm_min, self_min) and agent.world().self().unum() != 1: if Bhv_Block().execute(agent): agent.set_neck_action(NeckTurnToBall()) return True st = StrategyFormation().i() target = st.get_pos(agent.world().self().unum()) + if agent.world().self().unum() == 1: + target = Vector2D(target.x(), wm.ball().pos().y() / 3) + + if target.x() > wm.ball().pos().x(): + target = Vector2D(wm.ball().pos().x() + 7, target.y()) + + #if wm.ball().pos().x() > 15: + # target = Vector2D(target.x() + 20, target.y()) + log.debug_client().set_target(target) log.debug_client().add_message('bhv_move') @@ -69,7 +78,7 @@ def execute(self, agent: 'PlayerAgent'): dist_thr = 1.0 if GoToPoint(target, dist_thr, dash_power).execute(agent): - agent.set_neck_action(NeckTurnToBallOrScan()) + agent.set_neck_action(NeckTurnToBall()) return True return False diff --git a/base/goalie_decision.py b/base/goalie_decision.py index 16c234a9..9a9702d3 100644 --- a/base/goalie_decision.py +++ b/base/goalie_decision.py @@ -33,8 +33,8 @@ def decision(agent: 'PlayerAgent'): SP = ServerParam.i() wm = agent.world() - our_penalty = Rect2D(Vector2D(-SP.pitch_half_length(), -SP.penalty_area_half_width() + 1), - Size2D(SP.penalty_area_length() - 1, SP.penalty_area_width() - 2)) + our_penalty = Rect2D(Vector2D(-SP.pitch_half_length(), -SP.penalty_area_half_width() - 5), + Size2D(SP.penalty_area_length() - 1, SP.penalty_area_width() - 5)) log.os_log().debug(f'########## gdc={wm.time().cycle()}') log.os_log().debug(f'########## gd gmt={wm.game_mode().type()}') @@ -44,7 +44,7 @@ def decision(agent: 'PlayerAgent'): return False if (wm.time().cycle() > wm.self().catch_time().cycle() + SP.catch_ban_cycle() - and wm.ball().dist_from_self() < SP.catchable_area() - 0.05 + and wm.ball().dist_from_self() < SP.catchable_area() - 0.1 and our_penalty.contains(wm.ball().pos())): agent.do_catch() diff --git a/base/set_play/bhv_set_play.py b/base/set_play/bhv_set_play.py index aac3787b..ce7dcdd8 100644 --- a/base/set_play/bhv_set_play.py +++ b/base/set_play/bhv_set_play.py @@ -1,7 +1,7 @@ from base.set_play.bhv_set_play_before_kick_off import Bhv_BeforeKickOff from base.strategy_formation import * from lib.action.neck_scan_players import NeckScanPlayers -from lib.action.neck_turn_to_ball_or_scan import NeckTurnToBallOrScan +from lib.action.neck_turn_to_ball_or_scan import NeckTurnToBallOrScan, NeckTurnToBall from lib.action.scan_field import ScanField from lib.debug.debug import log from lib.debug.level import Level diff --git a/lib/action/go_to_point.py b/lib/action/go_to_point.py index f9c30b1c..180e5dfe 100644 --- a/lib/action/go_to_point.py +++ b/lib/action/go_to_point.py @@ -31,7 +31,7 @@ def execute(self, agent): target_dist = target_rel.r() if target_dist < self._dist_thr: - agent.do_turn(0.0) + #agent.do_turn(0.0) return False self.check_collision(agent) @@ -42,7 +42,7 @@ def execute(self, agent): if self.do_dash(agent): return True - agent.do_turn(0) + #agent.do_turn(0) return False def do_turn(self, agent): @@ -94,8 +94,9 @@ def do_dash(self, agent): required_accel = first_speed - rel_vel.x() if math.fabs(required_accel) < 0.05: return False - dash_power = required_accel / wm.self().dash_rate() - dash_power = min(dash_power, self._max_dash_power) + #dash_power = required_accel / wm.self().dash_rate() + #dash_power = min(dash_power, self._max_dash_power) + dash_power = self._max_dash_power if self._back_mode: dash_power = -dash_power dash_power = SP.i().normalize_dash_power(dash_power) diff --git a/lib/action/stop_ball.py b/lib/action/stop_ball.py index 303a2468..978f75e9 100644 --- a/lib/action/stop_ball.py +++ b/lib/action/stop_ball.py @@ -8,6 +8,8 @@ from pyrusgeom.angle_deg import AngleDeg from lib.rcsc.server_param import ServerParam +from lib.action.neck_turn_to_ball_or_scan import NeckTurnToBallOrScan, NeckTurnToBall + from typing import TYPE_CHECKING if TYPE_CHECKING: from lib.player.world_model import WorldModel @@ -38,11 +40,14 @@ def execute(self, agent: 'PlayerAgent'): wm: 'WorldModel' = agent.world() if not wm.self().is_kickable(): return False + + agent.set_neck_action(NeckTurnToBall()) + if not wm.ball().vel_valid(): # Always true until NFS nice :) required_accel = wm.self().vel() - (wm.self().pos() - wm.ball().pos()) kick_power = required_accel.r() / wm.self().kick_rate() kick_power *= 0.5 - agent.do_kick(min(kick_power, ServerParam.i().max_power()), + agent.do_kick(max(kick_power, ServerParam.i().max_power()), required_accel.th() - wm.self().body()) return True @@ -51,12 +56,12 @@ def execute(self, agent: 'PlayerAgent'): self.calcAccel(agent) - if self._accel_radius < 0.02: - agent.do_turn(0.0) - return False - kick_power = 0.0 - # kick_power = self._accel_radius / wm.self().kickRate() - # kick_power = min(kick_power, i.maxPower()) + #if self._accel_radius < 0.02: + # agent.do_turn(0.0) + # return False + kick_power = ServerParam.i().max_power() + #kick_power = self._accel_radius / wm.self().kickRate() + #kick_power = max(kick_power, i.maxPower()) return agent.do_kick(kick_power, self._accel_angle - wm.self().body()) diff --git a/lib/player/object_self.py b/lib/player/object_self.py index 0b24bdc4..9f6f2fe5 100644 --- a/lib/player/object_self.py +++ b/lib/player/object_self.py @@ -389,7 +389,7 @@ def update_ball_info(self, ball: BallObject): log.os_log().debug(f"(self obj update ball_info) kickable_area={ptype.kickable_area()}") if ball.dist_from_self() <= ptype.kickable_area(): - buff = 0.055 + buff = 0.1 if ball.seen_pos_count() >= 1: buff = 0.155 if ball.seen_pos_count() >= 2: diff --git a/lib/player/player_agent.py b/lib/player/player_agent.py index 0065bce5..8d8cdfd3 100644 --- a/lib/player/player_agent.py +++ b/lib/player/player_agent.py @@ -441,9 +441,9 @@ def do_catch(self): log.os_log().error(f"(do catch) player({self._real_world.self_unum()} play mode is not play_on!") return False - if not wm.ball().rpos_valid(): - log.os_log().error(f"(do catch) player({self._real_world.self_unum()} ball rpos is not valid!") - return False + #if not wm.ball().rpos_valid(): + # log.os_log().error(f"(do catch) player({self._real_world.self_unum()} ball rpos is not valid!") + # return False self._last_body_command.append(self.effector().set_catch()) From 0b948118ce08f27a5b072a25332af9fc2cbd5170 Mon Sep 17 00:00:00 2001 From: pilkiad Date: Tue, 21 Jan 2025 14:06:27 +0100 Subject: [PATCH 3/6] (change) Made players more aggressive --- base/bhv_block.py | 2 +- base/bhv_kick.py | 17 ++++-- base/generator_dribble.py | 8 ++- base/generator_pass.py | 102 +++++++++++++++++++++++----------- base/generator_shoot.py | 19 +++++-- lib/action/intercept_table.py | 2 +- lib/action/smart_kick.py | 9 ++- lib/rcsc/server_param.py | 2 +- start.sh | 6 +- 9 files changed, 114 insertions(+), 53 deletions(-) diff --git a/base/bhv_block.py b/base/bhv_block.py index e1e1a02a..ee4d0079 100644 --- a/base/bhv_block.py +++ b/base/bhv_block.py @@ -30,7 +30,7 @@ def execute(self, agent: 'PlayerAgent'): continue for c in range(1, 40): dribble_pos = ball_pos + Vector2D.polar2vector(c * dribble_speed_etimate, dribble_angle_estimate) - turn_cycle = Tools.predict_player_turn_cycle(tm.player_type(), tm.body(), tm.vel().r(), tm.pos().dist(dribble_pos), (dribble_pos - tm.pos()).th(), 0.2, False) + turn_cycle = Tools.predict_player_turn_cycle(tm.player_type(), tm.body(), tm.vel().r(), tm.pos().dist(dribble_pos) * 2, (dribble_pos - tm.pos()).th(), 0.2, False) tm_cycle = tm.player_type().cycles_to_reach_distance(tm.inertia_point(opp_min).dist(dribble_pos)) + turn_cycle if tm_cycle <= opp_min + c: if tm_cycle < block_cycle: diff --git a/base/bhv_kick.py b/base/bhv_kick.py index 22c6de4f..b01331af 100644 --- a/base/bhv_kick.py +++ b/base/bhv_kick.py @@ -31,21 +31,28 @@ def execute(self, agent: 'PlayerAgent'): 'shoot' + 'to ' + shoot_candidate.target_point.__str__() + ' ' + str(shoot_candidate.first_ball_speed)) SmartKick(shoot_candidate.target_point, shoot_candidate.first_ball_speed, shoot_candidate.first_ball_speed - 1, 3).execute(agent) - agent.set_neck_action(NeckScanPlayers()) + #agent.set_neck_action(NeckScanPlayers()) return True else: action_candidates: List[KickAction] = [] + action_candidates += BhvPassGen().generator(wm) - action_candidates += BhvDribbleGen().generator(wm) + + dribbles = BhvDribbleGen().generator(wm) + if dribbles is not None: + action_candidates += BhvDribbleGen().generator(wm) if len(action_candidates) == 0: - return self.no_candidate_action(agent) + return True + #return self.no_candidate_action(agent) best_action: KickAction = max(action_candidates) target = best_action.target_ball_pos log.debug_client().set_target(target) log.debug_client().add_message(best_action.type.value + 'to ' + best_action.target_ball_pos.__str__() + ' ' + str(best_action.start_ball_speed)) + print("SMORT KICKICK ") + print(best_action.type.value + 'to ' + best_action.target_ball_pos.__str__() + ' ' + str(best_action.start_ball_speed)) SmartKick(target, best_action.start_ball_speed, best_action.start_ball_speed - 1, 3).execute(agent) if best_action.type is KickActionType.Pass: @@ -54,7 +61,7 @@ def execute(self, agent: 'PlayerAgent'): agent.effector().queued_next_ball_pos(), agent.effector().queued_next_ball_vel())) - agent.set_neck_action(NeckScanPlayers()) + #agent.set_neck_action(NeckScanPlayers()) return True def no_candidate_action(self, agent: 'PlayerAgent'): @@ -69,5 +76,5 @@ def no_candidate_action(self, agent: 'PlayerAgent'): log.debug_client().add_message(best_action.type.value + 'to ' + best_action.target_ball_pos.__str__() + ' ' + str(best_action.start_ball_speed)) SmartKick(target, best_action.start_ball_speed, best_action.start_ball_speed - 2.0, 2).execute(agent) - agent.set_neck_action(NeckScanPlayers()) + #agent.set_neck_action(NeckScanPlayers()) return HoldBall().execute(agent) \ No newline at end of file diff --git a/base/generator_dribble.py b/base/generator_dribble.py index 71527811..6860caf8 100644 --- a/base/generator_dribble.py +++ b/base/generator_dribble.py @@ -19,6 +19,10 @@ class BhvDribbleGen(BhvKickGen): def generator(self, wm: 'WorldModel'): global max_dribble_time + + if wm.self().pos().x() > 40: + return None + start_time = time.time() self.generate_simple_dribble(wm) @@ -98,7 +102,7 @@ def simulate_kick_turns_dashes(self, wm: 'WorldModel', dash_angle, n_turn): # trap_rel = Vector2D.polar2vector(ptype.playerSize() + ptype.kickableMargin() * 0.2 + SP.ball_size(), dash_angle) trap_rel = Vector2D.polar2vector(ptype.player_size() + ptype.kickable_margin() * 0.2 + 0, dash_angle) - max_x = sp.pitch_half_length() - 1.0 + max_x = sp.pitch_half_length() - 5.0 max_y = sp.pitch_half_width() - 1.0 for n_dash in range(max_dash, min_dash - 1, -1): @@ -227,7 +231,7 @@ def check_opponent(self, wm: 'WorldModel', ball_trap_pos: Vector2D, dribble_step target_dist = opp_pos.dist(ball_trap_pos) - if target_dist - control_area < 0.001: + if target_dist - control_area < 0.01: if debug_dribble: log.sw_log().dribble().add_text( "###OPP {} Catch, ball will be in his body".format(o)) return False diff --git a/base/generator_pass.py b/base/generator_pass.py index ece617c5..47a5d882 100644 --- a/base/generator_pass.py +++ b/base/generator_pass.py @@ -35,8 +35,8 @@ def generator(self, wm: 'WorldModel'): # and r.pos().x() < self.best_pass.target_ball_pos.x() - 5: # break self.generate_direct_pass(wm, r) - self.generate_lead_pass(wm, r) - self.generate_through_pass(wm, r) + #self.generate_lead_pass(wm, r) + #self.generate_through_pass(wm, r) if debug_pass: for candid in self.debug_list: @@ -83,22 +83,22 @@ def update_receivers(self, wm: 'WorldModel'): def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'): sp = SP.i() - min_receive_step = 3 - max_direct_pass_dist = 0.8 * smath.inertia_final_distance(sp.ball_speed_max(), sp.ball_decay()) + min_receive_step = 1 + max_direct_pass_dist = smath.inertia_final_distance(sp.ball_speed_max(), sp.ball_decay()) max_receive_ball_speed = sp.ball_speed_max() * pow(sp.ball_decay(), min_receive_step) - min_direct_pass_dist = receiver.player_type().kickable_area() * 2.2 - if receiver.pos().x() > sp.pitch_half_length() - 1.5 \ - or receiver.pos().x() < -sp.pitch_half_length() + 5.0 \ - or receiver.pos().abs_y() > sp.pitch_half_width() - 1.5: - if debug_pass: - log.sw_log().pass_().add_text( '#DPass to {} {}, out of field'.format(receiver.unum(), receiver.pos())) - return + min_direct_pass_dist = 0 + #if receiver.pos().x() > sp.pitch_half_length() - 1.5 \ + # or receiver.pos().x() < -sp.pitch_half_length() + 5.0 \ + # or receiver.pos().abs_y() > sp.pitch_half_width() - 1.5: + # if debug_pass: + # log.sw_log().pass_().add_text( '#DPass to {} {}, out of field'.format(receiver.unum(), receiver.pos())) + # return # TODO sp.ourTeamGoalPos() - if receiver.pos().x() < wm.ball().pos().x() + 1.0 \ - and receiver.pos().dist2(Vector2D(-52.5, 0)) < pow(18.0, 2): - if debug_pass: - log.sw_log().pass_().add_text( '#DPass to {} {}, danger near goal'.format(receiver.unum(), receiver.pos())) - return + #if receiver.pos().x() < wm.ball().pos().x() + 1.0 \ + # and receiver.pos().dist2(Vector2D(-52.5, 0)) < pow(18.0, 2): + # if debug_pass: + # log.sw_log().pass_().add_text( '#DPass to {} {}, danger near goal'.format(receiver.unum(), receiver.pos())) + # return ptype = receiver.player_type() max_ball_speed = wm.self().kick_rate() * sp.max_power() @@ -111,18 +111,18 @@ def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'): receive_point = ptype.inertiaFinalPoint(receiver.pos(), receiver.vel()) ball_move_dist = wm.ball().pos().dist(receive_point) - if ball_move_dist < min_direct_pass_dist or max_direct_pass_dist < ball_move_dist: - if debug_pass: - log.sw_log().pass_().add_text( '#DPass to {} {}, far or close'.format(receiver.unum(), receiver.pos())) - return + #if ball_move_dist < min_direct_pass_dist or max_direct_pass_dist < ball_move_dist: + # if debug_pass: + # log.sw_log().pass_().add_text( '#DPass to {} {}, far or close'.format(receiver.unum(), receiver.pos())) + # return - if wm.game_mode().type().is_goal_kick() \ - and receive_point.x() < sp.our_penalty_area_line_x() + 1.0 \ - and receive_point.abs_y() < sp.penalty_area_half_width() + 1.0: - if debug_pass: - log.sw_log().pass_().add_text( - '#DPass to {} {}, in penalty area in goal kick mode'.format(receiver.unum(), receiver.pos())) - return + #if wm.game_mode().type().is_goal_kick() \ + # and receive_point.x() < sp.our_penalty_area_line_x() + 1.0 \ + # and receive_point.abs_y() < sp.penalty_area_half_width() + 1.0: + # if debug_pass: + # log.sw_log().pass_().add_text( + # '#DPass to {} {}, in penalty area in goal kick mode'.format(receiver.unum(), receiver.pos())) + # return max_receive_ball_speed = min(max_receive_ball_speed, ptype.kickable_area() + ( sp.max_dash_power() * ptype.dash_power_rate() * ptype.effort_max()) * 1.8) @@ -133,8 +133,9 @@ def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'): min_ball_step = sp.ball_move_step(sp.ball_speed_max(), ball_move_dist) # TODO Penalty step start_step = max(max(min_receive_step, min_ball_step), 0) - max_step = start_step + 2 + max_step = start_step + 30 log.sw_log().pass_().add_text( '#DPass to {} {}'.format(receiver.unum(), receiver.pos())) + print('#DPass to {} {}'.format(receiver.unum(), receiver.pos())) self.create_pass(wm, receiver, receive_point, start_step, max_step, min_ball_speed, max_ball_speed, min_receive_ball_speed, @@ -472,27 +473,66 @@ def create_pass(self, wm: 'WorldModel', receiver, receive_point: Vector2D, o_step, max_step)) self.debug_list.append((self.index, receive_point, True)) + candidate = KickAction() candidate.type = KickActionType.Pass candidate.start_ball_pos = wm.ball().pos() candidate.target_ball_pos = receive_point candidate.target_unum = receiver.unum() - candidate.start_ball_speed = first_ball_speed + candidate.start_ball_speed = max_first_ball_speed candidate.evaluate(wm) + #candidate.eval += 5 + opp_min = wm.intercept_table().opponent_reach_cycle() + if opp_min <= 5: + candidate.eval += 30 + else: + candidate.eval -= 10 + + if candidate.target_ball_pos.abs_y() <= 5: + candidate.eval += 30 + + if candidate.target_ball_pos.x() <= -50: + candidate.eval -= 1000 + """ + + if wm.game_mode() != GameModeType.PlayOn: + candidate.eval += 100 + + if candidate.start_ball_pos.x() >= 30 and candidate.target_ball_pos.abs_y() <= 5: + candidate.eval += 60 + + if candidate.target_ball_pos.abs_y() >= 20: + candidate.eval -= 30 + + if candidate.target_ball_pos.abs_x() <= 30 and candidate.target_ball_pos.x() > candidate.start_ball_pos.x(): + candidate.eval += 10 + if candidate.target_ball_pos.x() >= 40 and candidate.target_ball_pos.x() < candidate.start_ball_pos.x(): + candidate.eval += 30 + + opp_min = wm.intercept_table().opponent_reach_cycle() + if opp_min <= 5: + candidate.eval += 30 + else: + candidate.eval -= 10 + + if wm.self().pos().abs_x() > 40: + candidate.eval += 30 + """ self.candidates.append(candidate) if self.best_pass is None or candidate.eval > self.best_pass.eval: self.best_pass = candidate - find_another_pass = False + find_another_pass = True if not find_another_pass: break - + """ if o_step <= step + 3: break if min_step + 3 <= step: break + """ def predict_opponents_reach_step(self, wm: 'WorldModel', first_ball_pos: Vector2D, first_ball_speed, ball_move_angle: AngleDeg, receive_point: Vector2D, max_cycle, description): diff --git a/base/generator_shoot.py b/base/generator_shoot.py index 04247981..09f90eba 100644 --- a/base/generator_shoot.py +++ b/base/generator_shoot.py @@ -42,6 +42,8 @@ def generator(self, wm: 'WorldModel') -> ShootAction: target_point = Vector2D(goal_l.x(), goal_l.y() + dist_step * i) log.sw_log().shoot().add_text( "#shoot {} to {}".format(self.total_count, target_point)) self.create_shoot(wm, target_point) + self.create_shoot(wm, Vector2D(target_point.x(), target_point.y() + 2)) + self.create_shoot(wm, Vector2D(target_point.x(), target_point.y() - 2)) if len(self.candidates) == 0: return None @@ -62,6 +64,9 @@ def create_shoot(self, wm: 'WorldModel', target_point: Vector2D): log.sw_log().shoot().add_text( "#shoot {} didnt see goalie".format(self.total_count)) return + if wm.self().pos().abs_x() < 30 and wm.self().pos().abs_x() > 10: + return + sp = SP.i() ball_speed_max = sp.ball_speed_max() if wm.game_mode().type() == GameModeType.PlayOn \ @@ -99,9 +104,9 @@ def check_shoot(self, wm: 'WorldModel', target_point: Vector2D, first_ball_speed ball_reach_step = int( math.ceil(smath.calc_length_geom_series(first_ball_speed, ball_move_dist, sp.ball_decay()))) - if ball_reach_step == -1: - log.sw_log().shoot().add_text( 'Cant arrive to target') - return False + #if ball_reach_step == -1: + # log.sw_log().shoot().add_text( 'Cant arrive to target') + # return False log.sw_log().shoot().add_text( '{} {} {} {} {}'.format(first_ball_speed, ball_move_dist, sp.ball_decay(), smath.calc_length_geom_series(first_ball_speed, ball_move_dist, sp.ball_decay()), math.ceil(smath.calc_length_geom_series(first_ball_speed, ball_move_dist, sp.ball_decay())))) course = ShootAction(self.total_count, target_point, first_ball_speed, ball_move_angle, ball_move_dist, ball_reach_step) @@ -117,6 +122,8 @@ def check_shoot(self, wm: 'WorldModel', target_point: Vector2D, first_ball_speed for o in range(1, 12): opp = wm.their_player(o) + if opp is None: + continue if opp.unum() < 1: log.sw_log().shoot().add_text( '## opp {} can not, unum') continue @@ -135,8 +142,8 @@ def check_shoot(self, wm: 'WorldModel', target_point: Vector2D, first_ball_speed continue if opp.goalie(): - if self.maybe_goalie_catch(opp, course, wm): - return False + #if self.maybe_goalie_catch(opp, course, wm): + # return False log.sw_log().shoot().add_text( '## opp {} can not, goalie catch') continue @@ -287,7 +294,7 @@ def evaluate_courses(self, wm: 'WorldModel'): score += 100.0 goalie_rate = 1.0 - if goalie.unum() > 0: + if goalie is not None and goalie.unum() > 0: variance2 = 1.0 if it.goalie_never_reach else pow(10.0, 2) angle_diff = (it.ball_move_angle - goalie_angle).abs() goalie_rate = 1.0 - math.exp(-pow(angle_diff, 2) / (2.0 * variance2) ) diff --git a/lib/action/intercept_table.py b/lib/action/intercept_table.py index f8c90fa7..3c4b8189 100644 --- a/lib/action/intercept_table.py +++ b/lib/action/intercept_table.py @@ -21,7 +21,7 @@ class InterceptTable: def __init__(self): self._last_update_time: GameTime = GameTime(-10, -100) - self._max_cycle: int = 30 + self._max_cycle: int = 100 self._ball_cache: list[Vector2D] = [] self._self_cache: list[Vector2D] = [] diff --git a/lib/action/smart_kick.py b/lib/action/smart_kick.py index 35895ad7..ebc8ba2b 100644 --- a/lib/action/smart_kick.py +++ b/lib/action/smart_kick.py @@ -45,11 +45,13 @@ def execute(self, agent: 'PlayerAgent'): if SmartKick.debug_print_DEBUG: log.os_log().info("----- NotKickable -----") log.sw_log().kick().add_text("not kickable") + print("quitting the kick non kickable") return False if not wm.ball().vel_valid(): if SmartKick.debug_print_DEBUG: log.os_log().info("-- NonValidBall -> StopBall --") log.sw_log().kick().add_text("unknown ball vel") + print("quitting the kick vel") return StopBall().execute(agent) first_speed = min(self._first_speed, ServerParam.i().ball_speed_max()) first_speed_thr = max(0.0, self._first_speed_thr) @@ -66,7 +68,7 @@ def execute(self, agent: 'PlayerAgent'): if ans[0]: self._sequence = ans[1] - if self._sequence.speed_ >= first_speed_thr: # double check + if True: # double check vel = self._sequence.pos_list_[0] - wm.ball().pos() kick_accel = vel - wm.ball().vel() if SmartKick.debug_print_DEBUG: @@ -79,10 +81,13 @@ def execute(self, agent: 'PlayerAgent'): log.os_log().debug(f"----------------#### Player Number {wm.self().unum()} 'DO_KICK'ed in SmartKick at Time: {wm.time().cycle()} ####----------------") log.sw_log().kick().add_text(f"----------------#### Player Number {wm.self().unum()} 'DO_KICK'ed in SmartKick at Time: {wm.time().cycle()} ####----------------") return True + else: + print("HERE LIES THE ERROR") # failed to search the kick sequence log.sw_log().kick().add_text("----->>>>>Hold Ball") - HoldBall(False, self._target_point, self._target_point).execute(agent) + print("failed the kick end") + HoldBall(True, self._target_point, self._target_point).execute(agent) return False def sequence(self): diff --git a/lib/rcsc/server_param.py b/lib/rcsc/server_param.py index c6197fae..97748326 100644 --- a/lib/rcsc/server_param.py +++ b/lib/rcsc/server_param.py @@ -713,7 +713,7 @@ def parse(self, message): def set_additional_param(self): self._kickable_area = self._kickable_margin + self._ball_size + self._player_size - self._catchable_area = ((self.catch_area_w()*0.5)**2 + (self.catch_area_l()**2))**0.5 + self._catchable_area = ((self.catch_area_w()*0.5)**1.999 + (self.catch_area_l()**1.999))**0.5 self._control_radius_width = self._control_radius - self._player_size accel_max = self.max_dash_power() * self.default_dash_power_rate() * self.default_effort_max() diff --git a/start.sh b/start.sh index 622d5453..b2e5b6c7 100755 --- a/start.sh +++ b/start.sh @@ -34,19 +34,17 @@ pids=() $run_command $options --goalie & pids+=($!) -sleep 1 +sleep 0.1 i=2 while [ $i -le 11 ] ; do $run_command $options --player & pids+=($!) - sleep 0.2 - i=`expr $i + 1` done -sleep 2 +sleep 0.1 $run_command $options --coach & pids+=($!) From 3e3dfc52bbfdb6c44e1c83f2120bffcc11ef04d4 Mon Sep 17 00:00:00 2001 From: pilkiad Date: Tue, 21 Jan 2025 14:25:49 +0100 Subject: [PATCH 4/6] (change) Made shooting more aggressive --- base/generator_pass.py | 8 +++++++- base/generator_shoot.py | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/base/generator_pass.py b/base/generator_pass.py index 47a5d882..b7cfa501 100644 --- a/base/generator_pass.py +++ b/base/generator_pass.py @@ -85,7 +85,7 @@ def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'): sp = SP.i() min_receive_step = 1 max_direct_pass_dist = smath.inertia_final_distance(sp.ball_speed_max(), sp.ball_decay()) - max_receive_ball_speed = sp.ball_speed_max() * pow(sp.ball_decay(), min_receive_step) + max_receive_ball_speed = 3 * sp.ball_speed_max() * pow(sp.ball_decay(), min_receive_step) min_direct_pass_dist = 0 #if receiver.pos().x() > sp.pitch_half_length() - 1.5 \ # or receiver.pos().x() < -sp.pitch_half_length() + 5.0 \ @@ -493,6 +493,12 @@ def create_pass(self, wm: 'WorldModel', receiver, receive_point: Vector2D, if candidate.target_ball_pos.x() <= -50: candidate.eval -= 1000 + + if wm.game_mode() != GameModeType.PlayOn: + candidate.eval += 100 + + if wm.self().pos().abs_x() > 40: + candidate.eval += 30 """ if wm.game_mode() != GameModeType.PlayOn: diff --git a/base/generator_shoot.py b/base/generator_shoot.py index 09f90eba..f9d164b3 100644 --- a/base/generator_shoot.py +++ b/base/generator_shoot.py @@ -59,12 +59,12 @@ def generator(self, wm: 'WorldModel') -> ShootAction: def create_shoot(self, wm: 'WorldModel', target_point: Vector2D): ball_move_angle = (target_point - wm.ball().pos()).th() goalie = wm.get_opponent_goalie() - if goalie is None or (goalie.unum() > 0 and 5 < goalie.pos_count() < 30): + #if goalie is None or (goalie.unum() > 0 and 5 < goalie.pos_count() < 30): # TODO and wm.dirCount( ball_move_angle ) > 3 - log.sw_log().shoot().add_text( "#shoot {} didnt see goalie".format(self.total_count)) - return + # log.sw_log().shoot().add_text( "#shoot {} didnt see goalie".format(self.total_count)) + # return - if wm.self().pos().abs_x() < 30 and wm.self().pos().abs_x() > 10: + if wm.self().pos().abs_x() < 30 and wm.self().pos().x() > 0: return sp = SP.i() From 8842ddb09122104c8e2847b458a1feca7fda9bc0 Mon Sep 17 00:00:00 2001 From: pilkiad Date: Tue, 21 Jan 2025 14:36:12 +0100 Subject: [PATCH 5/6] (change) Added position based pass eval statement --- base/generator_pass.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/base/generator_pass.py b/base/generator_pass.py index b7cfa501..f9097e39 100644 --- a/base/generator_pass.py +++ b/base/generator_pass.py @@ -481,7 +481,7 @@ def create_pass(self, wm: 'WorldModel', receiver, receive_point: Vector2D, candidate.target_unum = receiver.unum() candidate.start_ball_speed = max_first_ball_speed candidate.evaluate(wm) - #candidate.eval += 5 + candidate.eval += 5 opp_min = wm.intercept_table().opponent_reach_cycle() if opp_min <= 5: candidate.eval += 30 @@ -499,6 +499,11 @@ def create_pass(self, wm: 'WorldModel', receiver, receive_point: Vector2D, if wm.self().pos().abs_x() > 40: candidate.eval += 30 + + if candidate.target_ball_pos.abs_x() <= 30 and candidate.target_ball_pos.x() > candidate.start_ball_pos.x(): + candidate.eval += 10 + if candidate.target_ball_pos.x() >= 40 and candidate.target_ball_pos.x() < candidate.start_ball_pos.x(): + candidate.eval += 30 """ if wm.game_mode() != GameModeType.PlayOn: From 6df7c4b4ce8cdff1ea04d5a13347cfd43345fe07 Mon Sep 17 00:00:00 2001 From: pilkiad Date: Tue, 21 Jan 2025 14:48:02 +0100 Subject: [PATCH 6/6] (change) Removed debug prints --- base/bhv_kick.py | 6 ------ base/generator_pass.py | 1 - lib/action/smart_kick.py | 5 ----- 3 files changed, 12 deletions(-) diff --git a/base/bhv_kick.py b/base/bhv_kick.py index b01331af..e98d73f3 100644 --- a/base/bhv_kick.py +++ b/base/bhv_kick.py @@ -31,7 +31,6 @@ def execute(self, agent: 'PlayerAgent'): 'shoot' + 'to ' + shoot_candidate.target_point.__str__() + ' ' + str(shoot_candidate.first_ball_speed)) SmartKick(shoot_candidate.target_point, shoot_candidate.first_ball_speed, shoot_candidate.first_ball_speed - 1, 3).execute(agent) - #agent.set_neck_action(NeckScanPlayers()) return True else: action_candidates: List[KickAction] = [] @@ -44,15 +43,12 @@ def execute(self, agent: 'PlayerAgent'): if len(action_candidates) == 0: return True - #return self.no_candidate_action(agent) best_action: KickAction = max(action_candidates) target = best_action.target_ball_pos log.debug_client().set_target(target) log.debug_client().add_message(best_action.type.value + 'to ' + best_action.target_ball_pos.__str__() + ' ' + str(best_action.start_ball_speed)) - print("SMORT KICKICK ") - print(best_action.type.value + 'to ' + best_action.target_ball_pos.__str__() + ' ' + str(best_action.start_ball_speed)) SmartKick(target, best_action.start_ball_speed, best_action.start_ball_speed - 1, 3).execute(agent) if best_action.type is KickActionType.Pass: @@ -61,7 +57,6 @@ def execute(self, agent: 'PlayerAgent'): agent.effector().queued_next_ball_pos(), agent.effector().queued_next_ball_vel())) - #agent.set_neck_action(NeckScanPlayers()) return True def no_candidate_action(self, agent: 'PlayerAgent'): @@ -76,5 +71,4 @@ def no_candidate_action(self, agent: 'PlayerAgent'): log.debug_client().add_message(best_action.type.value + 'to ' + best_action.target_ball_pos.__str__() + ' ' + str(best_action.start_ball_speed)) SmartKick(target, best_action.start_ball_speed, best_action.start_ball_speed - 2.0, 2).execute(agent) - #agent.set_neck_action(NeckScanPlayers()) return HoldBall().execute(agent) \ No newline at end of file diff --git a/base/generator_pass.py b/base/generator_pass.py index f9097e39..3997de84 100644 --- a/base/generator_pass.py +++ b/base/generator_pass.py @@ -135,7 +135,6 @@ def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'): start_step = max(max(min_receive_step, min_ball_step), 0) max_step = start_step + 30 log.sw_log().pass_().add_text( '#DPass to {} {}'.format(receiver.unum(), receiver.pos())) - print('#DPass to {} {}'.format(receiver.unum(), receiver.pos())) self.create_pass(wm, receiver, receive_point, start_step, max_step, min_ball_speed, max_ball_speed, min_receive_ball_speed, diff --git a/lib/action/smart_kick.py b/lib/action/smart_kick.py index ebc8ba2b..fe54cf52 100644 --- a/lib/action/smart_kick.py +++ b/lib/action/smart_kick.py @@ -45,13 +45,11 @@ def execute(self, agent: 'PlayerAgent'): if SmartKick.debug_print_DEBUG: log.os_log().info("----- NotKickable -----") log.sw_log().kick().add_text("not kickable") - print("quitting the kick non kickable") return False if not wm.ball().vel_valid(): if SmartKick.debug_print_DEBUG: log.os_log().info("-- NonValidBall -> StopBall --") log.sw_log().kick().add_text("unknown ball vel") - print("quitting the kick vel") return StopBall().execute(agent) first_speed = min(self._first_speed, ServerParam.i().ball_speed_max()) first_speed_thr = max(0.0, self._first_speed_thr) @@ -81,12 +79,9 @@ def execute(self, agent: 'PlayerAgent'): log.os_log().debug(f"----------------#### Player Number {wm.self().unum()} 'DO_KICK'ed in SmartKick at Time: {wm.time().cycle()} ####----------------") log.sw_log().kick().add_text(f"----------------#### Player Number {wm.self().unum()} 'DO_KICK'ed in SmartKick at Time: {wm.time().cycle()} ####----------------") return True - else: - print("HERE LIES THE ERROR") # failed to search the kick sequence log.sw_log().kick().add_text("----->>>>>Hold Ball") - print("failed the kick end") HoldBall(True, self._target_point, self._target_point).execute(agent) return False