|
2 | 2 |
|
3 | 3 | #include "software/ai/evaluation/defender_assignment.h" |
4 | 4 | #include "software/ai/evaluation/enemy_threat.h" |
| 5 | +#include "software/logger/logger.h" |
| 6 | + |
5 | 7 |
|
6 | 8 | DefensePlayFSM::DefensePlayFSM(TbotsProto::AiConfig ai_config) |
7 | 9 | : DefensePlayFSMBase::DefensePlayFSMBase(ai_config) |
8 | 10 | { |
9 | 11 | } |
10 | 12 |
|
11 | | -void DefensePlayFSM::defendAgainstThreats(const Update& event) |
| 13 | +bool DefensePlayFSM::shouldDefendAggressively(const Update& event) |
| 14 | +{ |
| 15 | + // If there is more attackers ahead of the ball than there |
| 16 | + // are our own defenders we won't press |
| 17 | + |
| 18 | + auto attackers = std::count_if( |
| 19 | + event.common.world_ptr->enemyTeam().getAllRobots().begin(), |
| 20 | + event.common.world_ptr->enemyTeam().getAllRobots().end(), |
| 21 | + [event](const Robot& robot) |
| 22 | + { return robot.position().x() < event.common.world_ptr->ball().position().x(); }); |
| 23 | + |
| 24 | + auto defenders = std::count_if( |
| 25 | + event.common.world_ptr->friendlyTeam().getAllRobots().begin(), |
| 26 | + event.common.world_ptr->friendlyTeam().getAllRobots().end(), |
| 27 | + [event](const Robot& robot) |
| 28 | + { return robot.position().x() < event.common.world_ptr->ball().position().x(); }); |
| 29 | + |
| 30 | + return defenders > attackers; |
| 31 | +} |
| 32 | + |
| 33 | +void DefensePlayFSM::blockShots(const Update& event) |
12 | 34 | { |
13 | 35 | auto enemy_threats = getAllEnemyThreats( |
14 | 36 | event.common.world_ptr->field(), event.common.world_ptr->friendlyTeam(), |
15 | 37 | event.common.world_ptr->enemyTeam(), event.common.world_ptr->ball(), false); |
16 | 38 |
|
| 39 | + updateCreaseAndPassDefenders(event, enemy_threats); |
| 40 | + updateShadowers(event, {}); |
| 41 | + |
| 42 | + setTactics(event); |
| 43 | +} |
| 44 | + |
| 45 | +void DefensePlayFSM::shadowAndBlockShots(const Update& event) |
| 46 | +{ |
| 47 | + auto enemy_threats = getAllEnemyThreats( |
| 48 | + event.common.world_ptr->field(), event.common.world_ptr->friendlyTeam(), |
| 49 | + event.common.world_ptr->enemyTeam(), event.common.world_ptr->ball(), false); |
| 50 | + |
| 51 | + updateCreaseAndPassDefenders(event, enemy_threats); |
| 52 | + |
| 53 | + if (pass_defenders.size() > 0) |
| 54 | + { |
| 55 | + pass_defenders.erase(pass_defenders.begin()); |
| 56 | + updateShadowers(event, {enemy_threats.front()}); |
| 57 | + } |
| 58 | + |
| 59 | + setTactics(event); |
| 60 | +} |
| 61 | + |
| 62 | +void DefensePlayFSM::updateCreaseAndPassDefenders( |
| 63 | + const Update& event, const std::vector<EnemyThreat>& enemy_threats) |
| 64 | +{ |
17 | 65 | auto defender_assignment_config = |
18 | 66 | ai_config.defense_play_config().defender_assignment_config(); |
19 | 67 | auto assignments = getAllDefenderAssignments( |
20 | 68 | enemy_threats, event.common.world_ptr->field(), event.common.world_ptr->ball(), |
21 | 69 | defender_assignment_config); |
22 | | - |
23 | 70 | if (assignments.size() == 0) |
24 | 71 | { |
25 | 72 | return; |
@@ -75,11 +122,43 @@ void DefensePlayFSM::defendAgainstThreats(const Update& event) |
75 | 122 | setAlignment(event, crease_defender_assignments, TbotsProto::BallStealMode::STEAL); |
76 | 123 | updatePassDefenderControlParams(pass_defender_assignments, |
77 | 124 | TbotsProto::BallStealMode::STEAL); |
| 125 | +} |
| 126 | + |
| 127 | +void DefensePlayFSM::updateShadowers(const Update& event, |
| 128 | + const std::vector<EnemyThreat>& threats_to_shadow) |
| 129 | +{ |
| 130 | + setUpShadowers(static_cast<unsigned int>(threats_to_shadow.size())); |
| 131 | + |
| 132 | + for (unsigned int i = 0; i < shadowers.size(); i++) |
| 133 | + { |
| 134 | + shadowers.at(i)->updateControlParams(threats_to_shadow.at(i), |
| 135 | + ROBOT_SHADOWING_DISTANCE_METERS); |
| 136 | + } |
| 137 | +} |
| 138 | + |
| 139 | + |
| 140 | +void DefensePlayFSM::setUpShadowers(int num_shadowers) |
| 141 | +{ |
| 142 | + if (num_shadowers == static_cast<int>(shadowers.size())) |
| 143 | + { |
| 144 | + return; |
| 145 | + } |
| 146 | + |
| 147 | + shadowers = std::vector<std::shared_ptr<ShadowEnemyTactic>>(num_shadowers); |
| 148 | + std::generate(shadowers.begin(), shadowers.end(), |
| 149 | + [this]() { return std::make_shared<ShadowEnemyTactic>(); }); |
| 150 | +} |
| 151 | + |
| 152 | +void DefensePlayFSM::setTactics(const Update& event) |
| 153 | +{ |
| 154 | + PriorityTacticVector tactics_to_return = {{}, {}, {}}; |
78 | 155 |
|
79 | | - PriorityTacticVector tactics_to_return = {{}, {}}; |
80 | 156 | tactics_to_return[0].insert(tactics_to_return[0].end(), crease_defenders.begin(), |
81 | 157 | crease_defenders.end()); |
82 | 158 | tactics_to_return[1].insert(tactics_to_return[1].end(), pass_defenders.begin(), |
83 | 159 | pass_defenders.end()); |
| 160 | + tactics_to_return[2].insert(tactics_to_return[2].end(), shadowers.begin(), |
| 161 | + shadowers.end()); |
| 162 | + |
84 | 163 | event.common.set_tactics(tactics_to_return); |
85 | 164 | } |
0 commit comments