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