BWAPI
SPAR/AIModule/SparAIModule/DecisionMaking/Layer2Actions/Managers/Layer2Managers.h
Go to the documentation of this file.
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 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines