public bool Matches(StateList conditions) { // DONE Use dictionary cache if avaliable - otherwise this is gonna be real slow // Check each state for a conflict in world SaveCache(); if (useCache) { foreach (KeyValuePair <string, float> pair in conditions.stateTree) { if (GetState(pair.Key) != pair.Value) { return(false); } } } else { foreach (State state in conditions.states) { // If it's not the right value, fail the match if (GetState(state.Name) != state.Value) { return(false); } } } return(true); }
private bool useCache = true; // if true then all operations are done using the cache (map), setting to false will disable all cache ops public StateList Copy() { SaveCache(); StateList s = new StateList(); s.states = states.Clone() as State[]; s.LoadCache(); return(s); }
public Node AddChild(Action action, StateList goal) { // The state is our nodes current state with the action applied // Cost goes up by one Node child = new Node(action, action.Simulate(state, goal), this, cost + 1.0f); children.Add(this); return(child); }
public Node(Action act, StateList s, Node par, float c = 0.0f) { // Start with no children children = new List <Node>(); // Remember what action created this node action = act; state = s; // Who's your daddy? parent = par; cost = c; }
public object Clone() { StateList cloned = new StateList(); foreach (KeyValuePair <string, float> state in this) { cloned.Add(state.Key, state.Value); } return(cloned); }
public void AddAction(Node previous, Action a) { // Calculate the world state after this action StateList nextState = a.Simulate(previous.state); // Calculate the total cost of the plan including this action float totalCost = previous.cost + a.cost; // Create the leaf node (which hooks up parent/child ref Node leaf = new Node(previous, a, nextState, totalCost); openLeaves.Add(leaf); }
// Checks the crrent planning tree to see if this is a world we've already considered private bool IsUniqueOutcome(StateList world) { // Check each visited node's world state foreach (Node n in visited) { // Matches is asymetric, so we check twice for real equivalency if (world.Matches(n.state) && n.state.Matches(world)) { return(false); } } return(true); }
public Node(Node parent, Action action, StateList state, float cost) { this.action = action; this.state = state; this.cost = cost; this.children = new List <Node>(); // Hook up parent/child ref if (parent != null) { this.parent = parent; parent.children.Add(this); } }
public bool Contains(StateList goal) { // TODO If I import my fuzzy library, I can just use that to eval the fuzz if (goal.Count == 0) { return(true); } // Each goal state is required foreach (KeyValuePair <string, float> state in goal) { if (!Mathf.Approximately(GetState(state.Key), state.Value)) { return(false); } } return(true); }
// Returns a fuzzy value of how much we've met our goal public float FuzzyContains(StateList goal) { // Boom, easy! if (goal.Count == 0) { return(1.0f); } float matchWeight = 1.0f / goal.Count; float match = 0.0f; // Each goal is weighted equally foreach (KeyValuePair <string, float> state in goal) { if (Mathf.Approximately(GetState(state.Key), state.Value)) { match += matchWeight; } } return(match); }
// Called after planning, when it's time to do the action. // Returns true if done with action, otherwise DoAction will be called again next frame // This should eventually do what it promised in Apply abstract public bool DoAction(StateList world, StateList goal, GameObject actor);
// Called when planning, to simulate the effects of the action to the world abstract public StateList Simulate(StateList world, StateList goal);
// Called when checking if the action can be applied to the current world state abstract public bool CheckPreconditions(StateList world, StateList goal);
public abstract IEnumerable DoAction(StateList world, StateList goal, GameObject actor);
// A percentage [0f..1f] on how much the action can move the world to the goal. // 1f means the action can get all the way to the goal (is the best choice) // 0f means the action is currently unavailable / is not a good choice public abstract float Heuristic(StateList world, StateList goal);
// Constructs an empty PlanTree for a given world state public PlanTree(StateList world) { openLeaves = new List <Node>(); root = new Node(null, null, world, 0.0f); openLeaves.Add(root); }