Example #1
0
        public static IEnumerable <IGraphNode <T> > AStar <T>(this IGraphNode <T> from, IGraphNode <T> to)
        {
            //'let'
            //Initial state of the algorithm
            var closedSet = new HashSet <IGraphNode <T> >();
            var openSet   = new HashSet <IGraphNode <T> >()
            {
                from
            };
            var gScore = new Map <IGraphNode <T>, float>()
            {
                { from, 0 }
            };
            var fScore = new Map <IGraphNode <T>, float>()
            {
                { from, from.Heuristic(to) }
            };
            var previous     = new Map <IGraphNode <T>, IGraphNode <T> >();
            var initialState = AStarState.New(closedSet, openSet, gScore, fScore, previous);

            //Compute final state from a sequence generated from the initial state
            //(the functional replacement of the queue), that is the last state of the following
            //generated sequence
            var finalState = Generate(initialState, state =>
            {
                //If we found the last node, we're finished generating states
                if (state.lastNode != null)
                {
                    return(null);
                }

                //'let'
                //Get the one with lowest fScore, lazyness prevents the full query from executing
                var node = state.openSet.OrderBy(x => state.fScore[x]).First();
                //Reached the target, finish the state generation
                if (node.Satisfies(to) || openSet.Count == 0)
                {
                    return(FinalAStarState(state, node));
                }

                //'in'
                return(NextAStarState(CloseNode(state, node), node, to));
            }).Last();

            //'in'
            //Reconstruct the path
            return(Generate(finalState.lastNode, node => finalState.previous[node]).Reverse());
        }