Beispiel #1
0
        //returns true if finds leave nodes
        private static bool BuildTree(GoapRequest _request, GoapNode _parentNode, List <GoapNode> _leaves, List <I_GoapAction> _remainingActions, HashSet <string> _goalState)
        {
            bool foundSolution = false;

            for (int i = 0; i < _remainingActions.Count; i++)
            {
                planningData.goapAgent      = _request.owner;
                planningData.agentPositonXZ = _request.agentPos;

                _remainingActions[i].InitPlanning(planningData);

                //check if we can use this action
                if (_remainingActions[i].GetPreConditions().IsSubsetOf(_parentNode.currentState) && _remainingActions[i].IsProceduralConditionValid())
                {
                    //Debug.Log("Found valid action!");
                    //found an action, create node and build with build tree with remaining actions
                    GoapNode newNode = new GoapNode(_remainingActions[i]);
                    newNode.parent = _parentNode;
                    newNode.currentState.UnionWith(_parentNode.currentState);
                    newNode.currentState.UnionWith(_remainingActions[i].GetPostEffects());
                    newNode.runningCost = _parentNode.runningCost + _remainingActions[i].GetCost();



                    if (_goalState.IsSubsetOf(newNode.currentState))
                    {
                        //found a solution
                        foundSolution = true;
                        _leaves.Add(newNode);
                        //Debug.Log("Found a solution!");
                    }
                    else
                    {
                        List <I_GoapAction> remainingActions = new List <I_GoapAction>(_remainingActions);
                        remainingActions.RemoveAt(i); //remove used action

                        foundSolution = BuildTree(_request, newNode, _leaves, remainingActions, _goalState);
                    }
                }
            }


            return(foundSolution);
        }
Beispiel #2
0
        private static void ExecuteGoapRequest(GoapRequest _request)
        {
            //I_GoapAgent _agent, HashSet< string > _worldState, HashSet<string> _goalState, I_GoapActionSet _actionSet

            //Check is there an action which can just run on the current worldstate without building a tree?


            //sort by number of effects
            List <I_GoapAction> actions = new List <I_GoapAction>(_request.actions);

            ///////TODO!!! Sort by number of preconditions


            //this is returned
            List <I_GoapAction> acitonSequence = new List <I_GoapAction>();

            //check if one action can just satisfy

            /*for (int i = 0; i < actions.Count; i++)
             * {
             *  actions[i].ResetConditionCache();
             *  if (actions[i].GetPreConditions().IsSubsetOf(_worldState) && actions[i].IsProceduralConditionValid(_agent))
             *  {
             *      HashSet<string> newWorldState = new HashSet<string>();
             *      newWorldState.UnionWith(_worldState);
             *      newWorldState.UnionWith(actions[i].GetPostEffects());
             *
             *      if (_goalState.IsSubsetOf(newWorldState))
             *      {
             *          acitonSequence.Add(actions[i]);
             *          return acitonSequence;
             *      }
             *
             *  }
             * }*/


            List <GoapNode> leaves = new List <GoapNode>(); //leaves are the solutions

            GoapNode rootNode = new GoapNode(null, null, _request.worldState, 0);

            for (int i = 0; i < actions.Count; i++)
            {
                if (actions[i] == null)
                {
                    Debug.LogError("One of the ations is null!");
                }
                actions[i].ResetConditionCache();
            }


            bool success = BuildTree(_request, rootNode, leaves, actions, _request.goalState);


            if (success)
            {
                Debug.Log("Found solution");
            }


            //return goap actions with cheapest cost
            float smallestCost = float.MaxValue;
            int   index        = -1;

            // Debug.Log("found leaves: " + leaves.Count);
            for (int i = 0; i < leaves.Count; i++)
            {
                //Debug.Log("cost: " + leaves[i].runningCost);
                if (smallestCost > leaves[i].runningCost)
                {
                    index        = i;
                    smallestCost = leaves[i].runningCost;
                }
            }

            Debug.Log("Found Solutions: " + leaves.Count);

            if (leaves.Count > 0)
            {
                GoapNode currentNode = leaves[index];
                while (currentNode != null)
                {
                    if (currentNode.GetValue() != null)
                    {
                        I_GoapAction action = (I_GoapAction)currentNode.GetValue().Clone();
                        action.ActionHasBeenPicked();
                        acitonSequence.Insert(0, action);
                    }
                    currentNode = (GoapNode)currentNode.parent;
                }
            }

            //callback -> should be executed on the main thread if this is ever threaded!
            _request.callback?.Invoke(acitonSequence);
        }
 public GoapNode(I_GoapAction _value, GoapNode _parent, HashSet <string> _baseState, float _runningCost) : base(_value, _parent)
 {
     runningCost  = _runningCost;
     currentState = _baseState;
 }