private List <StateNode> GetAdjacentStates(StateNode parent, HashSet <GoapAction> availableActions, Dictionary <string, bool> goal) { List <StateNode> adjacent = new List <StateNode>(); // Go through each action available at this node // and see if we can use it here foreach (GoapAction action in availableActions) { // if the parent state has the conditions for this // action's preconditions, we can use it here if (InState(action.Preconditions, parent.State)) { // Check if the Procedural Preconditions // are also matched ( These are OR conditions ) if (action.CheckProceduralPreconditions()) { // apply the action's effects to the parent state Dictionary <string, bool> state = UpdatedState(parent.State, action.Effects); // Create new Node State StateNode node = new StateNode(parent, parent.RunningCost + action.GetCost(), state, action, goal); // Add the new state to adjacent states AddToListAndSort(adjacent, node); } } } return(adjacent); }
private Plan FindPlan(HashSet <GoapAction> availableActions, Dictionary <string, bool> worldState, Dictionary <string, bool> goal, string agentName, string planName) { bool isPlanFound = false; openListStates = new List <StateNode>(); closedListStates = new List <StateNode>(); adjacentStates = new List <StateNode>(); // start by adding the original state to the open list AddToListAndSort(openListStates, new StateNode(null, 0, worldState, null, goal)); while (openListStates.Count > 0) { //TODO: Open List should be Sorted ( Ascending order by F ) // Get the square with the lowest F score StateNode currentState = openListStates[0]; // add the current state to the closed list closedListStates.Add(currentState); // if we added the destination to the closed list, we've found a path if (InState(goal, currentState.State)) { isPlanFound = true; break; } // Remove used action availableActions.Remove(currentState.action); // remove it from the open list //openListStates.Remove(currentState); openListStates.Clear(); // Retrieve all states next possible adjacentStates = GetAdjacentStates(currentState, availableActions, goal); foreach (StateNode state in adjacentStates) { // if this adjacent state is already in the closed list ignore it if (closedListStates.Contains(state)) { continue; } // if its not in the open list if (!openListStates.Contains(state)) { // compute its score, set the parent AddToListAndSort(openListStates, state); } // if its already in the open list else { // test if using the current G score make the states F score lower, // if yes update the parent because it means its a better path int index = openListStates.IndexOf(state); StateNode oldState = openListStates[index]; if (state.StateCost < oldState.StateCost) { openListStates.RemoveAt(index); AddToListAndSort(openListStates, state); } } } } return(new Plan(closedListStates, isPlanFound, agentName, planName)); }
private void AddToListAndSort(List <StateNode> list, StateNode element) { list.Insert(0, element); list.Sort(); }