// Creates and returns a new node. public static StateSpaceNode CreateNode(Planner planner, Domain domain, Problem problem, Plan plan, State state) { // Create a node for the current state. StateSpaceNode root = new StateSpaceNode(); // Record that a node was created. StateSpaceMediator.NodeCount++; // Check if the node is a leaf. if (StateSpaceSearchTools.CheckLeaf(plan, state, root)) { return(root); } // Set the node's domain. root.domain = domain; // Set the node's problem. root.problem = problem; // Set the node's plan. root.plan = plan; // Set the node's state. root.state = state; // Find out what the player knows. root.problem.Initial = RobertsonMicrotheory.Annotate(problem.Initial, problem.Player); // Find all outgoing user actions from this state. root.outgoing = StateSpaceTools.GetAllPossibleActions(domain, problem, plan, state); // Record the number of outgoing edges. StateSpaceMediator.OutgoingEdgesCount = StateSpaceMediator.OutgoingEdgesCount + root.outgoing.Count; // Return the current node. return(root); }
// Creates a child node. private static StateSpaceNode CreateChild(Planner planner, Domain domain, Problem problem, Plan plan, State state, StateSpaceEdge edge) { // Create a new problem object. Problem newProblem = new Problem(); // Create a new domain object. Domain newDomain = domain; // Create a new plan object. Plan newPlan = new Plan(); // Store actions the system takes. List <IOperator> systemActions = new List <IOperator>(); // If the outgoing action is an exceptional step... if (edge.ActionType == ActionType.Exceptional) { // Count the exceptional edge. Exceptional++; // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Find a new plan. newPlan = PlannerInterface.Plan(planner, newDomain, newProblem); // If the action was accommodated and the first step of the new plan isn't taken by the player... if (newPlan.Steps.Count > 0) { // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(newDomain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } else if (CEDeletion) { // Try to find a domain revision alibi. Tuple <Domain, Operator> alibi = ReviseDomain(planner, newDomain, problem, state, edge.Action as Operator); // If domain revision worked. if (alibi != null) { // Remember the new domain. newDomain = alibi.First; // Push the modified action to the edge object. edge.Action = alibi.Second; // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Find a new plan. newPlan = PlannerInterface.Plan(planner, newDomain, newProblem); // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(newDomain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } } } // Otherwise, if the action is a consistent step... else if (edge.ActionType == ActionType.Consistent) { // Count the consistent edge. Consistent++; // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Add the action to the system action list. systemActions = GetSystemActions(plan, new List <string> { problem.Player }, new List <IOperator>()); // Create a new state. State newState = new State(newProblem.Initial, state.nextStep, (Operator)plan.Steps.First()); // Create a new problem object. newProblem = NewProblem(newDomain, newProblem, newState, systemActions); // Create a new plan. newPlan = plan.GetPlanUpdate(newProblem, systemActions); } // Otherwise, the action is a constituent step... else { // Count the constituent edge. Constituent++; // If there are effects of the constituent action... if (edge.Action.Effects.Count > 0) { // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Create a new plan. newPlan = plan.GetPlanUpdate(newProblem, edge.Action as Operator); } // Otherwise, initialize to the old problem and plan... else { newProblem = problem; newPlan = plan.Clone() as Plan; } // If there are still plan actions... if (newPlan.Steps.Count > 0) { // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(newDomain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } } // Add the system actions to the current edge. edge.SystemActions = systemActions; // Create an empty child node. StateSpaceNode child = null; // If there are remaining plan steps... if (newPlan.Steps.Count > 0) { // Build a new tree using the first step of the plan as the next step. child = StateSpaceSearchTools.CreateNode(planner, newDomain, newProblem, newPlan, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First())); } else { // Terminate the tree by adding a goal node. child = StateSpaceSearchTools.CreateNode(planner, newDomain, newProblem, newPlan, new State(newProblem.Initial, newPlan.InitialStep, newPlan.GoalStep)); } // Store the system actions. child.systemActions = systemActions; // Record the action that triggered the node's generation. child.incoming = edge; return(child); }