Exemple #1
0
            public string PathToString()
            {
                var node = this;
                var s    = string.Empty;

                while (node.parent != null)
                {
                    s    = GoapAgent.PrettyPrint(node.action) + ">" + s;
                    node = node.parent;
                }
                return(s);
            }
Exemple #2
0
            public static WithContext Borrow(GoapAction action, GoapAgent agent, IStateful target)
            {
                var actionWithContext = pool.Borrow();

                actionWithContext.actionData = action;
                actionWithContext.agent      = agent;
                actionWithContext.target     = target;
                actionWithContext.startTime  = 0;
                actionWithContext.isInRange  = false;
                actionWithContext.isDone     = false;
                return(actionWithContext);
            }
        protected virtual bool CanDoNow(GoapAgent agent, IStateful target)
        {
            var worldState = WorldState.pool.Borrow();

            worldState.Clear();
            worldState[agent]  = agent.GetState();
            worldState[target] = target.GetState();
            var  conditions = GetDependentPreconditions(agent, target);
            bool result     = GoapPlanner.DoConditionsApplyToWorld(conditions, worldState);

            WorldState.pool.Return(worldState);
            return(result);
        }
Exemple #4
0
        protected virtual bool CanDoNow(GoapAgent agent, IStateful target)
        {
            var worldState = WorldState.Borrow();

            worldState[agent]  = agent.GetState();
            worldState[target] = target.GetState();
            // Since the action is a part of the plan, its preconditions on the agent
            // should apply.
            var doesApply = worldState.IsGoalState(GetIndependentPreconditions(agent));

            // NOTE: If the agent's state is volatile and can change outside of the
            // agent's plan, comment out this assertion.
            DebugUtils.AssertWarning(
                doesApply,
                "WARNING: Possible bug in definition of " + name
                + ". The agent " + agent.name + " planned to do it but now its state does not allow it");
            // Need to check that the target's state still apply to the preconditions
            // defined by the action.
            doesApply = doesApply && worldState.IsGoalState(GetDependentPreconditions(agent, target));
            worldState.ReturnSelf();
            return(doesApply);
        }
Exemple #5
0
            /// <summary>
            /// Run the action.
            /// Returns True if the action performed successfully or false if
            /// something happened and it can no longer perform. In this case the
            /// action queue should clear out and the goal cannot be reached.
            /// </summary>
            public bool Perform(GoapAgent agent)
            {
                if (Mathf.Approximately(startTime, 0f))
                {
                    if (!actionData.CanDoNow(agent, target))
                    {
                        return(false);
                    }
                    startTime = Time.time;
                }

                if (Time.time - startTime > actionData.workDuration)
                {
                    if (!actionData.CanDoNow(agent, target))
                    {
                        return(false);
                    }
                    DebugUtils.Log(GetType().Name + " Time is up - am I done?");
                    return(actionData.OnDone(agent, this));
                }
                return(true);
            }
        // Create possible previous goal (before this actionwas made)
        public WorldGoal reverseApplyToWorldGoal(WorldGoal goal)
        {
            WorldGoal newGoal = new WorldGoal(goal);              //this is deep copied, see c'tor

            foreach (KeyValuePair <IStateful, Goal> agentGoal in goal)
            {
                GoapAgent     currAgent   = (GoapAgent)agentGoal.Key;
                Goal          currGoal    = agentGoal.Value;
                Goal          updatedGoal = this.effects.reverseApplyEffectsToGoal(currGoal);
                List <string> keys        = new List <string> (updatedGoal.Keys);
                foreach (string k in keys)
                {
                    if (updatedGoal [k] == null)
                    {
                        updatedGoal.Remove(k);
                    }
                }

                if (newGoal.ContainsKey(currAgent))
                {
                    newGoal [currAgent] = updatedGoal;
                }
                else
                {
                    newGoal.Add(currAgent, updatedGoal);
                }

                // Add target preconditions to new goal
                foreach (KeyValuePair <string, Condition> kvp in this.preconditions)
                {
                    if (!newGoal [currAgent].ContainsKey(kvp.Key))
                    {
                        newGoal [currAgent].Add(kvp.Key, new Condition(kvp.Value.comparison, kvp.Value.value));
                    }
                }
            }

            return(newGoal);
        }
Exemple #7
0
        /// <summary>
        /// A* forward search for a plan that satisfies the given goal.
        /// </summary>
        /// <returns>Returns null if a plan could not be found, or a list of the
        /// actions that must be performed, in order.</returns>
        public static Queue <ITransition> Plan(
            GoapAgent agent,
            WorldGoal goal)
        {
            var worldState = WorldState.Borrow();

            worldState[agent] = agent.GetState();

            DebugUtils.Assert(worldState[agent].ContainsKey("x") &&
                              worldState[agent].ContainsKey("x"),
                              "Agent's state must contain his position as 'x' and 'y' keys");

            var path = AStarSearch.Search(agent, worldState, goal);

            GoapAction.WithContext.ReportLeaks();
            State.ReportLeaks();
            WorldState.ReportLeaks();
            WorldGoal.ReportLeaks();
            WorldEffects.ReportLeaks();

            return(path);
        }
Exemple #8
0
 /// <summary>
 /// Returns false if the action can not be performed.
 /// Override this to implement the affect of completing the action.
 /// </summary>
 protected virtual bool OnDone(GoapAgent agent, WithContext context)
 {
     context.isDone = true;
     DebugUtils.Log(GetType().Name + " DONE!");
     return(true);
 }
Exemple #9
0
 public int GetHashCode(WorldState obj)
 {
     return(GoapAgent.PrettyPrint(obj).GetHashCode());
 }
Exemple #10
0
        /// <summary>
        /// A* forward search for a plan that satisfies the given goal.
        /// </summary>
        /// <returns>Returns null if a plan could not be found, or a list of the
        /// actions that must be performed, in order.</returns>
        public static Queue <GoapAction.WithContext> Plan(
            GoapAgent agent,
            List <GoapAction> availableActions,
            WorldGoal goal)
        {
            var exploredNodes = new Dictionary <WorldState, Node> (WorldStateComparer.instance);
            var closedSet     = new HashSet <WorldState> (WorldStateComparer.instance);
            var openSet       = new FastPriorityQueue <Node> (MAX_FRINGE_NODES);

            var currentNode = Node.pool.Borrow();

            currentNode.Init(null, 0f, goal, null, null);
//			currentNode.position = Vector2.zero;
            currentNode.position = (agent as Component).transform.position;

            openSet.Enqueue(currentNode, 0f);
            int iterations = 0;

            while (openSet.Count > 0 && iterations < MAX_FRINGE_NODES - 10)
            {
                iterations++;

                currentNode = openSet.Dequeue();

                //TODO: delete print
                //Debug.Log ("current world goal: " + GoapAgent.PrettyPrint(currentNode.goal));

                if (DoConditionsApply(currentNode.goal[agent], agent.GetState()))
                {
                    DebugUtils.Log("Selected plan with cost: " + currentNode.Score);
                    var plan = UnwrapPlan(currentNode);
                    //DebugUtils.Log("the plan: " + GoapAgent.PrettyPrint(plan));

                    // Return all nodes.
                    Node.pool.ReturnAll();

                    // Check for leaks in the pools:
                    //DebugUtils.LogError("Nodes: " + Node.pool.Count);
                    //DebugUtils.LogError("WithContext: " + GoapAction.WithContext.pool.Count);
                    //DebugUtils.LogError("WorldState: " + WorldState.pool.Count);

                    return(plan);
                }

                foreach (GoapAction action in availableActions)
                {
                    //TODO: delete print
                    //Debug.Log("considering " + action.name);

                    WorldGoal possibleChildGoal = action.reverseApplyToWorldGoal(currentNode.goal);

                    //Debug.Log ("new goal will be: " + GoapAgent.PrettyPrint(possibleChildGoal));

                    if (agent.GetState().isGoalCloser(currentNode.goal, possibleChildGoal))
                    {
                        List <IStateful> targets = action.GetAllTargets(agent);

                        // No targets, move to next action
                        if (targets.Count == 0)
                        {
                            continue;
                        }

                        float     minCost       = 99999f;
                        float     tempCost      = 0f;
                        IStateful closestTarget = null;
                        Vector2   newPosition   = currentNode.position;
                        foreach (var target in targets)
                        {
                            //DebugUtils.Log ("targets...");
                            //TODO: check target preconds, make sure this works
                            if (goal.ContainsKey(target))
                            {
                                if (!DoConditionsApply(goal [target], target.GetPerceivedState()))
                                {
                                    continue;
                                }
                            }

                            if (action.RequiresInRange())
                            {
                                tempCost = action.CalculateCost(currentNode.position, target);
                                if (tempCost < minCost)
                                {
                                    minCost       = tempCost;
                                    closestTarget = target;
                                    newPosition   = (target as Component).transform.position;
                                    DebugUtils.Log("minCost: " + minCost);
                                    DebugUtils.Log("closestTarget: " + closestTarget);
                                }
                                //DebugUtils.Log ("calculating tempCost");
                            }
                            else
                            {
                                closestTarget = target;
                                tempCost      = 9999;
                                DebugUtils.Log("+++ closestTarget: " + closestTarget);
                                break;
                            }
                        }

                        float cost = currentNode.runningCost + action.workDuration + tempCost;

                        Node newChiledNode = Node.pool.Borrow();
                        DebugUtils.Log("*** closestTarget: " + closestTarget);
                        newChiledNode.Init(currentNode, cost, possibleChildGoal, action, closestTarget);
                        newChiledNode.position = newPosition;
                        openSet.Enqueue(newChiledNode, newChiledNode.runningCost);
                    }

                    //TODO: delete 'else' scope
                    else
                    {
                        //DebugUtils.Log (action.name + " doesnt improve goal");
                    }
                }
            }
            //TODO: return plan failed #yoel
            return(null);
        }