1+ from src .interfaces .IBehavior import IBehavior
2+ from src .interfaces .IAgent import IAgent
3+ import math
4+ from service_pb2 import *
5+ from src .behaviors .starter_setplay .bhv_starter_setplay_kickoff import *
6+ from src .behaviors .starter_setplay .bhv_starter_their_goal_kick_move import *
7+ from src .behaviors .starter_setplay .bhv_starter_setplay_freekick import *
8+ from src .behaviors .starter_setplay .bhv_starter_setplay_goal_kick import *
9+ from src .behaviors .starter_setplay .bhv_starter_setplay_kickin import *
10+ from src .behaviors .starter_setplay .bhv_starter_setplay_indirect_freekick import *
11+ from pyrusgeom .vector_2d import Vector2D
12+ from pyrusgeom .segment_2d import Segment2D
13+ from pyrusgeom .circle_2d import Circle2D
14+ from src .utils .convertor import Convertor
15+ from src .strategy .starter_strategy import StarterStrategy
16+ class BhvStarterSetPlay (IBehavior ):
17+ def __init__ (self ):
18+ pass
19+
20+ def execute (self , agent : IAgent ):
21+ actions = BhvStarterSetPlay .decision (agent )
22+ for i in actions :
23+ if not i == None :
24+ agent .add_action (i )
25+
26+ def decision (agent : IAgent ):
27+ wm = agent .wm
28+ if wm .self .is_goalie :
29+ if wm .game_mode_type != GameModeType .BackPass_ and wm .game_mode_type != GameModeType .IndFreeKick_ :
30+ return [PlayerAction (bhv_goalie_free_kick = bhv_goalieFreeKick ())] #TODO
31+ #return BhvSetPlayGoalKick.execute(agent) #TODO GoalieFreeKick
32+ else :
33+ return BhvStarterSetPlayIndirectFreeKick .execute (agent )
34+ return []
35+
36+ if wm .game_mode_type == GameModeType .KickOff_ :
37+ if wm .game_mode_side == wm .our_side :
38+ return BhvStarterSetPlayKickOff .execute (agent )
39+ else :
40+ return BhvStarterSetPlay .doBasicTheirSetPlayMove (agent )
41+
42+
43+ if wm .game_mode_type in [GameModeType .KickIn_ , GameModeType .CornerKick_ ]:
44+ if wm .game_mode_side == wm .our_side :
45+ return BhvStarterSetPlayKickIn .execute (agent )
46+ else :
47+ return BhvStarterSetPlay .doBasicTheirSetPlayMove (agent )
48+
49+ if wm .game_mode_type == GameModeType .GoalKick_ :
50+ if wm .game_mode_side == wm .our_side :
51+ return BhvStarterSetPlayGoalKick .execute (agent )
52+ else :
53+ return BhvStarterTheirGoalKickMove .execute (agent )
54+
55+ if wm .game_mode_type in [GameModeType .BackPass_ , GameModeType .IndFreeKick_ ]:
56+ return BhvStarterSetPlayIndirectFreeKick .execute (agent )
57+
58+ if wm .game_mode_type in [GameModeType .FoulCharge_ , GameModeType .FoulPush_ ]:
59+ if (wm .ball .position .x < agent .server_params .our_penalty_area_line_x + 1.0 and abs (wm .ball .position .y ) < agent .server_params .penalty_area_half_width + 1.0 ):
60+ return BhvStarterSetPlayIndirectFreeKick .execute (agent )
61+ elif (wm .ball .position .x > agent .server_params .their_penalty_area_line_x - 1.0 and
62+ abs (wm .ball .position .y ) < agent .server_params .penalty_area_half_width + 1.0 ):
63+ return BhvStarterSetPlayIndirectFreeKick .execute (agent )
64+
65+ if wm .is_our_set_play :
66+ return BhvStarterSetPlayFreeKick .execute (agent )
67+ else :
68+ return BhvStarterSetPlay .doBasicTheirSetPlayMove (agent )
69+
70+
71+
72+ def get_set_play_dash_power (agent : IAgent ):
73+ wm = agent .wm
74+ if not wm .is_our_set_play :
75+ target_point = StarterStrategy .get_position (agent , wm .self .uniform_number )
76+ if target_point .x > wm .self .position .x :
77+ if (wm .ball .position .x < - 30.0 and
78+ target_point .x < wm .ball .position .x ):
79+ return wm .self .get_safety_dash_power
80+ rate = 0.0
81+ if wm .self .stamina > agent .server_params .stamina_max * 0.8 :
82+ rate = 1.5 * wm .self .stamina / agent .server_params .stamina_max
83+ else :
84+ rate = 0.9 * (wm .self .stamina - agent .server_params .recover_dec_thr ) / agent .server_params .stamina_max
85+ rate = max (0.0 , rate )
86+ return (agent .player_types [wm .self .id ].stamina_inc_max * wm .self .recovery * rate )
87+ return wm .self .get_safety_dash_power
88+
89+ def can_go_to (agent : IAgent , count , wm , ball_circle : Circle2D , target_point :Vector2D ) -> bool :
90+ wm = agent .wm
91+ self_position = Vector2D (wm .self .position .x , wm .self .position .y )
92+ move_line = Segment2D (self_position , target_point )
93+ n_intersection = ball_circle .intersection (move_line )
94+
95+ num = str (count )
96+
97+ if n_intersection == 0 :
98+ return True
99+
100+ if n_intersection == 1 :
101+ angle = Vector2D (target_point - self_position ).th ()
102+ if abs (angle - wm .ball .angle_from_self ) > 80.0 :
103+ return True
104+ return False
105+
106+ def get_avoid_circle_point (wm , target_point ,agent :IAgent ):
107+ SP = agent .server_params
108+ wm = agent .wm
109+ avoid_radius = SP .center_circle_r + agent .player_types [wm .self .id ].player_size
110+ ball_position = Vector2D (wm .ball .position .x , wm .ball .position .y )
111+ ball_circle = Circle2D (ball_position , avoid_radius )
112+ if BhvStarterSetPlay .can_go_to (agent ,- 1 , wm , ball_circle , target_point ):
113+ return target_point
114+ self_position = Vector2D (wm .self .position .x , wm .self .position .y )
115+ target_angle = Vector2D (target_point - self_position ).th ()
116+ ball_target_angle = Vector2D (target_point - ball_position ).th ()
117+ ball_ang = AngleDeg (wm .ball .angle_from_self )
118+ ball_is_left = ball_ang .is_left_of (target_angle )
119+ ANGLE_DIVS = 6
120+ subtargets = []
121+ angle_step = 1 if ball_is_left else - 1
122+ count = 0
123+ a = angle_step
124+ for i in range (1 , ANGLE_DIVS ):
125+ angle = ball_target_angle + (180.0 / ANGLE_DIVS ) * a
126+ new_target = Vector2D (ball_position + Vector2D .from_polar (avoid_radius + 1.0 , angle ))
127+
128+ if abs (new_target .x ()) > SP .pitch_half_length + SP .pitch_margin - 1.0 or abs (new_target .y ()) > SP .pitch_half_width + SP .pitch_margin - 1.0 : #TODO pith_margin
129+ break
130+ if BhvStarterSetPlay .can_go_to (agent , count , wm , ball_circle , new_target ):
131+ return new_target
132+ a += angle_step
133+ count += 1
134+ a = - angle_step
135+ for i in range (1 , ANGLE_DIVS * 2 ):
136+ angle = ball_target_angle + (180.0 / ANGLE_DIVS ) * a
137+ new_target = Vector2D (ball_position + Vector2D .from_polar (avoid_radius + 1.0 , angle ))
138+
139+ if abs (new_target .x ()) > SP .pitch_half_length + SP .pitch_margin - 1.0 or abs (new_target .y ()) > SP .pitch_half_width + SP .pitch_margin - 1.0 :
140+ break
141+ if BhvStarterSetPlay .can_go_to (agent , count , wm , ball_circle , new_target ):
142+ return new_target
143+ a -= angle_step
144+ count += 1
145+ return target_point
146+
147+ def is_kicker (agent : IAgent ):
148+ wm = agent .wm
149+ min_dist = 10000.0
150+ unum = 0
151+ ball_position = Vector2D (wm .ball .position .x , wm .ball .position .y )
152+ for i in range (1 , 12 ):
153+ if i == wm .our_goalie_uniform_number and wm .game_mode_type == GameModeType .GoalieCatch_ :
154+ h_p :RpcVector2D = wm .teammates [wm .our_goalie_uniform_number - 1 ].position
155+ elif i == wm .our_goalie_uniform_number :
156+ continue
157+ else :
158+ h_p :RpcVector2D = StarterStrategy .get_position (agent , i )
159+ home_pos = Vector2D (h_p .x , h_p .y )
160+ if (home_pos .dist (ball_position ) < min_dist ):
161+ min_dist = home_pos .dist (ball_position )
162+ unum = i
163+ if wm .self .uniform_number == unum :
164+ return True
165+ return False
166+ '''teammates_from_ball = Tools.TeammatesFromBall(agent)
167+ wm = agent.wm
168+ ball_position = Vector2D(wm.ball.position.x, wm.ball.position.y)
169+ if wm.game_mode_type == GameModeType.GoalieCatch_ and wm.game_mode_side == wm.our_side and not wm.self.is_goalie:
170+ return False
171+ kicker_unum = 0
172+ min_dist2 = 100000.0
173+ second_kicker_unum = 0
174+ second_min_dist2 = 100000.0
175+ for unum in range(1, 12):
176+ if unum == wm.our_goalie_uniform_number:
177+ continue
178+ h_p:RpcVector2D = Strategy.get_home_pos(agent, unum)
179+ home_pos = Vector2D(h_p.x, h_p.y)
180+ if not home_pos.is_valid():
181+ continue
182+ d2 = home_pos.dist2(ball_position)
183+ if d2 < second_min_dist2:
184+ second_kicker_unum = unum
185+ second_min_dist2 = d2
186+ if second_min_dist2 < min_dist2:
187+ second_kicker_unum, kicker_unum = kicker_unum, second_kicker_unum
188+ second_min_dist2, min_dist2 = min_dist2, second_min_dist2
189+
190+ kicker = None
191+ second_kicker = None
192+ if kicker_unum != 0:
193+ print ('unum', kicker_unum)
194+ kicker = wm.teammates[kicker_unum]
195+ if second_kicker_unum != 0:
196+ second_kicker = wm.teammates[second_kicker_unum]
197+ if not kicker:
198+ if teammates_from_ball and teammates_from_ball[0].dist_from_ball < wm.ball.dist_from_self * 0.9:
199+ return False
200+
201+ return True
202+ print('kicker unum: ', kicker.uniform_number)
203+ print('second is_kicker', second_kicker.uniform_number)
204+ if kicker and second_kicker and (kicker.uniform_number == wm.self.uniform_number or second_kicker.uniform_number == wm.self.uniform_number):
205+ if math.sqrt(min_dist2) < math.sqrt(second_min_dist2) * 0.95:
206+ return kicker.uniform_number == wm.self.uniform_number
207+ elif kicker.dist_from_ball < second_kicker.dist_from_ball * 0.95:
208+ return kicker.uniform_number == wm.self.uniform_number
209+ elif second_kicker.dist_from_ball < kicker.dist_from_ball * 0.95:
210+ return second_kicker.uniform_number == wm.self.uniform_number
211+
212+ elif teammates_from_ball and teammates_from_ball[0].dist_from_ball < wm.self.dist_from_ball * 0.95:
213+ return False
214+ else:
215+ return True
216+ return kicker.uniform_number == wm.self.uniform_number'''
217+
218+ def is_delaying_tactics_situation (agent : IAgent ):
219+ wm = agent .wm
220+ real_set_play_count = wm .cycle - wm .last_set_play_start_time
221+ wait_buf = 15 if wm .game_mode_type == GameModeType .GoalKick_ else 2
222+ if real_set_play_count >= agent .server_params .drop_ball_time - wait_buf :
223+ return False
224+ our_score = wm .left_team_score if wm .our_side == Side .LEFT else wm .right_team_score
225+ opp_score = wm .right_team_score if wm .our_side == Side .LEFT else wm .left_team_score
226+ '''if wm.audioMemory().recoveryTime().cycle >= wm.cycle - 10:
227+ if our_score > opp_score:
228+ return True''' #TODO audio memory
229+ cycle_thr = max (0 , agent .server_params .nr_normal_halfs * (agent .server_params .half_time * 10 ) - 500 )
230+ if wm .cycle < cycle_thr :
231+ return False
232+ if our_score > opp_score and our_score - opp_score <= 1 :
233+ return True
234+ return False
235+
236+ def doBasicTheirSetPlayMove (agent : IAgent ):
237+ wm = agent .wm
238+ target = StarterStrategy .get_position (agent , wm .self .uniform_number )
239+ target_point = Vector2D (target .x , target .y )
240+ ball_position = Vector2D (wm .ball .position .x , wm .ball .position .y )
241+ dash_power = BhvStarterSetPlay .get_set_play_dash_power (agent )
242+ ball_to_target = Vector2D (target_point - ball_position )
243+ if ball_to_target .r () < 11.0 :
244+ xdiff = math .sqrt (math .pow (11.0 , 2 ) - math .pow (ball_to_target .y (), 2 ))
245+ target_point .set_x (wm .ball .position .x - xdiff )
246+ if target_point .x () < - 45.0 :
247+ target_point = ball_position
248+ target_point += ball_to_target .set_length_vector (11.0 )
249+
250+ if wm .game_mode_type == GameModeType .KickOff_ and agent .server_params .kickoff_offside :
251+ target_point .set_x (min (- 1.0e-5 , target_point .x ()))
252+
253+ adjusted_point = BhvStarterSetPlay .get_avoid_circle_point (wm , target_point ,agent )
254+ dist_thr = wm .ball .dist_from_self * 0.1
255+ if dist_thr < 0.7 :
256+ dist_thr = 0.7
257+ self_velocity = Vector2D (wm .self .velocity .x , wm .self .velocity .y )
258+ self_position = Vector2D (wm .self .position .x , wm .self .position .y )
259+ if adjusted_point != target_point and ball_position .dist (target_point ) > 10.0 and Tools .inertia_final_point (agent .player_types [wm .self .id ], self_position , self_velocity ).dist (adjusted_point ) < dist_thr :
260+ adjusted_point = target_point
261+ actions = []
262+ actions .append (PlayerAction (body_go_to_point = Body_GoToPoint (target_point = Convertor .convert_vector2d_to_rpc_vector2d (adjusted_point ), distance_threshold = dist_thr , max_dash_power = dash_power )))
263+ body_angle = wm .ball .angle_from_self
264+ if body_angle < 0.0 :
265+ body_angle -= 90.0
266+ else :
267+ body_angle += 90.0
268+ actions .append (PlayerAction (body_turn_to_angle = Body_TurnToAngle (angle = body_angle )))
269+ return actions
0 commit comments