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));
        }
Exemple #2
0
        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()));
        }
Exemple #3
0
        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)));
        }
Exemple #4
0
        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)));
 }