BWAPI
Skynet/Skynet/ResourceTracker.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines