BWAPI
|
00001 #include "ScoutManager.h" 00002 #include "BaseTracker.h" 00003 #include "TaskManager.h" 00004 #include "BuildOrderManager.h" 00005 #include "UnitTracker.h" 00006 #include "MapHelper.h" 00007 00008 void ScoutManagerClass::onBegin() 00009 { 00010 Base lastBase; 00011 std::set<Base> scoutBases; 00012 for each(Base base in BaseTracker::Instance().getAllBases()) 00013 { 00014 mLastScoutTime[base] = 1500; 00015 mLastScoutType[base] = ScoutType::None; 00016 mCurrentScoutType[base] = ScoutType::None; 00017 00018 if(base->isStartLocation()) 00019 { 00020 if(base->getPlayer() == BWAPI::Broodwar->self()) 00021 lastBase = base; 00022 else 00023 scoutBases.insert(base); 00024 } 00025 } 00026 00027 if(!lastBase) 00028 return; 00029 00030 while(!scoutBases.empty()) 00031 { 00032 Base closestBase; 00033 int distance = std::numeric_limits<int>::max(); 00034 for each(Base base in scoutBases) 00035 { 00036 int thisDistance = MapHelper::getGroundDistance(base->getCenterLocation(), lastBase->getCenterLocation()); 00037 if(thisDistance < distance) 00038 { 00039 distance = thisDistance; 00040 closestBase = base; 00041 } 00042 } 00043 00044 if(closestBase) 00045 { 00046 ScoutData newData = ScoutData(new ScoutDataClass(closestBase, ScoutType::InitialBaseLocationScout)); 00047 00048 mAllScoutData.insert(newData); 00049 mDataRequiringScout.push_back(newData); 00050 00051 mCurrentScoutType[closestBase] = ScoutType::InitialBaseLocationScout; 00052 00053 scoutBases.erase(closestBase); 00054 } 00055 00056 lastBase = closestBase; 00057 } 00058 } 00059 00060 void ScoutManagerClass::update() 00061 { 00062 int time = BWAPI::Broodwar->getFrameCount(); 00063 00064 bool performThoroughSearch = (BaseTracker::Instance().getEnemyBases().empty() && time > 4000); 00065 ScoutType scoutType = performThoroughSearch ? ScoutType::ThoroughSearch : ScoutType::BaseScout; 00066 00067 for each(Base base in BaseTracker::Instance().getAllBases()) 00068 { 00069 if(mCurrentScoutType[base] != ScoutType::None) 00070 continue; 00071 00072 // If we are doing thorough searches ignore last scout as we just need to find the enemy 00073 bool lastGroundFailed = mLastScoutType[base] == ScoutType::FailedWithGroundLow || mLastScoutType[base] == ScoutType::FailedWithGroundHigh || mLastScoutType[base] == ScoutType::CouldNotReachWithGround; 00074 if(performThoroughSearch && (lastGroundFailed || mLastScoutType[base] != ScoutType::FailedWithAir)) 00075 { 00076 mLastScoutType[base] = ScoutType::None; 00077 lastGroundFailed = false; 00078 } 00079 00080 int timeToReScout = 7000; 00081 if(lastGroundFailed) 00082 timeToReScout = 0; 00083 else if(performThoroughSearch && mLastScoutType[base] != scoutType && mCurrentScoutType[base] != scoutType) 00084 timeToReScout = 0; 00085 else if(performThoroughSearch && (base->isAllyBase() || base->isMyBase())) 00086 timeToReScout = 3500; 00087 else if(performThoroughSearch) 00088 timeToReScout = 1500; 00089 else if(mLastScoutType[base] != ScoutType::FailedWithAir) 00090 timeToReScout = 2000; 00091 else if(base->isEnemyBase()) 00092 timeToReScout = 3500; 00093 00094 if(mLastScoutTime[base] + timeToReScout <= time) 00095 { 00096 mLastScoutTime[base] = time; 00097 00098 ScoutData newData = ScoutData(new ScoutDataClass(base, scoutType)); 00099 00100 mAllScoutData.insert(newData); 00101 mDataRequiringScout.push_back(newData); 00102 00103 mCurrentScoutType[base] = scoutType; 00104 } 00105 } 00106 00107 for(std::set<ScoutData>::iterator it = mAllScoutData.begin(); it != mAllScoutData.end();) 00108 { 00109 (*it)->update(); 00110 00111 if((*it)->isAchieved()) 00112 { 00113 mCurrentScoutType[(*it)->getBase()] = ScoutType::None; 00114 mLastScoutType[(*it)->getBase()] = (*it)->getType(); 00115 mLastScoutTime[(*it)->getBase()] = time; 00116 mAllScoutData.erase(it++); 00117 } 00118 else 00119 ++it; 00120 } 00121 00122 for(std::list<ScoutData>::iterator it = mDataRequiringScout.begin(); it != mDataRequiringScout.end();) 00123 { 00124 //(*it)->drawDebug(BWAPI::Colors::Red); 00125 00126 if((*it)->isAchieved()) mDataRequiringScout.erase(it++); 00127 else ++it; 00128 } 00129 00130 updateObserverScouts(); 00131 updateWorkerScouts(); 00132 00133 // for each(Base base in BaseTracker::Instance().getAllBases()) 00134 // { 00135 // int x = base->getRegion()->getCenter().x(); 00136 // int y = base->getRegion()->getCenter().y(); 00137 // 00138 // BWAPI::Broodwar->drawTextMap(x, y, "Last Type: %s", ScoutType::getName(mLastScoutType[base].underlying()).c_str()); 00139 // BWAPI::Broodwar->drawTextMap(x, y+10, "This Type: %s", ScoutType::getName(mCurrentScoutType[base].underlying()).c_str()); 00140 // BWAPI::Broodwar->drawTextMap(x, y+20, "Time: %d", mLastScoutTime[base]); 00141 // } 00142 } 00143 00144 void ScoutManagerClass::updateWorkerScouts() 00145 { 00146 for(std::set<WorkerScoutTaskPointer>::iterator it = mWorkerScouts.begin(); it != mWorkerScouts.end();) 00147 { 00148 if((*it)->isFinishedScouting()) 00149 mWorkerScouts.erase(it++); 00150 else 00151 ++it; 00152 } 00153 00154 // use more workers the longer the game 00155 unsigned int maxForThisTime = !BuildOrderManager::Instance().getOrder(Order::Scout) ? 0 : BWAPI::Broodwar->getFrameCount() > 24*60*7 ? 2 : 1; 00156 00157 //BWAPI::Broodwar->drawTextScreen(5, 15, "Max Worker Scouts : %u", maxForThisTime); 00158 //BWAPI::Broodwar->drawTextScreen(5, 25, "Current Worker Scouts : %u", mWorkerScouts.size()); 00159 00160 // if we are short on tasks for workers, create some 00161 if(maxForThisTime > mWorkerScouts.size()) 00162 { 00163 ScoutData data = getScoutData(ScoutUnitType::Worker); 00164 00165 if(data) 00166 { 00167 WorkerScoutTaskPointer task = WorkerScoutTaskPointer(new WorkerScoutTask(TaskType::Scout, data)); 00168 mWorkerScouts.insert(task); 00169 00170 TaskManager::Instance().addTask(task); 00171 } 00172 } 00173 } 00174 00175 void ScoutManagerClass::updateObserverScouts() 00176 { 00177 for(std::set<ObserverScoutTaskPointer>::iterator it = mObserverScouts.begin(); it != mObserverScouts.end();) 00178 { 00179 if((*it)->hasEnded()) 00180 mObserverScouts.erase(it++); 00181 else 00182 ++it; 00183 } 00184 00185 unsigned int curreentObservers = UnitTracker::Instance().selectAllUnits(BWAPI::UnitTypes::Protoss_Observer).size(); 00186 unsigned int maxObservers = curreentObservers > 1 ? curreentObservers - 1 : 0; 00187 //BWAPI::Broodwar->drawTextScreen(5, 35, "Max Observer Scouts : %u", maxObservers); 00188 //BWAPI::Broodwar->drawTextScreen(5, 45, "Current Observer Scouts : %u", mObserverScouts.size()); 00189 00190 if(maxObservers > mObserverScouts.size()) 00191 { 00192 ScoutData data = getScoutData(ScoutUnitType::Observer); 00193 00194 ObserverScoutTaskPointer task = ObserverScoutTaskPointer(new ObserverScoutTask(TaskType::Scout, data)); 00195 mObserverScouts.insert(task); 00196 00197 TaskManager::Instance().addTask(task); 00198 } 00199 } 00200 00201 void ScoutManagerClass::updateLastScoutType(ScoutData data, ScoutType type) 00202 { 00203 mCurrentScoutType[data->getBase()] = ScoutType::None; 00204 mAllScoutData.erase(data); 00205 00206 mLastScoutTime[data->getBase()] = BWAPI::Broodwar->getFrameCount(); 00207 mLastScoutType[data->getBase()] = type; 00208 } 00209 00210 ScoutData ScoutManagerClass::getScoutData(ScoutUnitType unit) 00211 { 00212 for(std::list<ScoutData>::iterator it = mDataRequiringScout.begin(); it != mDataRequiringScout.end(); ++it) 00213 { 00214 const ScoutData data = *it; 00215 if(unit == ScoutUnitType::Worker) 00216 { 00217 if(data->getBase()->isEnemyBase() && BWAPI::Broodwar->getFrameCount() > 6000) 00218 continue; 00219 else if(mLastScoutType[data->getBase()] == ScoutType::CouldNotReachWithGround) 00220 continue; 00221 else if(mLastScoutType[data->getBase()] == ScoutType::FailedWithGroundHigh) 00222 continue; 00223 else if(mLastScoutType[data->getBase()] == ScoutType::FailedWithGroundLow && mLastScoutTime[data->getBase()] + 3500 > BWAPI::Broodwar->getFrameCount()) 00224 continue; 00225 } 00226 else if(unit == ScoutUnitType::Observer) 00227 { 00228 if(mLastScoutType[data->getBase()] == ScoutType::FailedWithAir) 00229 continue; 00230 } 00231 00232 mDataRequiringScout.erase(it); 00233 return data; 00234 } 00235 00236 return ScoutData(); 00237 }