コード例 #1
0
 public BrachNode(BrachNode _parent, float _runningCost, HashSet <KeyValuePair <string, object> > _state, GOAPAction _action)
 {
     parent      = _parent;
     runningCost = _runningCost;
     state       = _state;
     action      = _action;
 }
コード例 #2
0
        /// <summary>
        /// Returns true if at least one solution was found.
        /// The possible paths are stored in the leaves list. Each leaf has a
        /// 'runningCost' value where the lowest cost will be the best action
        /// sequence.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="leaves"></param>
        /// <param name="usableActions"></param>
        /// <param name="goal"></param>
        /// <returns></returns>
        private bool BuildGraph(BrachNode parent, List <BrachNode> leaves, HashSet <GOAPAction> usableActions, HashSet <KeyValuePair <string, object> > goal)
        {
            bool foundOne = false;

            // go through each action available at this BrachNode and see if we can use it here
            foreach (GOAPAction action in usableActions)
            {
                // if the parent state has the conditions for this action's preconditions, we can use it here
                if (InState(action.Preconditions, parent.state))
                {
                    // apply the action's effects to the parent state
                    HashSet <KeyValuePair <string, object> > currentState = PopulateState(parent.state, action.Effects);
                    //Debug.Log(GoapAgent.prettyPrint(currentState));
                    BrachNode BrachNode = new BrachNode(parent, parent.runningCost + action.cost, currentState, action);

                    if (InState(goal, currentState))
                    {
                        // we found a solution!
                        leaves.Add(BrachNode);
                        foundOne = true;
                    }
                    else
                    {
                        // not at a solution yet, so test all the remaining actions and branch out the tree
                        HashSet <GOAPAction> subset = ActionSubset(usableActions, action);
                        bool found = BuildGraph(BrachNode, leaves, subset, goal);
                        if (found)
                        {
                            foundOne = true;
                        }
                    }
                }
            }

            return(foundOne);
        }
コード例 #3
0
        /// <summary>
        /// Plan what sequence of actions can fulfill the goal.
        /// Returns null if a plan could not be found, or a list of the actions
        /// that must be performed, in order, to fulfill the goal.
        /// </summary>
        /// <param name="agent"></param>
        /// <param name="availableActions"></param>
        /// <param name="worldState"></param>
        /// <param name="goal"></param>
        /// <returns></returns>
        public Queue <GOAPAction> Plan(GameObject agent,
                                       HashSet <GOAPAction> availableActions,
                                       HashSet <KeyValuePair <string, object> > worldState,
                                       HashSet <KeyValuePair <string, object> > goal)
        {
            // reset the actions so we can start fresh with them
            foreach (GOAPAction a in availableActions)
            {
                a.DoReset();
            }

            // check what actions can run using their checkProceduralPrecondition
            HashSet <GOAPAction> usableActions = new HashSet <GOAPAction>();

            foreach (GOAPAction a in availableActions)
            {
                if (a.CheckProcPreconditions(agent))
                {
                    usableActions.Add(a);
                }
            }

            // we now have all actions that can run, stored in usableActions

            // build up the tree and record the leaf BrachNodes that provide a solution to the goal.
            List <BrachNode> leaves = new List <BrachNode>();

            // build graph
            BrachNode start   = new BrachNode(null, 0, worldState, null);
            bool      success = BuildGraph(start, leaves, usableActions, goal);

            if (!success)
            {
                // oh no, we didn't get a plan
//                Debug.LogWarning("NO plan was found for " + agent.name);
                return(null);
            }

            // get the cheapest leaf
            BrachNode cheapest = null;

            foreach (BrachNode leaf in leaves)
            {
                if (cheapest == null)
                {
                    cheapest = leaf;
                }
                else
                {
                    if (leaf.runningCost < cheapest.runningCost)
                    {
                        cheapest = leaf;
                    }
                }
            }

            // get its BrachNode and work back through the parents
            List <GOAPAction> result = new List <GOAPAction>();
            BrachNode         n      = cheapest;

            while (n != null)
            {
                if (n.action != null)
                {
                    result.Insert(0, n.action); // insert the action in the front
                }
                n = n.parent;
            }
            // we now have this action list in correct order

            Queue <GOAPAction> queue = new Queue <GOAPAction>();

            foreach (GOAPAction a in result)
            {
                queue.Enqueue(a);
            }

            // hooray we have a plan!
            return(queue);
        }