BWAPI
|
00001 #include "RequirementGroup.h" 00002 00003 #include <assert.h> 00004 00005 RequirementGroup::RequirementGroup() 00006 { 00007 } 00008 00009 std::pair<int, int> RequirementGroup::earliestTime() 00010 { 00011 int latestTime = BWAPI::Broodwar->getFrameCount(); 00012 00013 // Loop through all normal requirements 00014 for(std::vector<Requirement>::iterator requirement = mOtherRequirements.begin(); requirement != mOtherRequirements.end(); ++requirement) 00015 { 00016 assert(!requirement->unitRequirement()); 00017 00018 // If the easliest time this requirement is ready is the latest yet, save it 00019 int thisTime = requirement->earliestTime(); 00020 if(thisTime > latestTime) 00021 latestTime = thisTime; 00022 } 00023 00024 // Recurse through unit requirements 00025 std::set<Unit> units; 00026 if(recurseForUnitTime(latestTime, mUnitRequirements.begin(), latestTime, Requirement::maxTime, units)) 00027 { 00028 int biggestDelay = 0; 00029 // now loop through to find any delay in the execution 00030 for(std::vector<Requirement>::iterator requirement = mUnitRequirements.begin(); requirement != mUnitRequirements.end(); ++requirement) 00031 { 00032 int thisDelay = requirement->getDelay(); 00033 if(thisDelay > biggestDelay) 00034 biggestDelay = thisDelay; 00035 } 00036 00037 return std::make_pair(latestTime, biggestDelay); 00038 } 00039 00040 // if it didn't find a time, just return 00041 return std::make_pair(Requirement::maxTime, 0); 00042 } 00043 00044 bool RequirementGroup::recurseForUnitTime(int &latestTime, std::vector<Requirement>::iterator currentRequirement, int currentStartTime, int currentEndTime, std::set<Unit> ¤tUnits) 00045 { 00046 // If we have reached the end we have found a time, save it and return 00047 if(currentRequirement == mUnitRequirements.end()) 00048 { 00049 latestTime = currentStartTime; 00050 return true; 00051 } 00052 00053 assert(currentRequirement->unitRequirement()); 00054 00055 // get a selection of free times for this requirement 00056 const std::map<int, int> &unitTimes = currentRequirement->earliestUnitTime(currentStartTime, currentEndTime, currentUnits); 00057 00058 // For each one 00059 for(std::map<int, int>::const_iterator it = unitTimes.begin(); it != unitTimes.end(); ++it) 00060 { 00061 currentUnits.insert(currentRequirement->getUnit()); 00062 00063 int newEndTime = it->second; 00064 if(newEndTime != Requirement::maxTime) 00065 newEndTime += it->first; 00066 00067 // go to the next requirement with these times to see if it is suitable for the rest too 00068 if(recurseForUnitTime(latestTime, ++(std::vector<Requirement>::iterator(currentRequirement)), it->first, newEndTime, currentUnits)) 00069 return true; 00070 00071 currentUnits.erase(currentRequirement->getUnit()); 00072 } 00073 00074 return false; 00075 } 00076 00077 bool RequirementGroup::operator==(const RequirementGroup& other) const 00078 { 00079 if(mOtherRequirements == other.mOtherRequirements) 00080 return mUnitRequirements == other.mUnitRequirements; 00081 00082 return false; 00083 } 00084 00085 bool RequirementGroup::operator<(const RequirementGroup& other) const 00086 { 00087 if(mOtherRequirements < other.mOtherRequirements) 00088 return true; 00089 00090 return mUnitRequirements < other.mUnitRequirements; 00091 } 00092 00093 bool RequirementGroup::empty() const 00094 { 00095 if(!mOtherRequirements.empty()) 00096 return false; 00097 00098 return mUnitRequirements.empty(); 00099 } 00100 00101 void RequirementGroup::clear() 00102 { 00103 mOtherRequirements.clear(); 00104 mUnitRequirements.clear(); 00105 } 00106 00107 UnitGroup RequirementGroup::getUnits() const 00108 { 00109 UnitGroup units; 00110 for(std::vector<Requirement>::const_iterator requirement = mUnitRequirements.begin(); requirement != mUnitRequirements.end(); ++requirement) 00111 units.insert(requirement->getUnit()); 00112 00113 return units; 00114 } 00115 00116 void RequirementGroup::reserve(int time) 00117 { 00118 for(std::vector<Requirement>::iterator requirement = mOtherRequirements.begin(); requirement != mOtherRequirements.end(); ++requirement) 00119 requirement->reserve(time); 00120 00121 for(std::vector<Requirement>::iterator requirement = mUnitRequirements.begin(); requirement != mUnitRequirements.end(); ++requirement) 00122 requirement->reserve(time); 00123 } 00124 00125 void RequirementGroup::addUnitFilterRequirement(int priority, int duration, UnitFilter unitFilter, int quantity, Position position) 00126 { 00127 for(int i = 0; i < quantity; ++i) 00128 addUnitFilterRequirement(priority, duration, unitFilter, position); 00129 }