예제 #1
0
        public static Result SolveAStar(Maze maze)
        {
            // The set of nodes already evaluated
            var closedSet = new PositionSet();

            // The set of currently discovered nodes that are not evaluated yet.
            // Initially, only the start node is known.
            var openSet = new PositionSet();

            openSet.Add(maze.Start);

            // For each node, which node it can most efficiently be reached from.
            // If a node can be reached from many nodes, cameFrom will eventually contain the
            // most efficient previous step.
            var cameFrom = new PositionMap <Position>();

            // For each node, the cost of getting from the start node to that node.
            var gScore = new GScore(maze, 0);
            //map with default value of Infinity

            // For each node, the total cost of getting from the start node to the goal
            // by passing by that node. That value is partly known, partly heuristic.
            var fScore = new FScore(maze, HeuristicCostEstimate(maze.Start, maze.End));

            // For the first node, that value is completely heuristic.

            while (openSet.Count > 0)
            {
                Position current = fScore.GetLowest(openSet);
                //the node in openSet having the lowest fScore[] value

                if (current.Equals(maze.End))
                {
                    return(new Result(ReconstructPath(cameFrom, current), maze));
                }
                openSet.Remove(current);
                closedSet.Add(current);
                foreach (var neighbor in GetNeighbours(maze, current))
                {
                    if (closedSet.Contains(neighbor))
                    {
                        continue;       // Ignore the neighbor which is already evaluated.
                    }
                    if (!openSet.Contains(neighbor))
                    {  // Discover a new node
                        openSet.Add(neighbor);
                    }
                    // The distance from start to a neighbor
                    //the "dist_between" function may vary as per the solution requirements.
                    double tentative_gScore = gScore[current] + GetDistanceBetweenCost(current, neighbor);
                    if (tentative_gScore >= gScore[neighbor])
                    {
                        continue;               // This is not a better path.
                    }
                    // This path is the best until now. Record it!
                    cameFrom[neighbor] = current;
                    gScore[neighbor]   = tentative_gScore;
                    fScore.Add(neighbor, gScore[neighbor] + HeuristicCostEstimate(neighbor, maze.End));
                }
            }
            return(new Result(maze));
        }