title: How do I define my pool of Actions in such a way that they depend on variables in GOAP?
body: <p>I'm attempting to implement GOAP in my game. The game is a simulation-type game that would not only benefit from GOAP, but is almost essentially a requirement based on the scope of what an agent can do.</p>
  
  <p>I have the following code. There's no planner in here, just the definitions of Actions, State etc</p>
  
  <pre><code>#include &lt;vector&gt;
  #include &lt;string&gt;
  #include &lt;unordered_map&gt;
  
  class Condition
  {
  public:
  
      bool operator()(const int value) const
      {
          return m_min &lt;= value &amp;&amp; value &lt;= m_max;
      }
  
      enum class OP : std::uint8_t
      {
          EE, LT, GT, LE, GE
      };
  
      Condition(const int min, const int max, const OP op)
      :
          m_op(op),
          m_min(min),
          m_max(max)
      {}
  
      static Condition CreateEE(const int goal)
      {
          return Condition(goal, goal, OP::EE);
      }
  
      static Condition CreateGT(const int goal)
      {
          return Condition(goal+1, std::numeric_limits&lt;int&gt;::max(), OP::GT);
      }
  
      static Condition CreateLT(const int goal)
      {
          return Condition(std::numeric_limits&lt;int&gt;::min(), goal-1, OP::LT);
      }
  
      static Condition CreateGE(const int goal)
      {
          return Condition(goal, std::numeric_limits&lt;int&gt;::max(), OP::GT);
      }
  
      static Condition CreateLE(const int goal)
      {
          return Condition(std::numeric_limits&lt;int&gt;::min(), goal, OP::LT);
      }
  
  private:
  
      OP m_op;
      int m_min;
      int m_max;
  };
  
  class Effect
  {
  public:
  
      enum class OP : std::uint8_t
      {
          ADD, SUB, MUL, DIV, EQ
      };
  
      Effect(OP op, int value)
      :
          m_op(op),
          m_value(value)
      {
  
      }
  
  protected:
      OP m_op;
      int m_value;
  };
  
  class Action
  {
  public:
      void AddPrereq(const std::string&amp; name, Condition value)
      {
          m_prereqs.emplace_back(name,value);
      }
  
      void AddEffect(const std::string&amp; name, Effect effect)
      {
          m_effects.emplace_back(name,effect);
      }
  
      void SetCost(const float cost)
      {
          m_cost = cost;
      }
  
  private:
  
      float m_cost;
  
      std::vector&lt;std::pair&lt;std::string,Condition&gt;&gt; m_prereqs;
      std::vector&lt;std::pair&lt;std::string,Effect&gt;&gt; m_effects;
  };
  
  class WorldState
  {
  public:
  
      void AddFact(const std::string&amp; name, const int value)
      {
          m_facts[name] = value;
      }
  
  private:
  
      std::unordered_map&lt;std::string,int&gt; m_facts;
  };
  
  class GoalState
  {
  public:
  
      void AddCondition(const std::string&amp; name, const Condition condition)
      {
          m_conditions.emplace_back(name, condition);
      }
  
  private:
      std::vector&lt;std::pair&lt;std::string,Condition&gt;&gt; m_conditions;
  };
  
  int main()
  {
      Action goTo;
      goTo.AddEffect("isAtPosition", Effect(Effect::OP::EQ, 1));
  
      Action pickUp;
      pickUp.AddPrereq("isAtPosition", Condition::CreateEE(1));
      pickUp.AddEffect("itemInPossession", Effect(Effect::OP::EQ, 1));
  
      Action drop;
      drop.AddPrereq("itemInPossession", Condition::CreateEE(1));
      drop.AddEffect("itemAtPosition", Effect(Effect::OP::EQ, 1));
  
      WorldState ws;
      ws.AddFact("itemAtPosition", 0);
  
      GoalState gs;
      gs.AddCondition("itemAtPosition", Condition::CreateGE(1));
  
      return 0;
  }
  </code></pre>
  
  <p>For now I'm just using boolean values, because for my test-case, it's about the agent moving to a position, picking up an item, and moving it to another position. Later on, a goal might be to move <em>n</em> items or something.</p>
  
  <p>Actions would be:</p>
  
  <ol>
  <li>Goto (puts agent in position)</li>
  <li>PickUp (puts item in possession)</li>
  <li>Goto (puts agent in position)</li>
  <li>Drop (puts item in location) Goal Met!</li>
  </ol>
  
  <p>But how do I use the <code>Goto</code> action here twice? It's effect is the same, setting the "isAtPosition" variable. Would I need to create a new state variable for "isAtItemPosition" vs "isAtDestinationPosition"?</p>
  
  <p>Because that seems like I would be effectively crafting specific Actions for each possible Goal, with the effect of me determining all the possible sequences of Actions.</p>
  
  <p>How do I encode the state information in such a way that the same actions from the pool can be applied at different stages, having a different effect? (Goto the item position vs goto the destination position).</p>