public RouteFinderLists Open(LocationCandiate candiate) { var existing = _openList.Lookup(candiate.Location); return(existing .Select(x => x.CurrentCost < candiate.CurrentCost) .OrElse(false) ? this : new RouteFinderLists( _openList.SetItem(candiate.Location, candiate), _closedList)); }
public static Path BuildActorPath(LocationCandiate targetCandidate) { // Do not expect one node, would mean start = end Debug.Assert(targetCandidate.Parent.HasValue); // Pop last location added as it will be the current location return(Path.Create( targetCandidate.Location, targetCandidate .LinkedListToEnumerable(node => node.Parent) .Aggregate( ImmutableStack <Vector> .Empty, (stack, candidate) => stack.Push(candidate.Location)) .Pop())); }
public static RouteFinderLists OpenCandidateMoves( RouteFinderLists lists, LocationCandiate currentNode, Vector target, Func <Vector, bool> isValidMove) { Func <Vector, bool> isViable = move => isValidMove(move) && !lists.IsClosed(move); return(currentNode.Location .GetValidMoves(isViable) .Select(move => LocationCandiate .Create(target, move, currentNode.ToSome())) .Aggregate( lists.Close(currentNode), (finderLists, candiate) => finderLists.Open(candiate))); }
public static IMaybe <Path> FindRoute( this Vector start, Vector target, Func <Vector, bool> isValidMove, IMaybe <int> breakSize) { Debug.Assert(isValidMove != null); if (start == target) { return(Maybe <Path> .None); } var lists = RouteFinderLists .Create() .Open(LocationCandiate.Create(target, start)); while (lists.HasOpenCandidates) { // Capture to stop access modified closure var closedList = lists.ClosedList; if (breakSize.Select(x => x < closedList.Count).OrElse(false)) { break; } var currentNode = lists.NextOpenCandiate; if (currentNode.Location == target) { return(BuildActorPath(currentNode).ToSome()); } lists = OpenCandidateMoves( lists, currentNode, target, isValidMove); } return(Maybe <Path> .None); }
public RouteFinderLists Close(LocationCandiate candidate) { return(new RouteFinderLists( _openList.Remove(candidate.Location), _closedList.SetItem(candidate.Location, candidate))); }