public bool BuildGraph(Node parent, List <Node> leaves, List <Action> usableActions, string goal) { var foundPath = false; foreach (var usableAction in usableActions) { var usable = usableAction.IsPreconditionsMet(parent.States); if (!usable) { if (GenerateFailedPlansReport) { AddError(parent, usableAction, parent.States); } continue; } if (!usableAction.IsProceduralPreconditionMet(parent.States)) { continue; } var currentState = DictionaryPool <string, float> .Get(); var node = Pool <Node> .Get(); _usedNodes.Push(node); node.States = currentState; node.Action = usableAction; node.ActionName = usableAction.Name; node.Parent = parent; node.Cost = parent.Cost + usableAction.Cost; node.Cost += usableAction.DynamicallyEvaluateCost(parent.States); foreach (var parentState in parent.States) { if (!currentState.ContainsKey(parentState.Key)) { currentState.Add(parentState.Key, parentState.Value); } } foreach (var effect in usableAction.AfterEffects) { if (!currentState.ContainsKey(effect.Key)) { currentState.Add(effect.Key, effect.Value); } } usableAction.ProceduralEffect(currentState); // Goal Achieved if (currentState.ContainsKey(goal)) { leaves.Add(node); foundPath = true; } else { var subsetActions = ListPool <Action> .Get(); _usedActions.Push(subsetActions); foreach (var action in usableActions) { subsetActions.Add(action); } subsetActions.Remove(usableAction); foundPath = BuildGraph(node, leaves, subsetActions, goal); } } return(foundPath); }