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

The EconomyManager is responsible for the assignment of workers to be able to farm optimally across the nexus's ProtoBot creates over the course of a game. Each nexus has a defined NexusEconomy that implements a resource farming algorithm to optimally schedule workers to gather resources. More...

#include <EconomyManager.h>

Public Member Functions

 EconomyManager (ProtoBotCommander *commanderReference)
void onStart ()
void onFrame ()
void onUnitDestroy (BWAPI::Unit unit)
void assignUnit (BWAPI::Unit unit)
std::vector< NexusEconomygetNexusEconomies ()
BWAPI::Unitset getWorkersToTransfer (int numberOfWorkers, NexusEconomy &nexusEconomy)
void resourcesDepletedTranfer (BWAPI::Unitset workers, NexusEconomy &nexusEconomy)
BWAPI::Unit getAvalibleWorker (BWAPI::Position buildLocation)
BWAPI::Unit getUnitScout ()
void getMineralsAtBase (BWAPI::TilePosition nexusLocation, NexusEconomy &nexusEconomy)
bool checkRequestAlreadySent (int unitID)
bool workerIsConstructing (BWAPI::Unit)

Public Attributes

ProtoBotCommandercommanderReference
std::vector< NexusEconomynexusEconomies
int newMinerals
int totalWorkers = 0

Detailed Description

The EconomyManager is responsible for the assignment of workers to be able to farm optimally across the nexus's ProtoBot creates over the course of a game. Each nexus has a defined NexusEconomy that implements a resource farming algorithm to optimally schedule workers to gather resources.

Definition at line 15 of file EconomyManager.h.

Constructor & Destructor Documentation

◆ EconomyManager()

EconomyManager::EconomyManager ( ProtoBotCommander * commanderReference)

Definition at line 7 of file EconomyManager.cpp.

7 : commanderReference(commanderReference)
8{
9
10}

Member Function Documentation

◆ assignUnit()

void EconomyManager::assignUnit ( BWAPI::Unit unit)

Definition at line 96 of file EconomyManager.cpp.

97{
98 if (unit->getPlayer() != BWAPI::Broodwar->self()) return;
99
100 switch (unit->getType())
101 {
102 case BWAPI::UnitTypes::Protoss_Nexus:
103 {
104 bool alreadyExists = false;
105 for (const NexusEconomy& nexusEconomy : nexusEconomies)
106 {
107 if (nexusEconomy.nexus == unit)
108 {
109 alreadyExists = true;
110 break;
111 }
112 }
113
114 if (alreadyExists == false)
115 {
116 NexusEconomy temp = NexusEconomy(unit, nexusEconomies.size() + 1, this);
117 getMineralsAtBase(unit->getTilePosition(), temp);
118 nexusEconomies.push_back(temp);
119 //std::cout << "nexus: " << temp.workers.size();
120
121 }
122 else
123 {
124 //std::cout << "Nexus Already Exists" << "\n";
125 }
126
127
128 break;
129 }
130 case BWAPI::UnitTypes::Protoss_Assimilator:
131 {
132 //[TODO] need to verify that this will not assign a assimilator if we are performing a gas steal
133 for (NexusEconomy& nexusEconomy : nexusEconomies)
134 {
135 if (unit->getDistance(nexusEconomy.nexus->getPosition()) <= 300)
136 {
137 nexusEconomy.assignAssimilator(unit);
138 //std::cout << "Assigned Assimilator " << unit->getID() << " to Nexus " << nexusEconomy.nexusID << "\n";
139 break;
140 }
141 }
142 break;
143 }
144 case BWAPI::UnitTypes::Protoss_Probe:
145 {
146 for (NexusEconomy& nexusEconomy : nexusEconomies)
147 {
148 if (unit->getDistance(nexusEconomy.nexus->getPosition()) <= 300)
149 {
150 //std::cout << "Assigned Probe " << unit->getID() << " to Nexus " << nexusEconomy.nexusID << "\n";
151 nexusEconomy.assignWorker(unit);
152 break;
153 }
154 }
155 break;
156 }
157 }
158}

◆ checkRequestAlreadySent()

bool EconomyManager::checkRequestAlreadySent ( int unitID)

Definition at line 366 of file EconomyManager.cpp.

367{
368 return commanderReference->alreadySentRequest(unitID);
369}

◆ getAvalibleWorker()

BWAPI::Unit EconomyManager::getAvalibleWorker ( BWAPI::Position buildLocation)

Definition at line 267 of file EconomyManager.cpp.

268{
269 BWAPI::Unit closestWorker = nullptr;
270 int distance = INT_MAX;
271
272 for (NexusEconomy& nexusEconomy : nexusEconomies)
273 {
274 BWAPI::Unit unitToReturn = nexusEconomy.getWorkerToBuild(buildLocation);
275
276 if (unitToReturn == nullptr) continue;
277
278 const int approxDis = buildLocation.getApproxDistance(unitToReturn->getPosition());
279
280 if (approxDis < distance)
281 {
282 closestWorker = unitToReturn;
283 distance = approxDis;
284 }
285 }
286
287 return closestWorker;
288}

◆ getMineralsAtBase()

void EconomyManager::getMineralsAtBase ( BWAPI::TilePosition nexusLocation,
NexusEconomy & nexusEconomy )

Definition at line 300 of file EconomyManager.cpp.

301{
302 const BWEM::Base* myBase = nullptr;
303 bool found = false;
304
305 for (const Area& area : theMap.Areas())
306 {
307 for (const BWEM::Base& base : area.Bases()) {
308 if (base.Location().getApproxDistance(nexusLocation) < 5) {
309 myBase = &base;
310 found = true;
311 break;
312 }
313 }
314 if (found) { break; }
315 }
316
317 BWAPI::Unitset mineralsToReturn;
318 BWAPI::Unitset geysersToReturn;
319
320 if (myBase)
321 {
322 for (const auto* mineral : myBase->Minerals())
323 {
324 mineralsToReturn.insert(mineral->Unit());
325 }
326 newNexus.minerals = mineralsToReturn;
327
328 if (myBase->Geysers().size() != 0)
329 {
330 for (const auto* geyser : myBase->Geysers())
331 {
332 if (geyser == nullptr) continue;
333
334 newNexus.vespeneGyser = geyser->Unit();
335
336 BWAPI::Unitset unitsOnGeyser = BWAPI::Broodwar->getUnitsInRectangle(BWAPI::Position(geyser->TopLeft()), BWAPI::Position(geyser->BottomRight()));
337
338 for (BWAPI::Unit unit : unitsOnGeyser)
339 {
340 if (unit->getPlayer() == BWAPI::Broodwar->self() && unit->getType().isRefinery() && unit->exists())
341 {
342 newNexus.assimilator = unit;
343 }
344 }
345 }
346 }
347 }
348
349 newNexus.optimalWorkerAmount = newNexus.minerals.size() * OPTIMAL_WORKERS_PER_MINERAL;
350 newNexus.maximumWorkers = newNexus.optimalWorkerAmount + (newNexus.vespeneGyser != nullptr ? WORKERS_PER_ASSIMILATOR : 0);
351
352 //std::cout << "# of Minerals at nexus location: " << newNexus.minerals.size() << "\n";
353 //std::cout << "# Geyser at nexus location? " << (newNexus.vespeneGyser != nullptr ? "true\n" : "false\n");
354
355 //To keep probe production constant make this to be able to have more workers than nessecary at main or any other base. Transfers should disperse workers.
356 newNexus.workerOverflowAmount = (newNexus.minerals.size() * MAXIMUM_WORKERS_PER_MINERAL) + (newNexus.vespeneGyser != nullptr ? WORKERS_PER_ASSIMILATOR : 0);
357}

◆ getNexusEconomies()

std::vector< NexusEconomy > EconomyManager::getNexusEconomies ( )

Definition at line 359 of file EconomyManager.cpp.

360{
361 return nexusEconomies;
362}

◆ getUnitScout()

BWAPI::Unit EconomyManager::getUnitScout ( )

Definition at line 290 of file EconomyManager.cpp.

291{
292 for (NexusEconomy& nexusEconomy : nexusEconomies)
293 {
294 BWAPI::Unit unitToReturn = nexusEconomy.getWorkerToScout();
295
296 if (unitToReturn != nullptr) return unitToReturn;
297 }
298}

◆ getWorkersToTransfer()

BWAPI::Unitset EconomyManager::getWorkersToTransfer ( int numberOfWorkers,
NexusEconomy & nexusEconomy )

Definition at line 164 of file EconomyManager.cpp.

165{
166 BWAPI::Unitset workersToTransfer;
167 //Need to check if the size is sufficent for the transer possibly.
168 for (NexusEconomy& nexusEconomy : nexusEconomies)
169 {
170 if (nexusEconomy.nexusID == nexusEconomyRequest.nexusID) continue;
171
172 //Check if a nexus economy has workers to spare.
173 if (nexusEconomy.workers.size() != 0)
174 {
175 workersToTransfer = nexusEconomy.getWorkersToTransfer(numberOfWorkers);
176
177 //for (BWAPI::Unit worker : workersToTransfer)
178 //{
179 //nexusEconomyRequest.assignWorker(worker);
180 //}
181
182
183 //std::cout << "New nexus workers: " << nexusEconomyRequest.workers.size() << "\n";
184 break;
185 }
186 }
187
188 return workersToTransfer;
189
190}

◆ onFrame()

void EconomyManager::onFrame ( )

Definition at line 18 of file EconomyManager.cpp.

19{
20 for (NexusEconomy& nexusEconomy : nexusEconomies)
21 {
22 nexusEconomy.onFrame();
23
24 if (nexusEconomy.lifetime == 125)
25 {
26 if (nexusEconomy.nexusID > 1 && nexusEconomy.workers.size() == 0)
27 {
28 nexusEconomy.workers = getWorkersToTransfer(nexusEconomy.minerals.size(), nexusEconomy);;
29 nexusEconomy.assignWorkerBulk();
30 }
31 }
32 }
33}

◆ onStart()

void EconomyManager::onStart ( )

Definition at line 13 of file EconomyManager.cpp.

14{
15 nexusEconomies.clear();
16}

◆ onUnitDestroy()

void EconomyManager::onUnitDestroy ( BWAPI::Unit unit)

Definition at line 35 of file EconomyManager.cpp.

36{
37 if (unit->getPlayer() == BWAPI::Broodwar->enemy()) return;
38 int i = 0;
39
40 //Check which nexus economy the unit is assigned to.
41 for (std::vector<NexusEconomy>::iterator it = nexusEconomies.begin(); it != nexusEconomies.end(); ++it) {
42
43 //[TODO] Get assign workers to the closest nexus instead of just main.
44 if (unit->getID() == it->nexus->getID())
45 {
46 //Get the workers at the destroyed nexus and reassign them.
47 BWAPI::Unitset nexusEconomyWorkers = it->workers;
48
49 //std::cout << "Nexus size: " << nexusEconomies.size();
50
51 //it = nexusEconomies.erase(it);
52 if (nexusEconomies.size() == 1)
53 {
54 it = nexusEconomies.erase(it);
55 break;
56 }
57
58 //Assign workers to our "Main Base" index 0 of the Nexus Economies.
59 for (BWAPI::Unit worker : nexusEconomyWorkers)
60 {
61 //nexusEconomies.at(0).assignWorker(worker);
62 if (i >= nexusEconomies.size()-1)
63 {
64 i = 0;
65 }
66
67 if (nexusEconomies.at(i).nexus->getID() != it->nexus->getID())
68 {
69 nexusEconomies.at(i).assignWorker(worker);
70 }
71 else
72 {
73 i += 1;
74 nexusEconomies.at(i).assignWorker(worker);
75 }
76 i += 1;
77
78 }
79
80 it = nexusEconomies.erase(it);
81
82 break;
83 }
84 else if (it->OnUnitDestroy(unit) == true) break;
85 }
86}

◆ resourcesDepletedTranfer()

void EconomyManager::resourcesDepletedTranfer ( BWAPI::Unitset workers,
NexusEconomy & nexusEconomy )

Definition at line 192 of file EconomyManager.cpp.

193{
194 //std::cout << "Mineral has been depleted at Nexus Economy " << transferFrom.nexusID << ": Transfering " << workersToTransfer.size() << " probes...\n";
195 BWAPI::Unitset workersAdded;
196
197 //Search Nexus Economies for open worker slots.
198 for (NexusEconomy& nexusEconomy : nexusEconomies)
199 {
200 if (nexusEconomy.nexusID == transferFrom.nexusID) continue;
201
202 if (nexusEconomy.workers.size()+1 < nexusEconomy.optimalWorkerAmount || (nexusEconomy.workers.size() < nexusEconomy.optimalWorkerAmount && nexusEconomy.nexus->getTrainingQueue().empty()))
203 {
204 //std::cout << "Moving workers from Nexus Economy " << transferFrom.nexusID << " to Nexus Economy " << nexusEconomy.nexusID << "\n";
205 //std::cout << "Nexus Economy " << nexusEconomy.nexusID << " size before: " << nexusEconomy.workers.size() << "\n";
206
207 for (BWAPI::Unit worker : workersToTransfer)
208 {
209 nexusEconomy.assignWorker(worker);
210 workersAdded.insert(worker);
211
212 //std::cout << "Adding worker\n";
213
214 if ((nexusEconomy.workers.size()+1 == nexusEconomy.optimalWorkerAmount && !nexusEconomy.nexus->getTrainingQueue().empty())|| workersAdded.size() == workersToTransfer.size() || nexusEconomy.workers.size() == nexusEconomy.optimalWorkerAmount)
215 {
216 break;
217 }
218 }
219
220 if (workersAdded.size() == workersToTransfer.size()) break;
221
222 //std::cout << "Nexus Economy " << nexusEconomy.nexusID << " size after: " << nexusEconomy.workers.size() << "\n";
223 }
224
225 //Remove workers added.
226 for (BWAPI::Unit worker : workersAdded)
227 {
228 workersToTransfer.erase(worker);
229 }
230 workersAdded.clear();
231 }
232
233
234
235 //std::cout << "Workers left to transfer: " << workersToTransfer.size() << "\n";
236
237 //No nexus economies avalible just send them to the first one that has minerals.
238 if (workersToTransfer.size() != 0)
239 {
240 //std::cout << "No open nexus economies, just transfering them anyway\n";
241 for (NexusEconomy& nexusEconomy : nexusEconomies)
242 {
243 if (nexusEconomy.nexusID == transferFrom.nexusID) continue;
244
245 //std::cout << "Moving workers from Nexus Economy " << transferFrom.nexusID << " to Nexus Economy " << nexusEconomy.nexusID << "\n";
246
247 //std::cout << "Nexus Economy " << nexusEconomy.nexusID << " size before: " << nexusEconomy.workers.size() << "\n";
248 for (BWAPI::Unit worker : workersToTransfer)
249 {
250 nexusEconomy.assignWorker(worker);
251 workersAdded.insert(worker);
252 }
253 //std::cout << "Nexus Economy " << nexusEconomy.nexusID << " size after: " << nexusEconomy.workers.size() << "\n";
254 for (BWAPI::Unit worker : workersAdded)
255 {
256 workersToTransfer.erase(worker);
257 }
258 workersAdded.clear();
259 }
260 }
261
262 workersToTransfer.clear();
263 workersAdded.clear();
264}

◆ workerIsConstructing()

bool EconomyManager::workerIsConstructing ( BWAPI::Unit unit)

Definition at line 371 of file EconomyManager.cpp.

372{
373 return commanderReference->checkWorkerIsConstructing(unit);
374}

Member Data Documentation

◆ commanderReference

ProtoBotCommander* EconomyManager::commanderReference

Definition at line 18 of file EconomyManager.h.

◆ newMinerals

int EconomyManager::newMinerals

Definition at line 36 of file EconomyManager.h.

◆ nexusEconomies

std::vector<NexusEconomy> EconomyManager::nexusEconomies

Definition at line 19 of file EconomyManager.h.

◆ totalWorkers

int EconomyManager::totalWorkers = 0

Definition at line 37 of file EconomyManager.h.


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