public Plan MakePlan( World current, IGoal goal, RefreshActionsCallback actionRefresh, RefreshWorldCallback worldRefresh) { worldRefresh(current); PlanTree tree = new PlanTree(start: current); while (!tree.IsEmpty()) { // Select the endpoint of the easiest plan we have // This is bredth-first, try "closest" for A*like PlanTree.Node n = tree.PopCheapestLeaf(); if (goal.MeetsGoal(n.Expected)) { Debug.Log("Plan found!"); return(tree.GetPlan(n)); } IList <Step> actions = actionRefresh(n.Expected); Debug.Log("Found " + actions.Count + " actions."); foreach (Step a in actions) { tree.AddStep(n, a); } } Debug.Log("No plan exists!"); return(new Plan(new List <Step>())); }
private IEnumerator DoPlanningHelper() { currentlyPlanning = true; // The amount of nodes we'll look at before we give up const int MAX_NODES = 2048; // The ammount of nodes we look at each frame int nodesLookedAt = 0; // Look at nodes until we find a path or give up while (nodesLookedAt < MAX_NODES && !tree.IsEmpty()) { // Get the next unexplored node PlanTree.Node leaf = tree.PopCheapestLeaf(); nodesLookedAt++; // Give the action a chance to update anything it needs // Did we reach our goal? if (leaf.state.Matches(goal)) { plan = tree.GetPlan(leaf); Debug.Log("Found plan of " + plan.Count + " actions after looking at " + nodesLookedAt + " nodes!"); currentlyPlanning = false; yield break; } // See if we can do any possible actions on this tree foreach (Action act in possibleActions) { bool validAction = act.CheckPreconditions(leaf.state, goal); if (validAction) { tree.AddAction(leaf, act); } } // Wait for end of frame if that's what you're into if (ticksPerFrame > 0 && (nodesLookedAt % ticksPerFrame == 0)) { yield return(null); } } plan = new Queue <Action>(); Debug.Log("Couldn't find a plan after looking at " + nodesLookedAt + " nodes."); currentlyPlanning = false; yield break; }