BWAPI
|
00001 #include "ResourceTracker.h" 00002 00003 #include <math.h> 00004 #include <cassert> 00005 00006 #include "UnitTracker.h" 00007 #include "Requirement.h" 00008 #include "Logger.h" 00009 00010 ResourceTrackerClass::ResourceTrackerClass() 00011 { 00012 } 00013 00014 void ResourceTrackerClass::reservePlannedMinerals(int time, int amount) 00015 { 00016 if(time == Requirement::maxTime || amount == 0) 00017 return; 00018 00019 mPlannedReservedMinerals[time] += amount; 00020 } 00021 00022 void ResourceTrackerClass::reservePlannedGas(int time, int amount) 00023 { 00024 if(time == Requirement::maxTime || amount == 0) 00025 return; 00026 00027 mPlannedReservedGas[time] += amount; 00028 } 00029 00030 void ResourceTrackerClass::reservePlannedSupply(int time, int amount) 00031 { 00032 if(time == Requirement::maxTime || amount == 0) 00033 return; 00034 00035 mPlannedReservedSupply[time] += amount; 00036 00037 for(std::map<int, int>::reverse_iterator i = mFreeSupply.rbegin(); i != mFreeSupply.rend(); ++i) 00038 { 00039 if(i->first <= time) 00040 { 00041 i->second -= amount; 00042 if(i->second <= 0) 00043 { 00044 amount = -i->second; 00045 i->second = 0; 00046 00047 if(amount == 0) 00048 return; 00049 } 00050 else 00051 return; 00052 } 00053 } 00054 for(std::map<int, int>::iterator i = mFreeSupply.begin(); i != mFreeSupply.end(); ++i) 00055 { 00056 i->second -= amount; 00057 if(i->second <= 0) 00058 { 00059 amount = -i->second; 00060 i->second = 0; 00061 00062 if(amount == 0) 00063 return; 00064 } 00065 else 00066 return; 00067 } 00068 00069 LOGMESSAGEWARNING("It tried to reserve supply it didn't have"); 00070 } 00071 00072 void ResourceTrackerClass::reset() 00073 { 00074 mPlannedReservedMinerals.clear(); 00075 mPlannedReservedGas.clear(); 00076 mPlannedReservedSupply.clear(); 00077 mFreeSupply.clear(); 00078 mSupplyTime.clear(); 00079 00080 int timeNow = BWAPI::Broodwar->getFrameCount(); 00081 for(std::map<int, int>::iterator it = mCurrentReservedMinerals.begin(); it != mCurrentReservedMinerals.end();) 00082 { 00083 if(it->second <= 0) 00084 mCurrentReservedMinerals.erase(it++); 00085 else 00086 ++it; 00087 } 00088 mPlannedReservedMinerals = mCurrentReservedMinerals; 00089 00090 for(std::map<int, int>::iterator it = mCurrentReservedGas.begin(); it != mCurrentReservedGas.end();) 00091 { 00092 if(it->second <= 0) 00093 mCurrentReservedGas.erase(it++); 00094 else 00095 ++it; 00096 } 00097 mPlannedReservedGas = mCurrentReservedGas; 00098 00099 // Calculate free supply we have in the future 00100 for each(Unit unit in UnitTracker::Instance().getSupplyProviders())//TODO: hatcheries and lairs morphing return false but still give supply 00101 { 00102 if(unit->isCompleted()) 00103 mFreeSupply[timeNow] += unit->getType().supplyProvided(); 00104 else 00105 mFreeSupply[unit->getCompletedTime()] += unit->getType().supplyProvided(); 00106 } 00107 00108 // Cap it at 400 00109 int supplyTotal = 0; 00110 for(std::map<int, int>::iterator it = mFreeSupply.begin(); it != mFreeSupply.end(); ++it) 00111 { 00112 supplyTotal += it->second; 00113 if(supplyTotal > 400) 00114 { 00115 int difference = supplyTotal - 400; 00116 it->second -= difference; 00117 supplyTotal = 400; 00118 } 00119 } 00120 mSupplyTime = mFreeSupply; 00121 00122 // Remove the supply we are already using and that we plan to use 00123 int supplyUsed = BWAPI::Broodwar->self()->supplyUsed(); 00124 supplyTotal = 0; 00125 for(std::map<int, int>::iterator it = mFreeSupply.begin(); it != mFreeSupply.end();) 00126 { 00127 if(supplyUsed > 0) 00128 { 00129 int supplyToUse = std::min(supplyUsed, it->second); 00130 it->second -= supplyToUse; 00131 supplyUsed -= supplyToUse; 00132 } 00133 00134 supplyTotal += it->second; 00135 00136 if(it->second == 0) 00137 mFreeSupply.erase(it++); 00138 else 00139 ++it; 00140 } 00141 00142 for(std::map<int, int>::iterator i = mCurrentReservedSupply.begin(); i != mCurrentReservedSupply.end();) 00143 { 00144 if(i->second > 0) 00145 { 00146 int supplyToTake = std::min(supplyTotal, i->second); 00147 supplyTotal -= supplyToTake; 00148 reservePlannedSupply(i->first, supplyToTake); 00149 00150 ++i; 00151 } 00152 else 00153 mCurrentReservedSupply.erase(i++); 00154 } 00155 } 00156 00157 void ResourceTrackerClass::reserveCurrentMinerals(int time, int amount) 00158 { 00159 if(time == Requirement::maxTime || amount == 0) 00160 return; 00161 00162 mCurrentReservedMinerals[time] += amount; 00163 reservePlannedMinerals(time, amount); 00164 } 00165 00166 void ResourceTrackerClass::reserveCurrentGas(int time, int amount) 00167 { 00168 if(time == Requirement::maxTime || amount == 0) 00169 return; 00170 00171 mCurrentReservedGas[time] += amount; 00172 reservePlannedGas(time, amount); 00173 } 00174 00175 void ResourceTrackerClass::reserveCurrentSupply(int time, int amount) 00176 { 00177 if(time == Requirement::maxTime || amount == 0) 00178 return; 00179 00180 mCurrentReservedSupply[time] += amount; 00181 reservePlannedSupply(time, amount); 00182 } 00183 00184 void ResourceTrackerClass::releaseCurrentMinerals(int time, int amount) 00185 { 00186 mCurrentReservedMinerals[time] -= amount; 00187 } 00188 00189 void ResourceTrackerClass::releaseCurrentGas(int time, int amount) 00190 { 00191 mCurrentReservedGas[time] -= amount; 00192 } 00193 00194 void ResourceTrackerClass::releaseCurrentSupply(int time, int amount) 00195 { 00196 mCurrentReservedSupply[time] -= amount; 00197 } 00198 00199 int ResourceTrackerClass::earliestMineralAvailability(int amount) 00200 { 00201 double freeMinerals = BWAPI::Broodwar->self()->minerals(); 00202 00203 bool hasSpace = false; 00204 if(freeMinerals >= amount) 00205 { 00206 freeMinerals -= amount; 00207 hasSpace = true; 00208 } 00209 00210 int earliestTime = BWAPI::Broodwar->getFrameCount(); 00211 int lastTime = BWAPI::Broodwar->getFrameCount(); 00212 for(std::map<int, int>::iterator i = mPlannedReservedMinerals.begin(); i != mPlannedReservedMinerals.end(); ++i) 00213 { 00214 freeMinerals -= i->second; 00215 00216 if(i->first >= lastTime) 00217 { 00218 int timePassed = i->first - lastTime; 00219 lastTime = i->first; 00220 freeMinerals += timePassed * mMineralRate; 00221 } 00222 00223 if(!hasSpace && freeMinerals >= amount) 00224 { 00225 if(mMineralRate == 0) 00226 return Requirement::maxTime; 00227 00228 freeMinerals -= amount; 00229 hasSpace = true; 00230 earliestTime = int(i->first - (freeMinerals / mMineralRate)); 00231 } 00232 else if(freeMinerals < 0 && hasSpace) 00233 { 00234 hasSpace = false; 00235 freeMinerals += amount; 00236 } 00237 } 00238 00239 if(!hasSpace) 00240 { 00241 if(mMineralRate == 0) 00242 return Requirement::maxTime; 00243 00244 freeMinerals -= amount; 00245 earliestTime = lastTime + int(-freeMinerals / mMineralRate); 00246 } 00247 00248 return earliestTime; 00249 } 00250 00251 int ResourceTrackerClass::earliestGasAvailability(int amount) 00252 { 00253 double freeGas = BWAPI::Broodwar->self()->gas(); 00254 00255 bool hasSpace = false; 00256 if(freeGas >= amount) 00257 { 00258 freeGas -= amount; 00259 hasSpace = true; 00260 } 00261 00262 int earliestTime = BWAPI::Broodwar->getFrameCount(); 00263 int lastTime = BWAPI::Broodwar->getFrameCount(); 00264 for(std::map<int, int>::iterator i = mPlannedReservedGas.begin(); i != mPlannedReservedGas.end(); ++i) 00265 { 00266 freeGas -= i->second; 00267 00268 if(i->first >= lastTime) 00269 { 00270 int timePassed = i->first - lastTime; 00271 lastTime = i->first; 00272 freeGas += timePassed * mGasRate; 00273 } 00274 00275 if(!hasSpace && freeGas >= amount) 00276 { 00277 if(mGasRate == 0) 00278 return Requirement::maxTime; 00279 00280 freeGas -= amount; 00281 hasSpace = true; 00282 earliestTime = int(i->first - (freeGas / mGasRate)); 00283 } 00284 else if(freeGas < 0 && hasSpace) 00285 { 00286 hasSpace = false; 00287 freeGas += amount; 00288 } 00289 } 00290 00291 if(!hasSpace) 00292 { 00293 if(mGasRate == 0) 00294 return Requirement::maxTime; 00295 00296 freeGas -= amount; 00297 earliestTime = lastTime + int(-freeGas / mGasRate); 00298 } 00299 00300 return earliestTime; 00301 } 00302 00303 int ResourceTrackerClass::earliestSupplyAvailability(int amount) 00304 { 00305 int supplyTotal = 0; 00306 for(std::map<int, int>::iterator i = mFreeSupply.begin(); i != mFreeSupply.end(); ++i) 00307 { 00308 supplyTotal += i->second; 00309 if(supplyTotal >= amount) 00310 return i->first; 00311 } 00312 00313 return Requirement::maxTime; 00314 } 00315 00316 int ResourceTrackerClass::availableMineralAtTime(int time) 00317 { 00318 double freeMinerals = BWAPI::Broodwar->self()->minerals(); 00319 00320 int lastTime = BWAPI::Broodwar->getFrameCount(); 00321 for(std::map<int, int>::iterator i = mPlannedReservedMinerals.begin(); i != mPlannedReservedMinerals.end(); ++i) 00322 { 00323 if(i->first > time) 00324 break; 00325 00326 freeMinerals -= i->second; 00327 00328 if(i->first >= lastTime) 00329 { 00330 int timePassed = i->first - lastTime; 00331 lastTime = i->first; 00332 freeMinerals += timePassed * mMineralRate; 00333 } 00334 } 00335 00336 if(time > lastTime) 00337 { 00338 int timePassed = time - lastTime; 00339 freeMinerals += timePassed * mMineralRate; 00340 } 00341 00342 return int(freeMinerals); 00343 } 00344 00345 int ResourceTrackerClass::availableGasAtTime(int time) 00346 { 00347 double freeGas = BWAPI::Broodwar->self()->gas(); 00348 00349 int lastTime = BWAPI::Broodwar->getFrameCount(); 00350 for(std::map<int, int>::iterator i = mPlannedReservedGas.begin(); i != mPlannedReservedGas.end(); ++i) 00351 { 00352 if(i->first > time) 00353 break; 00354 00355 freeGas -= i->second; 00356 00357 if(i->first >= lastTime) 00358 { 00359 int timePassed = i->first - lastTime; 00360 lastTime = i->first; 00361 freeGas += timePassed * mGasRate; 00362 } 00363 } 00364 00365 if(time > lastTime) 00366 { 00367 int timePassed = time - lastTime; 00368 freeGas += timePassed * mGasRate; 00369 } 00370 00371 return int(freeGas); 00372 } 00373 00374 int ResourceTrackerClass::availableSupplyAtTime(int time) 00375 { 00376 int total = totalSupplyAtTime(time); 00377 00378 for(std::map<int, int>::iterator i = mPlannedReservedSupply.begin(); i != mPlannedReservedSupply.end(); ++i) 00379 { 00380 if(i->first > time) 00381 break; 00382 else 00383 total -= i->second; 00384 } 00385 00386 total -= BWAPI::Broodwar->self()->supplyUsed(); 00387 00388 return total; 00389 } 00390 00391 int ResourceTrackerClass::totalMineralAtTime(int time) 00392 { 00393 return BWAPI::Broodwar->self()->minerals() + int((time - BWAPI::Broodwar->getFrameCount()) * mMineralRate); 00394 } 00395 00396 int ResourceTrackerClass::totalGasAtTime(int time) 00397 { 00398 return BWAPI::Broodwar->self()->gas() + int((time - BWAPI::Broodwar->getFrameCount()) * mGasRate); 00399 } 00400 00401 int ResourceTrackerClass::totalSupplyAtTime(int time) 00402 { 00403 int total = 0; 00404 for(std::map<int, int>::iterator i = mSupplyTime.begin(); i != mSupplyTime.end(); ++i) 00405 { 00406 if(i->first > time) 00407 break; 00408 else 00409 total += i->second; 00410 } 00411 00412 return total; 00413 }