1-
21from src .interfaces .IAgent import IAgent
32from src .utils .convertor import Convertor
43from pyrusgeom .geom_2d import *
87
98
109class BhvStarterTackle (IBehavior ):
11- def __init__ (self ):
12- pass
10+ def __init__ (self , min_prob : float , body_thr : float ):
11+ self .min_prob = min_prob
12+ self .body_thr = body_thr
1313
1414 def execute (self , agent : IAgent ) -> bool :
1515 agent .logger .debug ("BhvStarterTackle.execute" )
1616 from src .sample_player_agent import SamplePlayerAgent # Local import to avoid circular import
1717 assert isinstance (agent , SamplePlayerAgent )
18- raise NotImplementedError ("BhvStarterTackle.execute not implemented" )
18+ wm = agent .wm
19+ use_foul = False
20+ tackle_prob = wm .self .tackle_probability
21+ if wm .self .card == CardType .NO_CARD and (wm .ball .position .x > agent .server_params .our_penalty_area_line_x + 0.5 or abs (wm .ball .position .y ) > agent .server_params .penalty_area_half_width + 0.5 ) and tackle_prob < wm .self .foul_probability :
22+ tackle_prob = wm .self .foul_probability
23+ use_foul = True
24+
25+ if tackle_prob < self .min_prob :
26+ return
27+
28+ self_min = wm .intercept_table .self_reach_steps
29+ mate_min = wm .intercept_table .first_teammate_reach_steps
30+ opp_min = wm .intercept_table .first_opponent_reach_steps
31+
32+ self_pos = Convertor .convert_rpc_vector2d_to_vector2d (wm .self .position )
33+ ball_pos = Convertor .convert_rpc_vector2d_to_vector2d (wm .ball .position )
34+ ball_velocity = Convertor .convert_rpc_vector2d_to_vector2d (wm .ball .velocity )
35+
36+ self_reach_point = inertia_n_step_point (ball_pos , ball_velocity , self_min , agent .server_params .ball_decay )
37+
38+ ball_will_be_in_our_goal = False
39+
40+ if self_reach_point .x () < - agent .server_params .pitch_half_length :
41+
42+ ball_ray = Ray2D (ball_pos , ball_velocity .th ())
43+ goal_line = Line2D (Vector2D (- agent .server_params .pitch_half_length , 10.0 ), Vector2D (- agent .server_params .pitch_half_length , - 10.0 ))
44+
45+ intersect = ball_ray .intersection (goal_line )
46+
47+ if intersect .is_valid () and intersect .abs_y () < (agent .server_params .goal_width / 2 ) + 1 :
48+ ball_will_be_in_our_goal = True
49+
50+ if opp_min < 2 or ball_will_be_in_our_goal or (opp_min < self_min - 3 and opp_min < mate_min - 3 ) or (self_min >= 5 and ball_pos .dist2 (Vector2D (agent .server_params .pitch_half_length , 0 )) < 100 ) and ((Vector2D (agent .server_params .pitch_half_length , 0 ) - self_pos ).th () - wm .self .body_direction ).abs () < 45 :
51+ # Try tackle
52+ pass
53+ else :
54+ return
55+
56+ BhvStarterTackle .ExecuteOldVersion (self , agent , use_foul )
57+
58+
59+ def ExecuteOldVersion (self , agent : IAgent , use_foul : bool ):
60+
61+ wm = agent .wm
62+ tackle_power = agent .server_params .max_tackle_power
63+
64+ if abs (wm .self .body_direction ) < self .body_thr :
65+ agent .add_action (PlayerAction (tackle = Tackle (power_or_dir = tackle_power , foul = use_foul )))
66+
67+ tackle_power = - agent .server_params .max_back_tackle_power
68+
69+ if tackle_power < 0.0 and abs (wm .self .body_direction ) > 180 - self .body_thr :
70+ agent .add_action (PlayerAction (tackle = Tackle (power_or_dir = tackle_power , foul = False )))
71+
72+ return
73+
74+ def ExecuteV12 (self , agent : IAgent , use_foul : bool ):
75+
76+ s_last_execute_time = agent .wm .cycle
77+ s_result = False
78+ s_best_angle = AngleDeg (0 ,0 )
79+
80+ wm = agent .wm
81+
82+ if s_last_execute_time == wm .time ():
83+ agent .add_log_text (LoggerLevel .TEAM , f": called several times" )
84+ if s_result :
85+ agent .add_log_text (LoggerLevel .TEAM , f"{ __file__ } : executeV12() tackle angle={ s_best_angle .degree ()} " )
86+ agent .add_log_message (LoggerLevel .TEAM ,f"BasicTackle{ s_best_angle .degree ()} " , agent .wm .self .position .x , agent .wm .self .position .y - 2 , '\033 [31m' )
87+
88+ tackle_dir = (s_best_angle - wm .self .body_direction ).degree ()
89+ agent .add_action (PlayerAction (tackle = Tackle (power_or_dir = tackle_dir , foul = use_foul )))
90+
91+ s_last_execute_time = wm .cycle
92+ s_result = False
93+
94+ SP = agent .server_params
95+
96+ opp_goal = Vector2D (SP .pitch_half_length , 0.0 )
97+ our_goal = Vector2D (- SP .pitch_half_length , 0.0 )
98+ kickable_opponent = True
99+ if wm .intercept_table .first_opponent_reach_steps > 1 :
100+ kickable_opponent = False
101+ virtual_accel = (kickable_opponent and Vector2D (our_goal - wm .ball .position ).set_length (0.5 ) or Vector2D (0.0 , 0.0 ))
102+ shoot_chance = (wm .ball .position .dist (opp_goal ) < 20.0 )
103+
104+ ball_rel_angle = wm .ball .angleFromSelf () - wm .self .body_direction
105+ tackle_rate = SP .tackle_power_rate * (1.0 - 0.5 * abs (ball_rel_angle ) / 180.0 )
106+
107+ best_angle = AngleDeg (0.0 )
108+ max_speed = - 1.0
109+
110+ for a in range (- 180.0 , 180.0 , 10.0 ):
111+ rel_angle = AngleDeg (a - wm .self .body_direction )
112+
113+ eff_power = SP .max_tackle_power + ((SP .max_tackle_power - SP .max_back_tackle_power ) * (1.0 - rel_angle .abs () / 180.0 ))
114+ eff_power *= tackle_rate
115+
116+ vel = Vector2D (wm .ball .velocity + Vector2D .polar2vector (eff_power , AngleDeg (a )))
117+ vel += virtual_accel
118+
119+ speed = vel .r ()
120+ if speed > SP .ball_speed_max :
121+ vel *= (SP .ball_speed_max / speed )
122+ speed = SP .ball_speed_max
123+
124+ if abs (vel .th ()) > 90.0 :
125+ continue
126+
127+ ball_next = wm .ball .position + vel
128+
129+ maybe_opponent_get_ball = False
130+
131+ for o in wm .opponents :
132+ if o .pos_count > 10 :
133+ continue
134+ if o .ghost_count > 0 :
135+ continue
136+ if o .is_tackling :
137+ continue
138+ if o .dist_from_ball > 6.0 :
139+ break
140+
141+ opp_pos = Vector2D (o .position + o .velocity )
142+ if opp_pos .dist (ball_next ) < SP .kickable_area + 0.1 :
143+ maybe_opponent_get_ball = True
144+ break
145+
146+ if maybe_opponent_get_ball :
147+ continue
148+
149+ if shoot_chance :
150+ ball_ray = Ray2D (wm .ball .position , vel .th ())
151+ goal_line = Line2D (Vector2D (SP .pitch_half_length , 10.0 ), Vector2D (SP .pitch_half_length , - 10.0 ))
152+ intersect = Vector2D (ball_ray .intersection (goal_line ))
153+ if intersect ._is_valid and intersect .abs_y () < (SP .goal_width / 2.0 ) - 3.0 :
154+ speed += 10.0
155+
156+ if speed > max_speed :
157+ max_speed = speed
158+ best_angle = AngleDeg (a )
159+
160+ if max_speed < 0.0 :
161+ s_result = False
162+ agent .add_log_text (LoggerLevel .TEAM , f"{ __file__ } : failed executeV12. max_speed={ max_speed } " )
163+ return False
164+
165+ s_result = True
166+ s_best_angle = best_angle
167+
168+ agent .add_log_text (LoggerLevel .TEAM , f"{ __file__ } : executeV12() angle={ best_angle .degree ()} " )
169+ agent .add_log_message (LoggerLevel .TEAM ,f"BasicTackle{ best_angle .degree ()} " , agent .wm .self .position .x , agent .wm .self .position .y - 2 , '\033 [31m' )
170+
171+ tackle_dir = (best_angle - wm .self .body_direction ).degree ()
172+ agent .add_action (PlayerAction (tackle = Tackle (power_or_dir = tackle_dir , foul = use_foul )))
173+
174+
175+
176+
0 commit comments