BWAPI
SPAR/AIModule/SparAIModule/DecisionMaking/Layer1Reactive/FSM/Behaviors/Move.h
Go to the documentation of this file.
00001 #pragma once
00002 #include "../GroupBehavior.h"
00003 #include "../BehaviorState.h"
00004 
00008 class Move : public GroupBehavior<Move>
00009 {
00010 protected:
00011   class Goto;
00012   friend class Goto;
00013 
00014   class Goto : public BehaviorState<Move, Goto>
00015   {
00016   public:
00017     Goto(Move& behavior, size_t refreshDelay);
00018     void onEnterImpl();
00019     void onExitImpl()
00020     {}
00021 
00022     void onUnitAddedToGroup(BWAPI::Unit* unit);
00023     void onUnitRemovedFromGroup(BWAPI::Unit* unit);
00024 
00025     void onTimer()
00026     {
00027       ++m_tickCounter;
00028 
00029       std::set<BWAPI::Unit*>::iterator nextIt;
00030       std::set<BWAPI::Unit*>::iterator it = m_context.unitsInMotion.begin();
00031       
00032       std::set<BWAPI::Unit*>::iterator toDelete = m_context.unitsInMotion.end();
00033       
00034       while(it != m_context.unitsInMotion.end())
00035       {
00036         nextIt = it;
00037         ++nextIt;
00038 
00039         BWAPI::Position toDelete2 = (*it)->getPosition();
00040         if((*it)->getPosition().getApproxDistance(m_context.m_destination) <= static_cast<int>(m_context.m_maxDistance))
00041         {
00042           BWAPI::Unit* unit = *it;
00043           m_context.unitsInMotion.erase(it);
00044           m_context.unitsAtDestination.insert(unit);
00045           m_context.getUnitAtDestinationEvent().raise(unit);
00046         }
00047         it = nextIt;
00048       }
00049 
00050       if(m_tickCounter >= m_context.m_nbTickBetweenAction)
00051       {
00052         m_tickCounter = 0;
00053         Layer1FSM::getInstance().getArbitrator().submitAction(m_context.getGroup(), m_moveAction, Arbitration::ActionImportance(*this));
00054       }
00055     }
00056 
00057     typedef SCHEDULER_EVENT(Goto, onTimer) TimerEvent;
00058 
00059     typedef boost::tuple<
00060       TimerEvent&
00061     > Events;
00062     const Events m_events;
00063 
00064     typedef boost::tuple<> Transitions;
00065                 const Transitions m_transitions;
00066 
00067   protected:
00068     // Variables
00069     size_t m_tickCounter;
00070 
00071     // Actions
00072     layer1::MoveAction m_moveAction;
00073 
00074     // Transitions
00075     TimerEvent m_timerEvent;
00076   };
00077 
00078 public:
00087   Move(const Process* parent, unsigned int initialPriority, const PersistentUnitGroup* group,
00088     BWAPI::Position destination, size_t maxDistance = 128, size_t refreshRate = 24, size_t nbTickBetweenAction = 1)
00089     : GroupBehavior(parent, initialPriority, group)
00090     , IGroupBehavior(parent, initialPriority, group)
00091     , IBehavior(parent, initialPriority)
00092     , IFSM(parent)
00093     , Process(parent)
00094     , m_gotoState(*this, refreshRate)
00095     , m_destination(destination)
00096     , m_destinationTP(destination.x()/TILE_SIZE, destination.y()/TILE_SIZE)
00097     , m_states(m_gotoState)
00098     , m_nbTickBetweenAction(nbTickBetweenAction)
00099     , m_maxDistance(maxDistance)
00100   { }
00101 
00110   Move(const Process* parent, unsigned int initialPriority, const PersistentUnitGroup* group,
00111     BWAPI::TilePosition destination, size_t maxDistance = 128, size_t refreshRate = 24, size_t nbTickBetweenAction = 1)
00112     : GroupBehavior(parent, initialPriority, group)
00113     , IGroupBehavior(parent, initialPriority, group)
00114     , IBehavior(parent, initialPriority)
00115     , IFSM(parent)
00116     , Process(parent)
00117     , m_gotoState(*this, refreshRate)
00118     , m_destination(destination.x()*TILE_SIZE + TILE_SIZE/2, destination.y()*TILE_SIZE + TILE_SIZE/2)
00119     , m_destinationTP(destination)
00120     , m_states(m_gotoState)
00121     , m_nbTickBetweenAction(nbTickBetweenAction)
00122     , m_maxDistance(maxDistance)
00123   { }
00124   
00125   virtual std::string getName() const
00126   {
00127     return "Moving at " + getObjectDescription(m_destination);//.x() + ", " + m_destination.y();
00128   }
00129 
00130   virtual void onUnitAddedToGroup(void*, BWAPI::Unit* unit)
00131   {
00132     assert(!unit->getType().isBuilding());
00133     if(m_currentState == &m_gotoState)
00134       m_gotoState.onUnitAddedToGroup(unit);
00135   }
00136 
00137   virtual void onUnitRemovedFromGroup(void*, BWAPI::Unit* unit)
00138   {
00139     if(m_currentState == &m_gotoState)
00140       m_gotoState.onUnitRemovedFromGroup(unit);
00141     if(getGroup()->empty())
00142       terminate(Success);
00143   }
00144 
00145   typedef boost::tuple<
00146       Goto&
00147     > States;
00148         const States m_states;
00149 
00150   DECLARE_EVENT1(OnUnitAtDestination, BWAPI::Unit*);
00151   OnUnitAtDestination& getUnitAtDestinationEvent() const { return m_unitAtDestination; }
00152   EVENT(OnUnitAtDestination) m_unitAtDestination;
00153 
00154 protected:
00155   virtual void executeImpl()
00156   {
00157     GroupBehavior::executeImpl();
00158     m_gotoState.onEnter();
00159   }
00160 
00161   Goto m_gotoState;
00162 
00163   BWAPI::Position m_destination;
00164   BWAPI::TilePosition m_destinationTP;
00165   const size_t m_nbTickBetweenAction;
00166   const size_t m_maxDistance;
00167 
00168   //TODO: Change to safeSet
00169   std::set<BWAPI::Unit*> unitsInMotion;
00170   std::set<BWAPI::Unit*> unitsAtDestination;
00171 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines