Skip to content

Commit 6fbfb8d

Browse files
committed
Dequadruplicate free kick behavior
1 parent 5a3c7cf commit 6fbfb8d

File tree

2 files changed

+103
-86
lines changed

2 files changed

+103
-86
lines changed

crates/control/src/behavior/node.rs

+103-85
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::time::SystemTime;
22

33
use color_eyre::Result;
4-
use itertools::Itertools;
54
use serde::{Deserialize, Serialize};
65

76
use context_attribute::context;
@@ -12,7 +11,7 @@ use spl_network_messages::{GamePhase, PlayerNumber, SubState, Team};
1211
use types::{
1312
action::Action,
1413
cycle_time::CycleTime,
15-
field_dimensions::{FieldDimensions, Side},
14+
field_dimensions::{FieldDimensions, GlobalFieldSide, Side},
1615
filtered_game_controller_state::FilteredGameControllerState,
1716
filtered_game_state::FilteredGameState,
1817
motion_command::{MotionCommand, OrientationMode, WalkSpeed},
@@ -156,46 +155,42 @@ impl Behavior {
156155
actions.push(Action::InterceptBall);
157156

158157
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+
}
159169
Role::DefenderLeft => match world_state.filtered_game_controller_state {
160170
Some(FilteredGameControllerState {
161171
sub_state: Some(SubState::CornerKick),
162172
kicking_team: Team::Opponent,
163173
..
164174
}) => 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-
}
178175
_ => actions.push(Action::DefendLeft),
179176
},
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+
}
180188
Role::DefenderRight => match world_state.filtered_game_controller_state {
181189
Some(FilteredGameControllerState {
182190
sub_state: Some(SubState::CornerKick),
183191
kicking_team: Team::Opponent,
184192
..
185193
}) => 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-
}
199194
_ => actions.push(Action::DefendRight),
200195
},
201196
Role::Keeper => match world_state.filtered_game_controller_state {
@@ -215,64 +210,43 @@ impl Behavior {
215210
_ => actions.push(Action::DefendGoal),
216211
},
217212
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),
250237
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),
276250
Role::Striker => match world_state.filtered_game_controller_state {
277251
None
278252
| Some(FilteredGameControllerState {
@@ -565,3 +539,47 @@ impl Behavior {
565539
})
566540
}
567541
}
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+
}

crates/types/src/filtered_game_controller_state.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use spl_network_messages::{GamePhase, Penalty, PlayerNumber, SubState, Team};
66

77
use crate::{
88
field_dimensions::GlobalFieldSide, filtered_game_state::FilteredGameState, players::Players,
9-
roles::Role, world_state::WorldState,
109
};
1110

1211
#[derive(Clone, Debug, Serialize, Deserialize, PathSerialize, PathIntrospect, PartialEq)]

0 commit comments

Comments
 (0)