예제 #1
0
 private static void DebugText(DebugPlanning current, DebugPlanning required, string text, params object[] obj)
 {
     if ((current & required) != 0)
     {
         Debug.Log(string.Format(text, obj));
     }
 }
예제 #2
0
        private static List <Action> FindSolution(IGoap igoap, List <Action> actions, Goal goal, DebugPlanning debug)
        {
            // Create the closed/ open list and add the goal state to the latter
            List <Node> closedList = new List <Node>();
            List <Node> openList   = new List <Node>();

            openList.Add(new Node(null, null, goal.succes));

            DebugText(debug, DebugPlanning.Everything, "Starting state is {0}.", ConditionsToText(goal.succes));

            // As long as there are nodes in the open list, we continue
            while (true)
            {
                Node p = GetCheapestNode(openList);
                if (p.action != null)
                {
                    DebugText(debug, DebugPlanning.Everything, "Picked open node with action {0} from the open list.", p.action.GetType());
                }

                // Look for each action if it gives the desired effects
                foreach (Action action in actions)
                {
                    Action a = action.OnClone();
                    DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Trying to add action {0} to the current state. Calling action {0}'s OnActionSetup.", a.GetType());
                    a.OnActionSetup(igoap, p.state);

                    // Make sure the effects add to the state
                    if (MatchesState(a.effects, p.state))
                    {
                        // Make sure the action is actually viable
                        if (!a.isViable)
                        {
                            DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Action {0} could not be added because it's not viable.", a.GetType());
                            continue;
                        }

                        DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Action {0} is viable, the state will now be altered with the effects and preconditions.", a.GetType());

                        // Add the actions preconditions
                        List <Condition> state = AddToState(p.state, a.preconditions);
                        DebugText(debug, DebugPlanning.Everything, "Current state after adding action {0}'s preconditions: {1}.", a.GetType(), ConditionsToText(state));
                        // Remove actions effects
                        state = RemoveFromState(state, a.effects);
                        DebugText(debug, DebugPlanning.Everything, "Current state after removing action {0}'s effects: {1}.", a.GetType(), ConditionsToText(state));
                        // Remove preconditions which our current state already fullfills
                        state = RemoveFromState(state, igoap.state);
                        DebugText(debug, DebugPlanning.Everything, "Current state after removing iGoap's state: {0}.", ConditionsToText(state));

                        // Create a new node
                        Node n = new Node(p, a, state);

                        // If the state hasn't changed, the action will be futile
                        if (MatchesState(n.state, p.state))
                        {
                            DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Action {0} effects did not alter the state. Since this action is futile it will not be added.", a.GetType());
                            continue;
                        }

                        // See if we've reached the solution
                        if (n.state.Count == 0)
                        {
                            closedList.Add(n);
                            continue;
                        }

                        DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Action {0} succesfully added to the open list. Current open list count: {1}.", a.GetType(), openList.Count);

                        // Otherwise we add it to the open list
                        openList.Add(n);
                    }
                    else
                    {
                        DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Action {0} is not viable.", a.GetType());
                    }
                }

                // We're done with this node, so we remove it from the list
                openList.Remove(p);

                // Check to see if a solution has been found
                if (openList.Count == 0 && closedList.Count != 0)
                {
                    return(NodesToActions(GetCheapestNode(closedList)));
                }

                if (openList.Count == 0)
                {
                    break;
                }
            }

            DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Ran out of viable path options for goal {0}.", goal.GetType());
            return(null);
        }
예제 #3
0
        /// <summary>
        /// Formulates a plan based on the given actions and goal
        /// </summary>
        /// <param name="actions">List of available actions</param>
        /// <param name="goals">Available goal</param>
        /// <param name="currentGoal">If a plan is found, this will be the current goal</param>
        /// <returns>If a plan was found, a list of actions. Otherwise null</returns>
        public static List <Action> FormulatePlan(IGoap igoap, List <Action> actions, Goal goal, out Goal currentGoal, DebugPlanning debug = DebugPlanning.None)
        {
            currentGoal = goal;
            if (igoap == null || actions == null || actions.Count == 0 || goal == null)
            {
                if (igoap == null)
                {
                    DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Can't formulate a plan because no suitable iGoap was found.");
                }
                if (actions == null || actions.Count == 0)
                {
                    DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Can't formulate a plan because no suitable actions for iGoap were found.");
                }
                if (goal)
                {
                    DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Can't formulate a plan because no suitable goal for iGoap was found.");
                }
            }

            DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Formulating a plan for goal {0}.", goal.GetType());

            goal.OnGoalSetup();
            if (!goal.IsGoalRelevant())
            {
                DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Goal {0} is not relevant.", goal.GetType());
                return(null);
            }

            List <Action> plan = FindSolution(igoap, actions, goal, debug);

            if (plan == null)
            {
                DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Couldn't find a plan for goal {0}, returning null.", goal.GetType());
            }
            else
            {
                DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Found a plan for goal {0} and returning it.", goal.GetType());
            }

            return(plan);
        }
예제 #4
0
        /// <summary>
        /// Formulates a plan based on the given actions and goals
        /// </summary>
        /// <param name="actions">List of available actions</param>
        /// <param name="goals">List of available goals, these will be sorted by priority</param>
        /// <param name="currentGoal">If a plan is found, this will be the current goal</param>
        /// <returns>If a plan was found, a list of actions. Otherwise null</returns>
        public static List <Action> FormulatePlan(IGoap igoap, List <Action> actions, List <Goal> goals, out Goal currentGoal, DebugPlanning debug = DebugPlanning.None)
        {
            currentGoal = null;
            if (igoap == null || actions == null || actions.Count == 0 || goals == null || goals.Count == 0)
            {
                if (igoap == null)
                {
                    DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Can't formulate a plan because no suitable iGoap was found.");
                }
                if (actions == null || actions.Count == 0)
                {
                    DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Can't formulate a plan because no suitable actions for iGoap were found.");
                }
                if (goals == null || goals.Count == 0)
                {
                    DebugText(debug, DebugPlanning.Basics | DebugPlanning.Everything, "Can't formulate a plan because no suitable goals for iGoap were found.");
                }

                return(null);
            }

            foreach (Goal goal in goals.OrderByDescending(g => g.priority).ToList())
            {
                List <Action> plan = FormulatePlan(igoap, actions, goal, out currentGoal, debug);

                if (plan != null)
                {
                    return(plan);
                }
            }

            return(null);
        }