BWAPI
|
00001 #include "ResourceManager.h" 00002 #include "BaseTracker.h" 00003 #include "TaskManager.h" 00004 #include "GatherTask.h" 00005 #include "ResourceTracker.h" 00006 #include "BuildOrderManager.h" 00007 #include "UnitTracker.h" 00008 00009 ResourceManagerClass::ResourceManagerClass() 00010 : mTaskPump(BWAPI::Broodwar->self()->getRace().getWorker(), TaskType::Worker) 00011 , mSaturated(false) 00012 , mGasLevel(0) 00013 , mTimeAllowGasChange(0) 00014 { 00015 } 00016 00017 void ResourceManagerClass::update() 00018 { 00019 std::set<Base> bases = BaseTracker::Instance().getActiveBases(true); 00020 if(mMyActiveBases != bases) 00021 { 00022 for each(Base base in mMyActiveBases) 00023 { 00024 std::set<Base>::iterator it = bases.find(base); 00025 if(it == bases.end()) 00026 { 00027 for(std::map<Unit, GatherTaskPointer>::iterator resourceIT = mResourceTasks[base].begin(); resourceIT != mResourceTasks[base].end(); ++resourceIT) 00028 resourceIT->second->cancel(); 00029 00030 mResourceTasks.erase(base); 00031 } 00032 } 00033 00034 mMyActiveBases = bases; 00035 } 00036 00037 unsigned int neededWorkers = 0; 00038 for each(Base base in mMyActiveBases) 00039 { 00040 if(!base->getResourceDepot() || !base->getResourceDepot()->exists()) 00041 continue; 00042 00043 const UnitGroup &minerals = base->getMinerals(); 00044 const UnitGroup &refineries = base->getRefineries(); 00045 00046 for(std::map<Unit, GatherTaskPointer>::iterator resourceIT = mResourceTasks[base].begin(); resourceIT != mResourceTasks[base].end();) 00047 { 00048 if(minerals.count(resourceIT->first) == 0 && refineries.count(resourceIT->first) == 0) 00049 { 00050 resourceIT->second->cancel(); 00051 mResourceToBase.erase(resourceIT->first); 00052 mResourceTasks[base].erase(resourceIT++); 00053 } 00054 else 00055 ++resourceIT; 00056 } 00057 00058 for each(Unit mineral in minerals) 00059 { 00060 neededWorkers += 2; 00061 if(mResourceTasks[base].count(mineral) == 0) 00062 { 00063 GatherTaskPointer gatherTask(new GatherTask(mineral, base)); 00064 TaskManager::Instance().addTask(gatherTask); 00065 mResourceTasks[base][mineral] = gatherTask; 00066 mResourceToBase[mineral] = base; 00067 } 00068 } 00069 00070 for each(Unit refinery in refineries) 00071 { 00072 if(refinery->getPlayer() == BWAPI::Broodwar->self()) 00073 { 00074 neededWorkers += 3; 00075 if(mResourceTasks[base].count(refinery) == 0 && refinery->exists()) 00076 { 00077 GatherTaskPointer gatherTask(new GatherTask(refinery, base)); 00078 TaskManager::Instance().addTask(gatherTask); 00079 mResourceTasks[base][refinery] = gatherTask; 00080 mResourceToBase[refinery] = base; 00081 } 00082 } 00083 } 00084 } 00085 00086 if(!BuildOrderManager::Instance().getOrder(Order::TrainWorkers)) 00087 neededWorkers = 0; 00088 00089 unsigned int numWorkers = UnitTracker::Instance().selectAllUnits(BWAPI::Broodwar->self()->getRace().getWorker()).size(); 00090 00091 mSaturated = numWorkers >= neededWorkers; 00092 00093 neededWorkers = std::min(neededWorkers, 50u); 00094 neededWorkers -= std::min(numWorkers, neededWorkers); 00095 neededWorkers = std::min(neededWorkers, UnitTracker::Instance().selectAllUnits(BWAPI::Broodwar->self()->getRace().getWorker().whatBuilds().first).size() + 1); 00096 00097 mTaskPump.changeTargetQuantity(neededWorkers); 00098 mTaskPump.update(); 00099 00100 double mineralRate = 0; 00101 double gasRate = 0; 00102 for(std::map<Base, std::map<Unit, GatherTaskPointer>>::iterator it = mResourceTasks.begin(); it != mResourceTasks.end(); ++it) 00103 { 00104 for(std::map<Unit, GatherTaskPointer>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) 00105 { 00106 mineralRate += it2->second->getMineralRate(); 00107 gasRate += it2->second->getGasRate(); 00108 } 00109 } 00110 00111 ResourceTracker::Instance().setMineralRate(mineralRate); 00112 ResourceTracker::Instance().setGasRate(gasRate); 00113 00114 int futureMinerals = ResourceTracker::Instance().availableMineralAtTime(BWAPI::Broodwar->getFrameCount() + 450); 00115 int futureGas = ResourceTracker::Instance().availableGasAtTime(BWAPI::Broodwar->getFrameCount() + 450); 00116 00117 if(mTimeAllowGasChange < BWAPI::Broodwar->getFrameCount()) 00118 { 00119 int newLevel = 0; 00120 if(UnitTracker::Instance().selectAllUnits(BWAPI::Broodwar->self()->getRace().getRefinery()).size() == 0) 00121 newLevel = 8; 00122 else if(futureMinerals != 0) 00123 { 00124 float ratio = float(futureGas) / float(futureMinerals); 00125 00126 if(ratio > 2.5f) 00127 newLevel = 0; 00128 else if(ratio > 1.9f) 00129 newLevel = 1; 00130 else if(ratio > 1.3f) 00131 newLevel = 2; 00132 else if(ratio > 1.0f) 00133 newLevel = 3; 00134 else if(ratio > 0.95f) 00135 newLevel = 4; 00136 else if(ratio > 0.9f) 00137 newLevel = 5; 00138 else if(ratio > 0.85f) 00139 newLevel = 6; 00140 else if(ratio > 0.4f) 00141 newLevel = 7; 00142 else 00143 newLevel = 8; 00144 } 00145 00146 if(mGasLevel != newLevel) 00147 { 00148 mTimeAllowGasChange = BWAPI::Broodwar->getFrameCount() + 24; 00149 if(mGasLevel > newLevel) 00150 --mGasLevel; 00151 else if(newLevel > mGasLevel) 00152 ++mGasLevel; 00153 } 00154 } 00155 } 00156 00157 void ResourceManagerClass::onDestroy(Unit unit) 00158 { 00159 std::map<Unit, Base>::iterator baseIT = mResourceToBase.find(unit); 00160 if(baseIT != mResourceToBase.end()) 00161 { 00162 std::map<Unit, GatherTaskPointer>::iterator resourceIT = mResourceTasks[baseIT->second].find(unit); 00163 if(resourceIT != mResourceTasks[baseIT->second].end()) 00164 { 00165 resourceIT->second->cancel(); 00166 mResourceTasks[baseIT->second].erase(unit); 00167 mResourceToBase.erase(baseIT); 00168 } 00169 } 00170 }