/// <summary> /// A* forward search for a plan that satisfies the given goal. /// </summary> /// <returns>Returns null if a plan could not be found, or a list of the /// actions that must be performed, in order.</returns> public static Queue <ITransition> Plan( GoapAgent agent, WorldGoal goal) { var worldState = WorldState.Borrow(); worldState[agent] = agent.GetState(); var regressiveSearchGoal = RegressiveSearchWorldGoal.Borrow(goal); DebugUtils.Assert(worldState[agent].ContainsKey("x") && worldState[agent].ContainsKey("y") && worldState[agent].ContainsKey("z"), "Agent's state must contain his position as 'x' and 'y' keys"); var path = AStarSearch.Search(agent, regressiveSearchGoal, worldState, true); worldState.ReturnSelf(); GoapAction.WithContext.ReportLeaks(); State.ReportLeaks(); WorldState.ReportLeaks(); WorldGoal.ReportLeaks(); RegressiveSearchWorldGoal.ReportLeaks(); WorldEffects.ReportLeaks(); return(path); }
public virtual WorldEffects GetEffectsOnAgent(IStateful agent) { var worldEffects = new WorldEffects(); if (effects.Count > 0) { worldEffects[agent] = effects; } return(worldEffects); }
/// <summary> /// Returns the effects that should be applied to the agent and the target /// of the action. /// </summary> public virtual WorldEffects GetDependentEffects(IStateful agent, IStateful target) { var worldEffects = WorldEffects.Borrow(); if (effects.Count > 0) { worldEffects[agent] = effects; } if (targetEffects.Count > 0) { worldEffects[target] = targetEffects; } return(worldEffects); }
/// <summary> /// Regress worldGoal to before effects /// </summary> public RegressiveSearchWorldGoal RegressWorldGoal(WorldEffects worldEffects, bool inPlace = false) { var worldGoal = this; if (!inPlace) { worldGoal = RegressiveSearchWorldGoal.Borrow(); foreach (var goal in this) { worldGoal[goal.Key] = goal.Value; } } // Reverse change. foreach (var effects in worldEffects) { if (worldGoal.ContainsKey(effects.Key)) { worldGoal[effects.Key] = worldGoal[effects.Key].RegressGoal(effects.Value); } } return(worldGoal); }
/// <summary> /// Apply the stateChange to the currentState. /// </summary> private static WorldState ChangeWorldState(WorldState currentWorldState, WorldEffects stateChange, bool inPlace = false) { // Copy state. WorldState worldState = currentWorldState; if (!inPlace) { worldState = new WorldState(); foreach (var kvp in currentWorldState) { worldState [kvp.Key] = kvp.Value; } } // Apply change. foreach (var change in stateChange) { if (!worldState.ContainsKey(change.Key)) { worldState [change.Key] = change.Key.GetState(); } worldState [change.Key] = ChangeState(worldState [change.Key], change.Value); } return(worldState); }