public Solution(Puzzle puzzle, State final, HashSet<State> reachedStates, HashSet<State> statesExitReachedFrom = null) { this.puzzle = puzzle; this.final = final; this.reachedStates = reachedStates; this.statesExitReachedFrom = statesExitReachedFrom ?? new HashSet<State>(); }
public void Move(string locationName, string liftName = null) { Edge edge = state.position.edgesFrom.FirstOrDefault(e => e.to.name == locationName && e.Move(state) != null && (liftName == null || e.lift != null && e.lift.name == liftName)); if (edge == null) { throw new Exception(String.Format("Move to {0}{1} failed: no suitable edge", locationName, liftName != null ? string.Format(" via {0)", liftName) : "")); } state = edge.Move(state); }
public State Unpush(State state) { if (state.calledLifts.Count == 0 || state.calledLifts.Last() != this.target) { return null; } var result = state.Clone(); result.calledLifts.RemoveAt(result.calledLifts.Count - 1); result.SetNext(state, new Push(this)); return result; }
public State Push(State state) { if (state.calledLifts.Contains(target)) { return null; } var result = state.Clone(); result.calledLifts.Add(target); result.SetPrevious(state, new Push(this)); return result; }
static void TestComparer() { Puzzle puzzle = Puzzles.Raise(); State state1 = new State(puzzle.start, new List<Lift>() { puzzle.locations[0].edgesFrom[0].lift }); State state2 = new State(puzzle.start, new List<Lift>() { puzzle.locations[0].edgesFrom[0].lift }); StateComparer comparer = new StateComparer(); Console.WriteLine(comparer.Equals(state1, state2)); Console.WriteLine(comparer.GetHashCode(state1)); Console.WriteLine(comparer.GetHashCode(state2)); Console.ReadLine(); }
public void Call(string liftName) { var button = state.position.buttons.FirstOrDefault(b => b.target.name == liftName); if (button == null) { throw new Exception(String.Format("Call {0} failed: no button for such lift at current position {1}", liftName, state.position)); } if (state.calledLifts.Contains(button.target)) { throw new Exception(String.Format("Call {0} failed: already in queue", liftName)); } state = button.Push(state); }
public State Unmove(State state) { if (this.lift != null && (state.calledLifts.Contains(this.lift))) { return null; } var result = state.Clone(); result.position = from; if (this.lift != null) { result.calledLifts.Insert(0, this.lift); } result.SetNext(state, new Move(this)); return result; }
public State Move(State state) { if (this.lift != null && (state.calledLifts.Count == 0 || state.calledLifts[0] != this.lift)) { return null; } var result = state.Clone(); result.position = to; if (this.lift != null) { result.calledLifts.RemoveAt(0); } result.SetPrevious(state, new Move(this)); return result; }
public static void Bfs(Puzzle puzzle, HashSet<State> reachedStates, State start) { Queue<State> queue = new Queue<State>(); queue.Enqueue(start); reachedStates.Add(start); while (queue.Count > 0) { List<State> nextStates = NextStates(puzzle, queue.Dequeue()); nextStates.ForEach(nextState => { if (!reachedStates.Contains(nextState)) { reachedStates.Add(nextState); queue.Enqueue(nextState); } }); } }
public static List<State> PreviousStates(Puzzle puzzle, State state) { var result = new List<State>(); state.position.edgesTo.ForEach(edge => { var prevState = edge.Unmove(state); if (prevState != null) { result.Add(prevState); } }); state.position.buttons.ForEach(button => { var prevState = button.Unpush(state); if (prevState != null) { result.Add(prevState); } }); return result; }
public static List<State> NextStates(Puzzle puzzle, State state) { var result = new List<State>(); state.position.edgesFrom.ForEach(edge => { var nextState = edge.Move(state); if (nextState != null) { result.Add(nextState); } }); state.position.buttons.ForEach(button => { var nextState = button.Push(state); if (nextState != null) { result.Add(nextState); } }); return result; }
public void SetPrevious(State previous, Action actionFromPrevious) { this.previous = previous; this.actionFromPrevious = actionFromPrevious; }
public void SetNext(State next, Action actionToNext) { this.next = next; this.actionToNext = actionToNext; }
public static bool Final(State state) { return state.position.isExit; }
public void Start() { state = new State(start); }