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

(DISCONTINUED)
Unfortunately, BOIDS could not be optimized enough to be run within tournament computation time rules. However, the algorithm is still a cool implementation of a flocking algorithm for unit movement, so it is being kept in the codebase for potential future use. More...

#include <BOIDS.h>

Static Public Member Functions

static void squadFlock (Squad *squad)
 Main function of BOIDS flocking. Calculates leader, separation, and terrain avoidance vectors for steering each unit in the squad.
Uses spatial partitioning optimization to only calculate separation vector with nearby units.

BOIDS vectors are applied to units in a gradually, being applied to previous BOIDS vectors with a reduced magnitude to cause steering rather than flickering.

Static Public Attributes

static unordered_map< BWAPI::Unit, pair< int, int >, unitHashleaderRadiusMap

Static Private Member Functions

static SeparationCell unitToCell (BWAPI::Position pos)
 Maps unit to a SeparationCell within the grid used for spatial partitioning.
static VectorPos getSeparationSteering (VectorPos unitPos, VectorPos neighborPos, VectorPos unitVelocity)
 Calculates separation steering based on cross product between unit-neighbor vector and the unit's velocity vector.
static VectorPos getTerrainSteering (BWAPI::Unit unit, VectorPos unitPos, VectorPos leaderPos, VectorPos unitVelocity)
 Checks ahead of unit and, if it finds a close enough terrain, returns vector pointing away from terrain.
static bool inLeaderRadius (VectorPos unitPos, VectorPos leaderPos, double leaderRadius)

Static Private Attributes

static unordered_map< BWAPI::Unit, int, unitHashterrainFrameMap
 Maps unit to a frame counter, being reduced every frame.
static unordered_map< BWAPI::Unit, VectorPos, unitHashterrainDirMap
 Maps unit to a previously calculated terrain vector.
static unordered_map< BWAPI::Unit, unordered_map< BWAPI::Unit, double, unitHash >, unitHashunitDistanceCache
 Maps unit to an unordered_map of previous distance calculations for its surrounding units.
static unordered_map< BWAPI::Unit, VectorPos, unitHashpreviousBOIDSMap
 Maps unit to its previous BOIDS calculations to apply the current BOIDS vector gradually.

Detailed Description

(DISCONTINUED)
Unfortunately, BOIDS could not be optimized enough to be run within tournament computation time rules. However, the algorithm is still a cool implementation of a flocking algorithm for unit movement, so it is being kept in the codebase for potential future use.

Uses flocking algorithm to maintain unit separation and formation while moving towards a position.
Units will adjust their position based on a leader vector, separation vector, and terrain avoidance vector.
Leader vector keeps units surrounding the squad leader, separation vector keeps units from crowding too tightly, and terrain avoidance vector keeps units away from terrain.

Normalization is done through VectorPos class

Definition at line 67 of file BOIDS.h.

Member Function Documentation

◆ getSeparationSteering()

VectorPos BOIDS::getSeparationSteering ( VectorPos unitPos,
VectorPos neighborPos,
VectorPos unitVelocity )
staticprivate

Calculates separation steering based on cross product between unit-neighbor vector and the unit's velocity vector.

Uses cross product to determine whether to move left or right relative to the neighbouring unit.
This vector's magnitude is modified later in squadFlock() using SEPARATION_STRENGTH which is defined in BOIDS.h

Parameters
unitPosUnit position in BWAPI::Position
neighborPosNeighbor's position in BWAPI::Position
unitVelocityCurrent velocity of unit in VectorPos
Returns

Definition at line 273 of file BOIDS.cpp.

273 {
274 const VectorPos toNeighbor = (neighborPos - unitPos).normalized();
275 const VectorPos velocityDir = unitVelocity.normalized();
276
277 const double crossProduct = velocityDir.x * toNeighbor.y - velocityDir.y * toNeighbor.x;
278 // If crossProduct > 0, neighbor on left so need to go right
279 // vice versa.
280 VectorPos left = VectorPos(-velocityDir.y, velocityDir.x);
281 VectorPos right = VectorPos(velocityDir.y, -velocityDir.x);
282 VectorPos dir = crossProduct > 0 ? right : left;
283
284 return dir;
285}
VectorPos normalized()
Uses L^2 normalization Normalized VectorPos object.
Definition VectorPos.h:34

◆ getTerrainSteering()

VectorPos BOIDS::getTerrainSteering ( BWAPI::Unit unit,
VectorPos unitPos,
VectorPos leaderPos,
VectorPos unitVelocity )
staticprivate

Checks ahead of unit and, if it finds a close enough terrain, returns vector pointing away from terrain.

Uses unitVelocity to check all four corners of the unit. If, from these corners, the lookahead vectors find a terrain, the unit is going to collide with something soon.
Accumulates vectors pointing away from the terrain from each of the checked corners that found a terrain.
Final normalized vector used to steer unit away.

Parameters
unit
unitPos
leaderPos
unitVelocity
Returns

Definition at line 287 of file BOIDS.cpp.

287 {
288 VectorPos forward;
289
290 if (unitVelocity.getSqDistance() > 0.5) {
291 forward = unitVelocity.normalized();
292 }
293 else {
294 forward = (leaderPos - unitPos).normalized();
295 }
296
297 const int width = unit->getType().width();
298 const int height = unit->getType().height();
299
300 // Unit corners
301 const VectorPos topLeft(unitPos.x - width / 2, unitPos.y - height / 2);
302 const VectorPos topRight(unitPos.x + width / 2, unitPos.y - height / 2);
303 const VectorPos bottomLeft(unitPos.x - width / 2, unitPos.y + height / 2);
304 const VectorPos bottomRight(unitPos.x + width / 2, unitPos.y + height / 2);
305
306 const VectorPos topLeftCheck = topLeft + forward * (MAX_FORCE + 10);
307 const VectorPos topRightCheck = topRight + forward * (MAX_FORCE + 10);
308 const VectorPos bottomLeftCheck = bottomLeft + forward * (MAX_FORCE + 10);
309 const VectorPos bottomRightCheck = bottomRight + forward * (MAX_FORCE + 10);
310
311#ifdef DEBUG_DRAW
312 BWAPI::Broodwar->drawLineMap(topLeft, topLeftCheck, BWAPI::Colors::Green);
313 BWAPI::Broodwar->drawLineMap(topRight, topRightCheck, BWAPI::Colors::Green);
314 BWAPI::Broodwar->drawLineMap(bottomLeft, bottomLeftCheck, BWAPI::Colors::Green);
315 BWAPI::Broodwar->drawLineMap(bottomRight, bottomRightCheck, BWAPI::Colors::Green);
316#endif
317
318 VectorPos normal(0, 0);
319
320 // Accumulate normals from blocked corners
321 if (!BWAPI::Broodwar->isWalkable(BWAPI::WalkPosition(topLeftCheck))
322 || !BWAPI::Broodwar->getUnitsOnTile(BWAPI::TilePosition(topLeftCheck), BWAPI::Filter::IsBuilding).empty()) {
323 normal += (unitPos - topLeft).normalized();
324 }
325 if (!BWAPI::Broodwar->isWalkable(BWAPI::WalkPosition(topRightCheck))
326 || !BWAPI::Broodwar->getUnitsOnTile(BWAPI::TilePosition(topRightCheck), BWAPI::Filter::IsBuilding).empty()) {
327 normal += (unitPos - topRight).normalized();
328 }
329 if (!BWAPI::Broodwar->isWalkable(BWAPI::WalkPosition(bottomLeftCheck))
330 || !BWAPI::Broodwar->getUnitsOnTile(BWAPI::TilePosition(bottomLeftCheck), BWAPI::Filter::IsBuilding).empty()) {
331 normal += (unitPos - bottomLeft).normalized();
332 }
333 if (!BWAPI::Broodwar->isWalkable(BWAPI::WalkPosition(bottomRightCheck))
334 || !BWAPI::Broodwar->getUnitsOnTile(BWAPI::TilePosition(bottomRightCheck), BWAPI::Filter::IsBuilding).empty()) {
335 normal += (unitPos - bottomRight).normalized();
336 }
337
338 // No terrain detected
339 if (normal.getSqDistance() == 0) {
340 return VectorPos(0, 0);
341 }
342
343 normal = normal.normalized();
344
345#ifdef DEBUG_DRAW
346 BWAPI::Broodwar->drawLineMap(unitPos, unitPos + normal * 40, BWAPI::Colors::Yellow);
347#endif
348
349 return normal;
350}
double getSqDistance()
Returns squared distance of vector from origin (0, 0). Used for performance optimization instead of g...
Definition VectorPos.h:58

◆ inLeaderRadius()

bool BOIDS::inLeaderRadius ( VectorPos unitPos,
VectorPos leaderPos,
double leaderRadius )
staticprivate

Definition at line 356 of file BOIDS.cpp.

356 {
357 if (unitPos.getApproxDistance(leaderPos) <= leaderRadius) {
358 return true;
359 }
360 else {
361 return false;
362 }
363}

◆ squadFlock()

void BOIDS::squadFlock ( Squad * squad)
static

Main function of BOIDS flocking. Calculates leader, separation, and terrain avoidance vectors for steering each unit in the squad.
Uses spatial partitioning optimization to only calculate separation vector with nearby units.

BOIDS vectors are applied to units in a gradually, being applied to previous BOIDS vectors with a reduced magnitude to cause steering rather than flickering.

Parameters
squad

Definition at line 14 of file BOIDS.cpp.

14 {
15 unitDistanceCache.clear();
16
17 const int mapWidth = BWAPI::Broodwar->mapWidth();
18 const int mapHeight = BWAPI::Broodwar->mapHeight();
19
20 // Spatial Paritioning optimization
21 unordered_map<SeparationCell, vector<BWAPI::Unit>, SeparationCellHash> unitGrid;
22 for (auto& unit : BWAPI::Broodwar->self()->getUnits()) {
23 SeparationCell cell;
24 if (unit->getType().isBuilding()) {
25 const int tileWidth = unit->getType().tileWidth();
26 const int tileHeight = unit->getType().tileHeight();
27
28 for (int x = -(tileWidth / 2); x < tileWidth / 2; x++) {
29 for (int y = -(tileHeight / 2); y < tileHeight / 2; y++) {
30 cell = unitToCell(unit->getPosition() + BWAPI::Position(x * 32, y * 32));
31 unitGrid[cell].push_back(unit);
32 }
33 }
34 }
35 else {
36 cell = unitToCell(unit->getPosition());
37 unitGrid[cell].push_back(unit);
38 }
39 }
40
41 for (const auto& unit : squad->info.units) {
42 if (!unit->exists()) {
43 continue;
44 }
45
46 // Ignore leader or if unit is attacking
47 if (unit == squad->leader || unit->isAttackFrame()) {
48#ifdef DEBUG_DRAW
49 BWAPI::Broodwar->drawCircleMap(unit->getPosition(), MIN_SEPARATION_DISTANCE, BWAPI::Colors::Red);
50#endif
51 continue;
52 }
53
54 // Position info
55 const VectorPos unitPos = VectorPos(unit->getPosition());
56 const VectorPos leaderPos = VectorPos(squad->leader->getPosition());
57 const double distUnitToLeader = unitPos.getApproxDistance(leaderPos);
58
59 // Don't worry about flocking if unit is too far away from the leader
60 if (distUnitToLeader > BOIDS_RANGE || unit->isStuck()) {
61 unit->attack(leaderPos);
62 continue;
63 }
64
65 // Velocity info
66 VectorPos unitVelocity = VectorPos(unit->getVelocityX(), unit->getVelocityY());
67 VectorPos leaderVelocity = VectorPos(squad->leader->getVelocityX(), squad->leader->getVelocityY());
68 const bool isZeroUnitVelocity = unitVelocity.getSqDistance() == 0;
69
70 // For drawing radiuses
71#ifdef DEBUG_DRAW
72 BWAPI::Broodwar->drawCircleMap(unitPos, MIN_SEPARATION_DISTANCE, BWAPI::Colors::Red);
73 BWAPI::Broodwar->drawCircleMap(leaderPos, BOIDS_RANGE, BWAPI::Colors::Grey);
74#endif
75
76 // LEADER VECTOR
77 VectorPos leaderVec = VectorPos(0, 0);
78 const double spacing = 30.0;
79 double outer_radius;
80
81 // Update leader radii map if needed
82 const int squadSize = CombatManager::unitSquadMap[unit]->info.units.size();
83
84 // Only calculate outer_radius if squad size has changed since the unit's previous calculation
85 // Saves performance since sqrt is expensive
86 if (squadSize == leaderRadiusMap[squad->leader].first) {
87 outer_radius = leaderRadiusMap[squad->leader].second;
88 }
89 else {
90 outer_radius = max(spacing * 1.5, spacing + sqrt(squad->info.units.size()) * spacing);
91 leaderRadiusMap[unit].first = squadSize;
92 leaderRadiusMap[unit].second = outer_radius;
93 }
94#ifdef DEBUG_DRAW
95 BWAPI::Broodwar->drawCircleMap(leaderPos, outer_radius, BWAPI::Colors::Yellow);
96#endif
97
98 leaderVec += leaderVelocity * clamp(distUnitToLeader / outer_radius, 0.0, 1.0);
99
100 // leaderVec stronger when farther from leader + includes velocity for grouping while moving
101 if (distUnitToLeader > outer_radius) {
102 leaderVec += (leaderPos - unitPos) * (1 / distUnitToLeader);
103 }
104
105 // SEPARATION VECTOR
106 VectorPos separationVec = VectorPos(0, 0);
107 VectorPos leaderSeparationVec = VectorPos(0, 0);
108
109 SeparationCell thisCell = unitToCell(unit->getPosition());
110 auto& squadMap = CombatManager::unitSquadMap;
111 for (int dx = -1; dx <= 1; dx++) {
112 for (int dy = -1; dy <= 1; dy++) {
113 for (const auto& neighbor : unitGrid[thisCell + SeparationCell(dx, dy)]) {
114 // If neighbor is the current unit, dont process
115 if (neighbor == unit) {
116 continue;
117 }
118
119 const VectorPos neighborPos = VectorPos(neighbor->getPosition().x, neighbor->getPosition().y);
120
121 Squad* unitSquad = squadMap[unit];
122 Squad* neighborSquad;
123 BWAPI::Unit neighborLeader;
124 VectorPos neighborLeaderPos;
125 if (squadMap.find(neighbor) == squadMap.end()) {
126 neighborSquad = nullptr;
127 neighborLeader = nullptr;
128 neighborLeaderPos = VectorPos();
129 }
130 else {
131 neighborSquad = squadMap[neighbor];
132 neighborLeader = neighborSquad->leader;
133 neighborLeaderPos = VectorPos(neighborLeader->getPosition());
134 }
135
136 // unitDistanceCache keeps distances between units for this frame.
137 // If neighbor has not seen another unit yet or if the neighbor has not seen this unit, then this unit should store the distance first
138 // Otherwise the neighbor has seen this unit before and has tracked the distance already so use that distance.
139 double distToNeighbor;
140 if (unitDistanceCache.find(neighbor) != unitDistanceCache.end()) {
141 if (unitDistanceCache[neighbor].find(unit) != unitDistanceCache[neighbor].end()) {
142 distToNeighbor = unitDistanceCache[neighbor][unit];
143 }
144 else {
145 distToNeighbor = unitPos.getDistance(neighborPos);
146 }
147 }
148 else {
149 distToNeighbor = unitPos.getDistance(neighborPos);
150 unitDistanceCache[unit][neighbor] = distToNeighbor;
151 }
152
153 const bool isSameSquad = unitSquad && neighborSquad && unitSquad == neighborSquad;
154 const bool isNeighborLeader = neighborLeader && neighborLeader == neighbor;
155 const bool neighborInLeaderRadius = neighborLeaderPos != VectorPos() && inLeaderRadius(neighborPos, neighborLeaderPos, outer_radius);
156 const bool unitInLeaderRadius = inLeaderRadius(unitPos, leaderPos, outer_radius);
157
158 if (isSameSquad) { // same squad
159 if (isNeighborLeader) {
160 leaderSeparationVec += (unitPos - neighborPos);
161 }
162 else if (!unitInLeaderRadius && neighborInLeaderRadius) { // unit not in radius but neighbor is
163 separationVec += VectorPos(0, 0);
164 }
165 else if (isZeroUnitVelocity) {
166 separationVec += (unitPos - neighborPos);
167 continue;
168 }
169 else {
170 separationVec += getSeparationSteering(unitPos, neighborPos, unitVelocity);
171 }
172 }
173 else if (isNeighborLeader) { // neighbor is a leader of different squad
174 leaderSeparationVec += (unitPos - neighborPos);
175 }
176 else {
177 if (isZeroUnitVelocity) {
178 separationVec += (unitPos - neighborPos);
179 continue;
180 }
181 separationVec += getSeparationSteering(unitPos, neighborPos, unitVelocity);
182 }
183 }
184 }
185 }
186
187 VectorPos finalLeaderVec = leaderVec * LEADER_STRENGTH;
188 VectorPos finalSeparationVec = (leaderSeparationVec * LEADER_SEPARATION_STRENGTH) + (separationVec * SEPARATION_STRENGTH);
189
190 // TERRAIN VECTOR
191 VectorPos terrainVec;
192 double terrainSqDistance;
193 // Look to see if unit is already avoiding terrain
194 if (terrainFrameMap[unit] > 0) {
195 terrainVec = terrainDirMap[unit];
196 terrainSqDistance = terrainVec.getSqDistance();
197 terrainFrameMap[unit]--;
198 }
199 else {
200 terrainVec = getTerrainSteering(unit, unitPos, leaderPos, unitVelocity);
201 terrainSqDistance = terrainVec.getSqDistance();
202 if (terrainSqDistance > 0) {
203 terrainDirMap[unit] = terrainVec;
204 terrainFrameMap[unit] = TERRAIN_AVOIDANCE_FRAMES;
205 }
206 }
207
208 // BOIDS VECTOR
209
210 VectorPos boidsVector = finalLeaderVec + finalSeparationVec;
211
212 // Applying terrain avoidance after leader + separation to remove terrain component from final boidsVector
213 if (terrainSqDistance > 0) {
214 const VectorPos terrainNorm = terrainVec.normalized();
215 const double dotProduct = boidsVector.dot(terrainNorm);
216
217 if (dotProduct < 0) {
218 boidsVector -= terrainNorm * dotProduct * TERRAIN_STRENGTH; // remove component of vector going into the wall
219 }
220 }
221
222 // At a minimum, scale BOIDS by 75%. Too short was making units too slow.
223 const double distScale = max(sqrt(distUnitToLeader / outer_radius), 0.75);
224 boidsVector = boidsVector * distScale;
225
226 // If the adjustment is not significant enough, don't move the unit
227 const double boidsLength = boidsVector.getLength();
228 if (boidsLength < 0.2) {
229 previousBOIDSMap[unit] = boidsVector;
230 continue;
231 }
232
233 // Clamping
234 if (boidsLength < MIN_FORCE) {
235 boidsVector = boidsVector / boidsLength * MIN_FORCE;
236 }
237 else if (boidsLength > MAX_FORCE) {
238 boidsVector = boidsVector / boidsLength * MAX_FORCE;
239 }
240
241 // Cache boidsVector to smoothly apply changes instead of drastic ones (was causing too much jittering)
242 if (previousBOIDSMap.find(unit) != previousBOIDSMap.end()) {
243 boidsVector = previousBOIDSMap[unit] * 0.7 + boidsVector * 0.3;
244 previousBOIDSMap[unit] = boidsVector;
245 }
246 else {
247 previousBOIDSMap[unit] = boidsVector;
248 }
249
250 const VectorPos finalTarget = unitPos + unitVelocity + boidsVector;
251
252 unit->attack(finalTarget);
253
254#ifdef DEBUG_MAGNITUDES
255 cout << "Separation Vector : " << finalSeparationVec.getLength() << endl;
256 cout << "Leader Vector : " << finalLeaderVec.getLength() << endl;
257 cout << "Boids Vector : " << boidsVector.getLength() << endl;
258 cout << "Final Vector : " << finalTarget << endl;
259 //BWAPI::Broodwar->drawLineMap(unitPos, unitPos + separationVec * 10, BWAPI::Colors::Red);
260 //BWAPI::Broodwar->drawLineMap(unitPos, unitPos + cohesionVec * 10, BWAPI::Colors::Yellow);
261 //BWAPI::Broodwar->drawLineMap(unitPos, unitPos + alignmentVec * 10, BWAPI::Colors::Purple);
262 //BWAPI::Broodwar->drawLineMap(unitPos, unitPos + leaderVec * 10, BWAPI::Colors::Blue);
263 //BWAPI::Broodwar->drawLineMap(unitPos, unitPos + finalDirection * 10, BWAPI::Colors::Green);
264 //BWAPI::Broodwar->printf("Separation magnitude: %f", BWAPI::Position(0, 0).getDistance(separationVec));
265 //BWAPI::Broodwar->printf("Cohesion magnitude: %f", BWAPI::Position(0, 0).getDistance(cohesionVec));
266 //BWAPI::Broodwar->printf("Alignment magnitude: %f", BWAPI::Position(0, 0).getDistance(alignmentVec));
267 //BWAPI::Broodwar->printf("Leader magnitude: %f", BWAPI::Position(0, 0).getDistance(leaderDirection));
268 //BWAPI::Broodwar->printf("FinalDirection magnitude: %f", unitPos.getDistance(finalDirection));
269#endif
270 }
271}
static unordered_map< BWAPI::Unit, int, unitHash > terrainFrameMap
Maps unit to a frame counter, being reduced every frame.
Definition BOIDS.h:97
static VectorPos getTerrainSteering(BWAPI::Unit unit, VectorPos unitPos, VectorPos leaderPos, VectorPos unitVelocity)
Checks ahead of unit and, if it finds a close enough terrain, returns vector pointing away from terra...
Definition BOIDS.cpp:287
static VectorPos getSeparationSteering(VectorPos unitPos, VectorPos neighborPos, VectorPos unitVelocity)
Calculates separation steering based on cross product between unit-neighbor vector and the unit's vel...
Definition BOIDS.cpp:273
static unordered_map< BWAPI::Unit, VectorPos, unitHash > previousBOIDSMap
Maps unit to its previous BOIDS calculations to apply the current BOIDS vector gradually.
Definition BOIDS.h:123
static unordered_map< BWAPI::Unit, unordered_map< BWAPI::Unit, double, unitHash >, unitHash > unitDistanceCache
Maps unit to an unordered_map of previous distance calculations for its surrounding units.
Definition BOIDS.h:114
static unordered_map< BWAPI::Unit, VectorPos, unitHash > terrainDirMap
Maps unit to a previously calculated terrain vector.
Definition BOIDS.h:105
static SeparationCell unitToCell(BWAPI::Position pos)
Maps unit to a SeparationCell within the grid used for spatial partitioning.
Definition BOIDS.cpp:352
double dot(VectorPos other)
Returns dot product of this vector and another vector.
Definition VectorPos.h:50

◆ unitToCell()

SeparationCell BOIDS::unitToCell ( BWAPI::Position pos)
staticprivate

Maps unit to a SeparationCell within the grid used for spatial partitioning.

Returns unit's SeparationCell on the spatial grid map (unitGrid) that stores unit counts on the game map's TilePositions

Parameters
posBWAPI::Position of the unit
Returns
SeparationCell with the x and y coordinates of the cell

Definition at line 352 of file BOIDS.cpp.

352 {
353 return SeparationCell(pos.x / MIN_SEPARATION_DISTANCE, pos.y / MIN_SEPARATION_DISTANCE);
354}

Member Data Documentation

◆ leaderRadiusMap

unordered_map< BWAPI::Unit, pair< int, int >, unitHash > BOIDS::leaderRadiusMap
static

Definition at line 79 of file BOIDS.h.

◆ previousBOIDSMap

unordered_map< BWAPI::Unit, VectorPos, unitHash > BOIDS::previousBOIDSMap
staticprivate

Maps unit to its previous BOIDS calculations to apply the current BOIDS vector gradually.

BOIDS forces/vectors are not applied in its entirety if a previous BOIDS vector was found.
This is to avoid doing sudden flickering movements due to new forces.
The current BOIDS direction is applied, with a reduced magnitude, to the previous BOIDS direction to "steer" the unit instead of drastically changing its direction.

Definition at line 123 of file BOIDS.h.

◆ terrainDirMap

unordered_map< BWAPI::Unit, VectorPos, unitHash > BOIDS::terrainDirMap
staticprivate

Maps unit to a previously calculated terrain vector.

Tracks the vector the unit is currently travelling in to avoid terrain (if the unit had recently avoided any terrain)
If a unit is still avoiding terrain (terrainFrameMap[unit] > 0), then applies this direction to the boidsVector for the current frame.

Definition at line 105 of file BOIDS.h.

◆ terrainFrameMap

unordered_map< BWAPI::Unit, int, unitHash > BOIDS::terrainFrameMap
staticprivate

Maps unit to a frame counter, being reduced every frame.

To avoid constant checks for when units are near frames, the terrainFrameMap tracks the frames alotted to units for avoiding terrain.
If a unit's terrain frames are still greater than 0, the unit's terrain vector will not be calculated.

Definition at line 97 of file BOIDS.h.

◆ unitDistanceCache

unordered_map< BWAPI::Unit, unordered_map< BWAPI::Unit, double, unitHash >, unitHash > BOIDS::unitDistanceCache
staticprivate

Maps unit to an unordered_map of previous distance calculations for its surrounding units.

Since we're looping through units, the distance between two units will normally be checked twice. This distance measurement is expensive.
To optimize the distance calculation, this map tracks the distance between a unit and its surrounding units.
Once one unit calculates the distance between itself and other units, when the latter arrives in the loop the unit will check the map and find previously calculated distances.

Definition at line 114 of file BOIDS.h.


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