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