ProtoBot
Loading...
Searching...
No Matches
Squad Class Reference

The Squad class represents a group of combat units owned by ProtoBot. More...

#include <Squad.h>

Public Member Functions

 Squad (BWAPI::Unit leader, int squadId, BWAPI::Color squadColor)
void onFrame ()
void setState (SquadState &newState)
void removeUnit (BWAPI::Unit unit)
void addUnit (BWAPI::Unit unit)
void addObserver (BWAPI::Unit observer)
void observerOnFrame ()
 Defines the behavior of the observer unit in the squad.
void drawSquadBox ()
void drawDebugInfo ()
bool operator== (const Squad &other) noexcept(true)
bool operator!= (const Squad &other) noexcept(true)

Public Attributes

BWAPI::Unit leader = nullptr
BWAPI::Unit observer = nullptr
SquadInfo info

Detailed Description

The Squad class represents a group of combat units owned by ProtoBot.

Base squad structure that holds its leader, observer, as well as its methods.
Information is stored inside of a SquadInfo class.



Every squad has a leader and methods for adding and removing units.
Squad behavior is defined by its state and onFrame(), which calls the current state's Update() method.

Definition at line 56 of file Squad.h.

Constructor & Destructor Documentation

◆ Squad()

Squad::Squad ( BWAPI::Unit leader,
int squadId,
BWAPI::Color squadColor )

Definition at line 4 of file Squad.cpp.

5{
6 this->leader = leader;
7 this->info.squadId = squadId;
8 this->info.squadColor = squadColor;
9}

Member Function Documentation

◆ addObserver()

void Squad::addObserver ( BWAPI::Unit observer)

Definition at line 101 of file Squad.cpp.

101 {
102 if (unreservedObserver == nullptr) {
103 return;
104 }
105
106 observer = unreservedObserver;
107}

◆ addUnit()

void Squad::addUnit ( BWAPI::Unit unit)

Definition at line 74 of file Squad.cpp.

74 {
75 if (unit == nullptr) {
76 return;
77 }
78
79 if (std::find(info.units.begin(), info.units.end(), unit) != info.units.end()) {
80 // Avoids adding duplicate units
81 return;
82 }
83
84 info.units.push_back(unit);
85
86 // Unit should do whatever the squad is currently doing
87 if (info.currentState == &DefendingState::getInstance()) {
88 unit->attack(info.currentDefensivePosition);
89 }
90 if (info.currentState == &ReinforcingState::getInstance()) {
91 unit->attack(info.currentReinforcePosition);
92 }
93 if (info.currentState == &AttackingState::getInstance()) {
94 unit->attack(info.currentAttackPosition);
95 }
96#ifdef DEBUG_SQUAD
97 BWAPI::Broodwar->printf("Unit %d added to Squad %d", unit->getID(), squadId);
98#endif
99}

◆ drawDebugInfo()

void Squad::drawDebugInfo ( )

Definition at line 158 of file Squad.cpp.

158 {
159 for (auto& unit : info.units) {
160 if (!unit || !unit->exists()) {
161 continue;
162 }
163
164 // Draw lines and shapes to debug commands
165 const BWAPI::UnitCommand command = unit->getLastCommand();
166
167 BWAPI::Broodwar->drawCircleMap(unit->getPosition(), 5, info.squadColor, true);
168 if (unit == leader) {
169 BWAPI::Broodwar->drawCircleMap(unit->getPosition(), 2, BWAPI::Colors::White, true);
170 BWAPI::Broodwar->drawTextMap(BWAPI::Position(unit->getPosition().x - 12, unit->getPosition().y + 20), "LEADER", BWAPI::Colors::White);
171
172 if (info.currentState == &AttackingState::getInstance()) {
173 BWAPI::Broodwar->drawTextMap(BWAPI::Position(unit->getPosition().x - 16, unit->getPosition().y + 25), "-ATTACKING-", BWAPI::Colors::Orange);
174 }
175 if (info.currentState == &DefendingState::getInstance()) {
176 BWAPI::Broodwar->drawTextMap(BWAPI::Position(unit->getPosition().x - 16, unit->getPosition().y + 25), "-DEFENDING-", BWAPI::Colors::Orange);
177 }
178 if (info.currentState == &IdleState::getInstance()) {
179 BWAPI::Broodwar->drawTextMap(BWAPI::Position(unit->getPosition().x - 16, unit->getPosition().y + 25), "-IDLE-", BWAPI::Colors::Orange);
180 }
181 }
182
183 if (command.getTargetPosition() != BWAPI::Positions::None) {
184 BWAPI::Broodwar->drawLineMap(unit->getPosition(), command.getTargetPosition(), info.squadColor);
185 }
186 if (command.getTargetTilePosition() != BWAPI::TilePositions::None) {
187 BWAPI::Broodwar->drawLineMap(unit->getPosition(), BWAPI::Position(command.getTargetTilePosition()), info.squadColor);
188 }
189 if (command.getTarget() != nullptr) {
190 BWAPI::Broodwar->drawLineMap(unit->getPosition(), command.getTarget()->getPosition(), info.squadColor);
191 }
192
193 // Draws squad ID below unit
194 const BWAPI::Position textPos(unit->getPosition().x - 20, unit->getPosition().y + 20);
195 BWAPI::Broodwar->drawTextMap(textPos, "%d", info.squadId);
196 }
197}

◆ drawSquadBox()

void Squad::drawSquadBox ( )

Definition at line 123 of file Squad.cpp.

123 {
124 int leftMost = 0;
125 int topMost = 0;
126 int rightMost = 0;
127 int bottomMost = 0;
128 constexpr int offset = 16;
129
130 // Something for making observer more visible in group
131 if (observer != nullptr) {
132 const BWAPI::Position topLeft = BWAPI::Position(observer->getPosition().x - offset, observer->getPosition().y - offset);
133 const BWAPI::Position bottomRight = BWAPI::Position(observer->getPosition().x + offset, observer->getPosition().y + offset);
134 BWAPI::Broodwar->drawBoxMap(topLeft, bottomRight, BWAPI::Colors::Purple);
135 }
136
137 // Boundary box of the squad
138 for (const auto& unit : info.units) {
139 const int dist = unit->getPosition().getApproxDistance(leader->getPosition());
140 const int maxDist = 300;
141 if (dist < maxDist) {
142 const int x = unit->getPosition().x - leader->getPosition().x;
143 const int y = unit->getPosition().y - leader->getPosition().y;
144
145 if (x < leftMost) { leftMost = x; }
146 if (x > rightMost) { rightMost = x; }
147 if (y < topMost) { topMost = y; }
148 if (y > bottomMost) { bottomMost = y; }
149 }
150 }
151
152 // Drawing squad boundary box (color based on squad state)
153 const BWAPI::Position topLeft = (leader->getPosition() + BWAPI::Position(leftMost - offset, topMost - offset)).makeValid();
154 const BWAPI::Position bottomRight = (leader->getPosition() + BWAPI::Position(rightMost + offset, bottomMost + offset)).makeValid();
155 BWAPI::Broodwar->drawBoxMap(topLeft, bottomRight, CombatManager::stateColorMap[info.currentState]);
156}

◆ observerOnFrame()

void Squad::observerOnFrame ( )

Defines the behavior of the observer unit in the squad.


If the observer is not under attack, it will stay above the leader.
If the observer is under attack, it will run towards the base (typically away from enemies).

Definition at line 109 of file Squad.cpp.

109 {
110 // No matter the state, observer should have same behavior.
111 // If not in danger, stay above leader.
112 // Else, run towards base (typically away from enemies)
113 if (observer != nullptr && leader != nullptr) {
114 if (!observer->isUnderAttack() || observer->getUnitsInRadius(100, BWAPI::Filter::IsEnemy && BWAPI::Filter::CanAttack).empty()) {
115 observer->move(leader->getPosition());
116 }
117 else {
118 observer->move(BWAPI::Position(BWAPI::Broodwar->self()->getStartLocation()));
119 }
120 }
121}

◆ onFrame()

void Squad::onFrame ( )

Definition at line 11 of file Squad.cpp.

11 {
12 // Process current squad state
13 info.currentState->Update(this);
14
16
17#ifdef DEBUG_SQUAD
18 drawDebugInfo();
19#endif
20}
void observerOnFrame()
Defines the behavior of the observer unit in the squad.
Definition Squad.cpp:109

◆ operator!=()

bool Squad::operator!= ( const Squad & other)
inlinenoexcept

Definition at line 82 of file Squad.h.

82 {
83 return !(*this == other);
84 }

◆ operator==()

bool Squad::operator== ( const Squad & other)
inlinenoexcept

Definition at line 79 of file Squad.h.

79 {
80 return this->info.squadId == other.info.squadId;
81 }

◆ removeUnit()

void Squad::removeUnit ( BWAPI::Unit unit)

Definition at line 30 of file Squad.cpp.

30 {
31 if (unit == nullptr) {
32 return;
33 }
34
35 if (unit == leader) {
36 BOIDS::leaderRadiusMap.erase(unit);
37 info.units.erase(std::remove(info.units.begin(), info.units.end(), unit), info.units.end());
38
39 if (info.units.empty()){
40 return;
41 }
42
43 // Closest unit to the leader is assigned as the new leader
44 double closest = std::numeric_limits<double>::infinity();
45 BWAPI::Unit closestUnit = nullptr;
46 const BWAPI::Position leaderPos = unit->getPosition();
47 for (BWAPI::Unit _unit : info.units) {
48 if (!_unit || !_unit->exists()) {
49 continue;
50 }
51
52 const BWAPI::Position unitPos = _unit->getPosition();
53 const double dist = unitPos.getDistance(leaderPos);
54
55 if (dist < closest) {
56 closest = dist;
57 closestUnit = _unit;
58 }
59 }
60
61 // Assign closest unit to leader as the new leader
62 if (closestUnit != nullptr) {
63 leader = closestUnit;
64 }
65 }
66 else if (unit == observer) {
67 observer = nullptr;
68 }
69 else {
70 info.units.erase(std::remove(info.units.begin(), info.units.end(), unit), info.units.end());
71 }
72}

◆ setState()

void Squad::setState ( SquadState & newState)

Definition at line 22 of file Squad.cpp.

22 {
23 if (info.currentState != nullptr) {
24 info.currentState->Exit(this);
25 }
26 info.currentState = &newState;
27 info.currentState->Enter(this);
28}

Member Data Documentation

◆ info

SquadInfo Squad::info

Definition at line 60 of file Squad.h.

◆ leader

BWAPI::Unit Squad::leader = nullptr

Definition at line 58 of file Squad.h.

◆ observer

BWAPI::Unit Squad::observer = nullptr

Definition at line 59 of file Squad.h.


The documentation for this class was generated from the following files: