BWAPI
|
00001 #pragma once 00002 #include "../../../PerceptualState/Common.h" 00003 #include "../../../SituationAnalysis/Layer1GameState/Layer1GameState.h" 00004 #include "../../../SituationAnalysis/Layer2Cueing/Layer2Cueing.h" 00005 #include "../../Layer1Reactive/FSM/Layer1FSM.h" 00006 #include "../Layer2Actions.h" 00007 #include "ActionsImplementation/Common.h" 00008 #include "Locations/Common.h" 00009 #include "Layer2ManagersBase.h" 00010 #include "Layer2ManagersUnitData.h" 00011 #include <BWAPI.h> 00012 #include <boost/iterator/transform_iterator.hpp> 00013 00014 class Layer2Managers : public Layer2ManagersBase, public Layer2Actions<Layer2Cueing<Layer1GameState>, Layer1FSM> 00015 { 00016 public: 00017 static bool includedIn(Resources r1, Resources r2); 00018 00019 Layer2Managers(Layer2Cueing<Layer1GameState>& layer2Cueing, Layer1FSM& layer1FSM); 00020 ~Layer2Managers(); 00021 void onStart(); 00022 void onFrame(); 00023 void onEnd(); 00024 void onSendText(std::string text); 00025 00026 //void onActionExecuted(L2TacticalAction* action); 00027 //void onActionEnded(void* data); 00028 00029 void requestResources(unsigned int priority, const ActionResources& resources, ResourcesRequestID& id); 00030 void releaseResources(const Resources& resources); 00031 void cancelResourcesRequest(ResourcesRequestID& id); 00032 void changeResourcesRequestPriority(ResourcesRequestID& id, unsigned int newPriority); 00033 00035 // Requests // 00037 Resources getAvailableResources(unsigned int priority) const; 00038 Resources getLowestPriorityAvailableResources() const; 00039 Resources getHighestPriorityAvailableResources() const; 00040 size_t getNbAvailableBuildings(const BWAPI::UnitType buildingType, const StaticLocation& location) const; 00041 00042 static Layer2Managers& getInstance() 00043 { 00044 return *s_instance; 00045 } 00046 00047 DECLARE_EVENT(OnResourcesAllocated); 00048 00050 // GUI // 00052 //typedef std::list<L2TacticalAction*>::const_iterator ActionIterator; 00053 //std::pair<ActionIterator, ActionIterator> getCurrentActions() const 00054 //{ 00055 // return std::make_pair(m_currentActions.begin(), m_currentActions.end()); 00056 //} 00057 00058 00059 #pragma region Types_Matching 00060 // 00061 // Tactical action types matching 00062 // 00063 template <class DerivedTacticalActionType> 00064 struct TacticalActionTypes { 00065 }; 00066 template <> 00067 struct TacticalActionTypes<layer2::TacticalAction> { 00068 typedef L2TacticalAction Type; 00069 }; 00070 template <> 00071 struct TacticalActionTypes<layer2::GroupTacticalAction> { 00072 typedef L2GroupTacticalAction Type; 00073 }; 00074 template <> 00075 struct TacticalActionTypes<layer2::Attack> { 00076 typedef L2Attack Type; 00077 }; 00078 template <> 00079 struct TacticalActionTypes<layer2::AttackMove> { 00080 typedef L2AttackMove Type; 00081 }; 00082 template <> 00083 struct TacticalActionTypes<layer2::Build> { 00084 typedef L2Build Type; 00085 }; 00086 template <> 00087 struct TacticalActionTypes<layer2::CollectMinerals> { 00088 typedef L2CollectMinerals Type; 00089 }; 00090 template <> 00091 struct TacticalActionTypes<layer2::CollectGas> { 00092 typedef L2CollectGas Type; 00093 }; 00094 template <> 00095 struct TacticalActionTypes<layer2::Defend> { 00096 typedef L2Defend Type; 00097 }; 00098 template <> 00099 struct TacticalActionTypes<layer2::Expand> { 00100 typedef L2Expand Type; 00101 }; 00102 template <> 00103 struct TacticalActionTypes<layer2::Harass> { 00104 typedef L2Harass Type; 00105 }; 00106 template <> 00107 struct TacticalActionTypes<layer2::Move> { 00108 typedef L2Move Type; 00109 }; 00110 //template <> 00111 //struct TacticalActionTypes<layer2::OffensiveBuild> { 00112 // typedef L2OffensiveBuild Type; 00113 //}; 00114 template <> 00115 struct TacticalActionTypes<layer2::Recruit> { 00116 typedef L2Recruit Type; 00117 }; 00118 template <> 00119 struct TacticalActionTypes<layer2::UpgradeResearch> { 00120 typedef L2UpgradeResearch Type; 00121 }; 00122 template <> 00123 struct TacticalActionTypes<layer2::TechResearch> { 00124 typedef L2TechResearch Type; 00125 }; 00126 template <> 00127 struct TacticalActionTypes<layer2::Scout> { 00128 typedef L2Scout Type; 00129 }; 00130 00131 // 00132 // Location types matching 00133 // 00134 template <class LocationType> 00135 struct LocationTypes {}; 00136 template <> 00137 struct LocationTypes<AirLocation> { 00138 typedef L2AirLocation Type; 00139 }; 00140 template <> 00141 struct LocationTypes<BaseLocation> { 00142 typedef L2BaseLocation Type; 00143 }; 00144 template <> 00145 struct LocationTypes<Chokepoint> { 00146 typedef L2Chokepoint Type; 00147 }; 00148 template <> 00149 struct LocationTypes<Region> { 00150 typedef L2Region Type; 00151 }; 00152 template <> 00153 struct LocationTypes<RegionLocation> { 00154 typedef L2RegionLocation Type; 00155 }; 00156 template <> 00157 struct LocationTypes<Map> { 00158 typedef L2Map Type; 00159 }; 00160 #pragma endregion Types_Matching 00161 00162 typedef Layer2ManagersUnitData L2UnitData; 00163 00164 protected: 00165 static Layer2Managers* s_instance; 00166 00167 void reserveResource(const Resources& resources); 00168 00172 Resources m_reservedResources; 00173 00177 ResourcesRequestsType m_resourcesRequests; 00178 00182 unsigned int m_requestCounter; 00183 00187 //std::list<L2TacticalAction*> m_currentActions; 00188 00189 //EVENT_HANDLER(Layer2Managers, onActionEnded) m_actionEndedEventHandler; 00190 00191 struct UseResources 00192 { 00193 ResourcesRequestsType& m_resourcesRequests; 00194 Resources m_remainingResources; 00195 Layer2Managers* m_layer2; 00196 UseResources(ResourcesRequestsType& resourcesRequests, Resources remainingResource, Layer2Managers* layer2) 00197 : m_resourcesRequests(resourcesRequests) 00198 , m_remainingResources(remainingResource) 00199 , m_layer2(layer2) 00200 {} 00201 ResourcesRequestsType::FunctionReturn operator()(ResourcesRequest& request) 00202 { 00203 SafeMultisetBase::FunctionReturn result; 00204 00205 bool haveMineral = (request.actionResources.getMinerals() == 0 || request.actionResources.getMinerals() <= m_remainingResources.getMinerals()) && 00206 (request.actionResources.getGas() == 0 || request.actionResources.getGas() <= m_remainingResources.getGas()) && 00207 (request.actionResources.getSupply() == 0 || request.actionResources.getSupply() <= m_remainingResources.getSupply()); 00208 m_remainingResources -= request.actionResources.getResources(); 00209 00210 if(request.actionResources.getBuildingLocation() == NULL) 00211 { 00212 if(haveMineral) 00213 { 00214 m_layer2->reserveResource(request.actionResources.getResources()); 00215 request.resourcesId.eventHandler.onEvent(NULL, boost::tuples::tuple<BWAPI::Unit*>(NULL)); 00216 request.resourcesId.isValid = false; 00217 result.deleteCurrent = true; 00218 } 00219 } else { 00220 std::pair<StaticLocation::own_unit_type_const_iterator, StaticLocation::own_unit_type_const_iterator> buildingList = 00221 request.actionResources.getBuildingLocation()->getOwnUnits(request.actionResources.getBuildingType()); 00222 StaticLocation::own_unit_const_iterator buildingIt = buildingList.first; 00223 bool done = false; 00224 while(!done && buildingIt != buildingList.second) 00225 { 00226 BWAPI::Unit* unit = (*buildingIt)->getUnit(); 00227 Layer2ManagersUnitData& unitData = dynamic_cast<Layer2ManagersUnitData&>(Spar->getUnitManager().getUnitData(unit)); 00228 if(!unitData.isInUse() && 00229 (unitData.getLastRequestedFrame() < BWAPI::Broodwar->getFrameCount() || unitData.getLastRequestedPriority() <= request.priority) 00230 && unit->isCompleted() && !unit->isUnpowered()) 00231 { 00232 if(haveMineral) 00233 { 00234 done = true; 00235 unitData.setInUseFlag(true); 00236 m_layer2->reserveResource(request.actionResources.getResources()); 00237 request.resourcesId.eventHandler.onEvent(NULL, boost::tuples::make_tuple(unit)); 00238 request.resourcesId.isValid = false; 00239 result.deleteCurrent = true; 00240 } else { 00241 unitData.setLastRequestedFrame(BWAPI::Broodwar->getFrameCount()); 00242 unitData.setLastRequestedPriority(request.priority); 00243 } 00244 } 00245 ++buildingIt; 00246 } 00247 //TODO: 00248 // if(!done) 00249 // Notify Layer3 Action delayed no building available (+ Resources?) 00250 } 00251 00252 if(!haveMineral) { 00253 //TODO: Notify layer 3, Delayed action 00254 } 00255 return result; 00256 } 00257 }; 00258 00259 struct AvailableResourcesFunctor 00260 { 00261 unsigned int m_priority; 00262 Resources m_resources; 00263 AvailableResourcesFunctor(Resources baseResources, unsigned int priority) 00264 : m_resources(baseResources) 00265 , m_priority(priority) 00266 {} 00267 ResourcesRequestsType::ConstFunctionReturn AvailableResourcesFunctor::operator()(const ResourcesRequest& request) 00268 { 00269 ResourcesRequestsType::ConstFunctionReturn result = ResourcesRequestsType::ConstFunctionReturn(); 00270 if(m_priority > request.priority) 00271 result.breakIteration = true; 00272 else 00273 m_resources -= request.actionResources.getResources(); 00274 00275 return result; 00276 } 00277 }; 00278 00279 struct ClearResourcesRequestsFunctor 00280 { 00281 ResourcesRequestsType::FunctionReturn ClearResourcesRequestsFunctor::operator()(const ResourcesRequest& request) 00282 { 00283 unused(request); 00284 return ResourcesRequestsType::FunctionReturn(true,false); 00285 } 00286 }; 00287 00288 };