1
1
use std:: time:: SystemTime ;
2
2
3
3
use color_eyre:: Result ;
4
- use itertools:: Itertools ;
5
4
use serde:: { Deserialize , Serialize } ;
6
5
7
6
use context_attribute:: context;
@@ -12,7 +11,7 @@ use spl_network_messages::{GamePhase, PlayerNumber, SubState, Team};
12
11
use types:: {
13
12
action:: Action ,
14
13
cycle_time:: CycleTime ,
15
- field_dimensions:: { FieldDimensions , Side } ,
14
+ field_dimensions:: { FieldDimensions , GlobalFieldSide , Side } ,
16
15
filtered_game_controller_state:: FilteredGameControllerState ,
17
16
filtered_game_state:: FilteredGameState ,
18
17
motion_command:: { MotionCommand , OrientationMode , WalkSpeed } ,
@@ -156,46 +155,42 @@ impl Behavior {
156
155
actions. push ( Action :: InterceptBall ) ;
157
156
158
157
match world_state. robot . role {
158
+ Role :: DefenderLeft
159
+ if world_state
160
+ . filtered_game_controller_state
161
+ . clone ( )
162
+ . is_some_and ( |filtered_game_controller_state| {
163
+ is_free_kick ( filtered_game_controller_state, world_state. clone ( ) )
164
+ } ) =>
165
+ {
166
+ actions. push ( Action :: LookAtReferee ) ;
167
+ actions. push ( Action :: DefendLeft ) ;
168
+ }
159
169
Role :: DefenderLeft => match world_state. filtered_game_controller_state {
160
170
Some ( FilteredGameControllerState {
161
171
sub_state : Some ( SubState :: CornerKick ) ,
162
172
kicking_team : Team :: Opponent ,
163
173
..
164
174
} ) => actions. push ( Action :: DefendOpponentCornerKick { side : Side :: Left } ) ,
165
- Some ( FilteredGameControllerState {
166
- sub_state : Some ( SubState :: KickIn ) | Some ( SubState :: PushingFreeKick ) ,
167
- game_state :
168
- FilteredGameState :: Playing {
169
- ball_is_free : false ,
170
- ..
171
- } ,
172
- own_team_is_home_after_coin_toss : false ,
173
- ..
174
- } ) => {
175
- actions. push ( Action :: LookAtReferee ) ;
176
- actions. push ( Action :: DefendLeft ) ;
177
- }
178
175
_ => actions. push ( Action :: DefendLeft ) ,
179
176
} ,
177
+ Role :: DefenderRight
178
+ if world_state
179
+ . filtered_game_controller_state
180
+ . clone ( )
181
+ . is_some_and ( |filtered_game_controller_state| {
182
+ is_free_kick ( filtered_game_controller_state, world_state. clone ( ) )
183
+ } ) =>
184
+ {
185
+ actions. push ( Action :: LookAtReferee ) ;
186
+ actions. push ( Action :: DefendRight ) ;
187
+ }
180
188
Role :: DefenderRight => match world_state. filtered_game_controller_state {
181
189
Some ( FilteredGameControllerState {
182
190
sub_state : Some ( SubState :: CornerKick ) ,
183
191
kicking_team : Team :: Opponent ,
184
192
..
185
193
} ) => actions. push ( Action :: DefendOpponentCornerKick { side : Side :: Right } ) ,
186
- Some ( FilteredGameControllerState {
187
- sub_state : Some ( SubState :: KickIn ) | Some ( SubState :: PushingFreeKick ) ,
188
- game_state :
189
- FilteredGameState :: Playing {
190
- ball_is_free : false ,
191
- ..
192
- } ,
193
- own_team_is_home_after_coin_toss : true ,
194
- ..
195
- } ) => {
196
- actions. push ( Action :: LookAtReferee ) ;
197
- actions. push ( Action :: DefendRight ) ;
198
- }
199
194
_ => actions. push ( Action :: DefendRight ) ,
200
195
} ,
201
196
Role :: Keeper => match world_state. filtered_game_controller_state {
@@ -215,64 +210,43 @@ impl Behavior {
215
210
_ => actions. push ( Action :: DefendGoal ) ,
216
211
} ,
217
212
Role :: Loser => actions. push ( Action :: SearchForLostBall ) ,
218
- Role :: MidfielderLeft => match world_state. filtered_game_controller_state {
219
- Some ( FilteredGameControllerState {
220
- sub_state : Some ( SubState :: KickIn ) | Some ( SubState :: PushingFreeKick ) ,
221
- game_state :
222
- FilteredGameState :: Playing {
223
- ball_is_free : false ,
224
- ..
225
- } ,
226
- own_team_is_home_after_coin_toss : false ,
227
- ..
228
- } ) => {
229
- actions. push ( Action :: LookAtReferee ) ;
230
- actions. push ( Action :: SupportLeft ) ;
231
- }
232
- _ => actions. push ( Action :: SupportLeft ) ,
233
- } ,
234
- Role :: MidfielderRight => match world_state. filtered_game_controller_state {
235
- Some ( FilteredGameControllerState {
236
- sub_state : Some ( SubState :: KickIn ) | Some ( SubState :: PushingFreeKick ) ,
237
- game_state :
238
- FilteredGameState :: Playing {
239
- ball_is_free : false ,
240
- ..
241
- } ,
242
- own_team_is_home_after_coin_toss : true ,
243
- ..
244
- } ) => {
245
- actions. push ( Action :: LookAtReferee ) ;
246
- actions. push ( Action :: SupportRight ) ;
247
- }
248
- _ => actions. push ( Action :: SupportRight ) ,
249
- } ,
213
+ Role :: MidfielderLeft
214
+ if world_state
215
+ . filtered_game_controller_state
216
+ . clone ( )
217
+ . is_some_and ( |filtered_game_controller_state| {
218
+ is_free_kick ( filtered_game_controller_state, world_state. clone ( ) )
219
+ } ) =>
220
+ {
221
+ actions. push ( Action :: LookAtReferee ) ;
222
+ actions. push ( Action :: SupportLeft ) ;
223
+ }
224
+ Role :: MidfielderLeft => actions. push ( Action :: SupportLeft ) ,
225
+ Role :: MidfielderRight
226
+ if world_state
227
+ . filtered_game_controller_state
228
+ . clone ( )
229
+ . is_some_and ( |filtered_game_controller_state| {
230
+ is_free_kick ( filtered_game_controller_state, world_state. clone ( ) )
231
+ } ) =>
232
+ {
233
+ actions. push ( Action :: LookAtReferee ) ;
234
+ actions. push ( Action :: SupportRight ) ;
235
+ }
236
+ Role :: MidfielderRight => actions. push ( Action :: SupportRight ) ,
250
237
Role :: ReplacementKeeper => actions. push ( Action :: DefendGoal ) ,
251
- Role :: Searcher => match world_state. filtered_game_controller_state {
252
- Some ( FilteredGameControllerState {
253
- sub_state : Some ( SubState :: KickIn ) | Some ( SubState :: PushingFreeKick ) ,
254
- penalties,
255
- ..
256
- } ) => {
257
- let mut first_two_nonpenalized_nonkeeper_player_numbers = penalties
258
- . iter ( )
259
- . filter_map ( |( player_number, penalty) | {
260
- penalty. is_none ( ) . then_some ( player_number)
261
- } )
262
- // Skip the lowest non-penalized player number since this is always the Keeper or ReplacementKeeper
263
- . skip ( 1 )
264
- . take ( 2 ) ;
265
- if first_two_nonpenalized_nonkeeper_player_numbers
266
- . contains ( & world_state. robot . player_number )
267
- {
268
- actions. push ( Action :: LookAtReferee ) ;
269
- actions. push ( Action :: Search ) ;
270
- } else {
271
- actions. push ( Action :: Search ) ;
272
- }
273
- }
274
- _ => actions. push ( Action :: Search ) ,
275
- } ,
238
+ Role :: Searcher
239
+ if world_state
240
+ . filtered_game_controller_state
241
+ . clone ( )
242
+ . is_some_and ( |filtered_game_controller_state| {
243
+ is_free_kick ( filtered_game_controller_state, world_state. clone ( ) )
244
+ } ) =>
245
+ {
246
+ actions. push ( Action :: LookAtReferee ) ;
247
+ actions. push ( Action :: Search ) ;
248
+ }
249
+ Role :: Searcher => actions. push ( Action :: Search ) ,
276
250
Role :: Striker => match world_state. filtered_game_controller_state {
277
251
None
278
252
| Some ( FilteredGameControllerState {
@@ -565,3 +539,47 @@ impl Behavior {
565
539
} )
566
540
}
567
541
}
542
+
543
+ pub fn is_free_kick (
544
+ filtered_game_controller_state : FilteredGameControllerState ,
545
+ world_state : WorldState ,
546
+ ) -> bool {
547
+ let is_free_kick_filtered_game_controller_state = matches ! (
548
+ filtered_game_controller_state,
549
+ FilteredGameControllerState {
550
+ sub_state: Some ( SubState :: KickIn ) | Some ( SubState :: PushingFreeKick ) ,
551
+ game_state: FilteredGameState :: Playing {
552
+ ball_is_free: false ,
553
+ ..
554
+ } ,
555
+ ..
556
+ }
557
+ ) ;
558
+
559
+ let first_two_nonpenalized_nonkeeper_player_numbers: Vec < PlayerNumber > =
560
+ filtered_game_controller_state
561
+ . penalties
562
+ . iter ( )
563
+ . filter_map ( |( player_number, penalty) | penalty. is_none ( ) . then_some ( player_number) )
564
+ // Skip the lowest non-penalized player number since this is always the Keeper or ReplacementKeeper
565
+ . skip ( 1 )
566
+ . take ( 2 )
567
+ . collect ( ) ;
568
+
569
+ let is_correct_free_kick_role = match (
570
+ world_state. robot . role ,
571
+ filtered_game_controller_state. global_field_side ,
572
+ ) {
573
+ ( Role :: DefenderRight | Role :: MidfielderRight , GlobalFieldSide :: Home ) => true ,
574
+ ( Role :: DefenderLeft | Role :: MidfielderLeft , GlobalFieldSide :: Away ) => true ,
575
+ ( Role :: Searcher , _)
576
+ if first_two_nonpenalized_nonkeeper_player_numbers
577
+ . contains ( & world_state. robot . player_number ) =>
578
+ {
579
+ true
580
+ }
581
+ _ => false ,
582
+ } ;
583
+
584
+ is_free_kick_filtered_game_controller_state && is_correct_free_kick_role
585
+ }
0 commit comments