コード例 #1
0
ファイル: ReGoapPlanner.cs プロジェクト: TMPxyz/ReGoap
        public IReGoapGoal <T, W> Plan(IReGoapAgent <T, W> agent, IReGoapGoal <T, W> blacklistGoal = null, Queue <ReGoapActionState <T, W> > currentPlan = null, Action <IReGoapGoal <T, W> > callback = null)
        {
            if (ReGoapLogger.Level == ReGoapLogger.DebugLevel.Full)
            {
                ReGoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent);
            }
            goapAgent   = agent;
            Calculated  = false;
            currentGoal = null;
            var possibleGoals = new List <IReGoapGoal <T, W> >();

            foreach (var goal in goapAgent.GetGoalsSet())
            {
                if (goal == blacklistGoal)
                {
                    continue;
                }
                goal.Precalculations(this);
                if (goal.IsGoalPossible())
                {
                    possibleGoals.Add(goal);
                }
            }
            possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority()));

            while (possibleGoals.Count > 0)
            {
                currentGoal = possibleGoals[possibleGoals.Count - 1];
                possibleGoals.RemoveAt(possibleGoals.Count - 1);
                var goalState = currentGoal.GetGoalState();

                // can't work with dynamic actions, of course
                if (!settings.UsingDynamicActions)
                {
                    var wantedGoalCheck = currentGoal.GetGoalState();
                    // we check if the goal can be archived through actions first, so we don't brute force it with A* if we can't
                    foreach (var action in goapAgent.GetActionsSet())
                    {
                        action.Precalculations(goapAgent, goalState);
                        if (!action.CheckProceduralCondition(goapAgent, wantedGoalCheck))
                        {
                            continue;
                        }
                        // check if the effects of all actions can archieve currentGoal
                        var previous = wantedGoalCheck;
                        wantedGoalCheck = ReGoapState <T, W> .Instantiate();

                        previous.MissingDifference(action.GetEffects(wantedGoalCheck), ref wantedGoalCheck);
                    }
                    // can't validate goal
                    if (wantedGoalCheck.Count > 0)
                    {
                        currentGoal = null;
                        continue;
                    }
                }

                //Utilities.ReGoapLogger.Log(string.Format("**** Goal: {0}, Expected State = ({1})", currentGoal.GetName(), goalState));

                goalState = goalState.Clone();
                var leaf = (ReGoapNode <T, W>)astar.Run(
                    ReGoapNode <T, W> .Instantiate(this, goalState, null, null), goalState, settings.MaxIterations, settings.PlanningEarlyExit, debugPlan: agent.debugPlan);
                if (leaf == null)
                {
                    currentGoal = null;
                    continue;
                }

                var result = leaf.CalculatePath();
                if (currentPlan != null && currentPlan == result)
                {
                    currentGoal = null;
                    break;
                }
                if (result.Count == 0)
                {
                    currentGoal = null;
                    continue;
                }
                currentGoal.SetPlan(result);
                break;
            }
            Calculated = true;

            if (callback != null)
            {
                callback(currentGoal);
            }
            if (currentGoal != null)
            {
                ReGoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count));
                if (ReGoapLogger.Level == ReGoapLogger.DebugLevel.Full)
                {
                    int i = 0;
                    foreach (var action in currentGoal.GetPlan())
                    {
                        ReGoapLogger.Log(string.Format("[ReGoapPlanner] {0}) {1}", i++, action.Action));
                    }
                }
            }
            else
            {
                ReGoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
            }
            return(currentGoal);
        }
コード例 #2
0
ファイル: ReGoapPlanner.cs プロジェクト: spoutnickgp/ReGoap
        public IReGoapGoal <T, W> Plan(IReGoapAgent <T, W> agent, IReGoapGoal <T, W> blacklistGoal = null, Queue <ReGoapActionState <T, W> > currentPlan = null, Action <IReGoapGoal <T, W> > callback = null)
        {
            goapAgent   = agent;
            Calculated  = false;
            currentGoal = null;
            var possibleGoals = new List <IReGoapGoal <T, W> >();

            foreach (var goal in goapAgent.GetGoalsSet())
            {
                if (goal == blacklistGoal)
                {
                    continue;
                }
                goal.Precalculations(this);
                if (goal.IsGoalPossible())
                {
                    possibleGoals.Add(goal);
                }
            }
            possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority()));

            var currentState = agent.GetMemory().GetWorldState();

            while (possibleGoals.Count > 0)
            {
                currentGoal = possibleGoals[possibleGoals.Count - 1];
                possibleGoals.RemoveAt(possibleGoals.Count - 1);
                var goalState = currentGoal.GetGoalState();

                // can't work with dynamic actions, of course
                if (!settings.UsingDynamicActions)
                {
                    var wantedGoalCheck = currentGoal.GetGoalState();
                    GoapActionStackData <T, W> stackData;
                    stackData.agent        = goapAgent;
                    stackData.currentState = currentState;
                    stackData.goalState    = goalState;
                    stackData.next         = null;
                    stackData.settings     = null;
                    // we check if the goal can be archived through actions first, so we don't brute force it with A* if we can't
                    foreach (var action in goapAgent.GetActionsSet())
                    {
                        action.Precalculations(stackData);
                        if (!action.CheckProceduralCondition(stackData))
                        {
                            continue;
                        }
                        // check if the effects of all actions can archieve currentGoal
                        var previous = wantedGoalCheck;
                        wantedGoalCheck = ReGoapState <T, W> .Instantiate();

                        previous.MissingDifference(action.GetEffects(stackData), ref wantedGoalCheck);
                    }
                    // finally push the current world state
                    var current = wantedGoalCheck;
                    wantedGoalCheck = ReGoapState <T, W> .Instantiate();

                    current.MissingDifference(GetCurrentAgent().GetMemory().GetWorldState(), ref wantedGoalCheck);
                    // can't validate goal
                    if (wantedGoalCheck.Count > 0)
                    {
                        currentGoal = null;
                        continue;
                    }
                }

                goalState = goalState.Clone();
                var leaf = (ReGoapNode <T, W>)astar.Run(
                    ReGoapNode <T, W> .Instantiate(this, goalState, null, null, null), goalState, settings.MaxIterations, settings.PlanningEarlyExit);
                if (leaf == null)
                {
                    currentGoal = null;
                    continue;
                }

                var result = leaf.CalculatePath();
                if (currentPlan != null && currentPlan == result)
                {
                    currentGoal = null;
                    break;
                }
                if (result.Count == 0)
                {
                    currentGoal = null;
                    continue;
                }
                currentGoal.SetPlan(result);
                break;
            }
            Calculated = true;

            if (callback != null)
            {
                callback(currentGoal);
            }
            return(currentGoal);
        }