Example #1
0
 private void Clear()
 {
     this.parent      = null;
     this.runningCost = 0;
     this.weight      = 0;
     this.state       = null;
     this.resources   = null;
     this.action      = null;
 }
Example #2
0
 public void ReInit(GoapNode parent, float runningCost, float weight, Dictionary <string, object> state, Dictionary <Int64, Int64> resources, GoapAction action)
 {
     Clear();
     this.parent      = parent;
     this.runningCost = runningCost;
     this.weight      = weight;
     this.state       = state;
     this.resources   = resources;
     this.action      = action;
 }
Example #3
0
 /// <summary>
 ///     compare node
 /// </summary>
 /// <param name="cheapest"></param>
 /// <returns></returns>
 public bool BetterThan(GoapNode rh)
 {
     return(runningCost < rh.runningCost);
     //if (weight > rh.weight && runningCost < rh.runningCost)
     //    return true;
     //if (weight < rh.weight && runningCost > rh.runningCost)
     //    return false;
     ////make weight > cost
     //var better = (weight / rh.weight - 1) >= (runningCost / rh.runningCost - 1);
     //return better;
 }
Example #4
0
        /**
         * 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.
         */
        private bool buildGraph(GoapNode parent, List <GoapNode> leaves, HashSet <GoapAction> usableActions, Dictionary <string, object> goal, Dictionary <Int64, Int64> resourceGoal)
        {
            bool foundOne = false;

            // go through each action available at this node 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
                    Dictionary <string, object> currentState     = populateState(parent.state, action.Effects);
                    Dictionary <Int64, Int64>   currentResources = populateResource(parent.resources, action.Resources);

                    // Console.WriteLine(GoapAgent.PrettyPrint(currentState));
                    GoapNode node = new GoapNode(parent, parent.runningCost + action.GetCost(), parent.weight + action.GetWeight(), currentState, currentResources, action);

                    if (inState(goal, currentState) && inResources(resourceGoal, currentResources))
                    {
                        // we found a solution!
                        leaves.Add(node);
                        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(node, leaves, subset, goal, resourceGoal);
                        if (found)
                        {
                            foundOne = true;
                        }
                    }
                }
            }

            return(foundOne);
        }
Example #5
0
        /**
         * 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.
         */
        public Queue <GoapAction> Plan(object agent, HashSet <GoapAction> availableActions, Dictionary <string, object> worldState, Dictionary <Int64, Int64> resourceState, Dictionary <string, object> goal, Dictionary <Int64, Int64> resourceGoal)
        {
            // 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.checkProceduralPrecondition(agent))
                {
                    usableActions.Add(a);
                }
            }

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

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

            // build graph
            GoapNode start   = new GoapNode(null, 0, 0, worldState, resourceState, null);
            bool     success = buildGraph(start, leaves, usableActions, goal, resourceGoal);

            if (!success)
            {
                // oh no, we didn't get a plan
                // Console.WriteLine("NO PLAN");
                return(null);
            }

            // get the cheapest leaf
            GoapNode cheapest = null;

            foreach (GoapNode leaf in leaves)
            {
                if (cheapest == null)
                {
                    cheapest = leaf;
                }
                else
                {
                    if (leaf.BetterThan(cheapest))
                    {
                        cheapest = leaf;
                    }
                }
            }

            // get its node and work back through the parents
            List <GoapAction> result = new List <GoapAction>();
            GoapNode          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);
        }
Example #6
0
 public GoapNode(GoapNode parent, float runningCost, float weight, Dictionary <string, object> state, Dictionary <Int64, Int64> resources, GoapAction action)
 {
     ID = MaxID++;
     ReInit(parent, runningCost, weight, state, resources, action);
 }