예제 #1
0
        // Method to run the overall A* algorithm and print the results to console
        public static void Run()
        {
            // Create the open and closed lists
            var frontier = new MinHeap <BoardNode>();
            var visited  = new List <BoardState>();

            // Variables to show the amount of nodes generated and the cost
            int numExpanded  = 0;
            int numGenerated = 0;
            int pathCost     = 0;

            // Create node to interate through open list
            BoardNode current = null;

            // Create Node for the starting state
            BoardNode initialState;

            // Ask for user starting and goal states until configuration is possible
            do
            {
                // Ask user for goal state
                goalState = getGoal();

                // Ask user for starting state
                initialState = getInitial();
            }while (!goalState.checkPolarity(initialState.State));

            // Print starting and goal nodes
            Logger.WriteLine("Initial State: ");
            initialState.State.PrintBoard();

            Logger.WriteLine("Goal State: ");
            goalState.PrintBoard();

            // Add starting state to the open list
            frontier.Add(initialState);

            // While the open list is not empty
            while (!frontier.IsEmpty())
            {
                // Store the best move from the open list
                current = frontier.RemoveMin();
                numExpanded++;

                // If the current node is the goal
                if (current.GoalNode)
                {
                    // Set the path cost and break from the loop
                    pathCost = current.GVal;
                    break;
                }

                // Add the current state to the closed list
                visited.Add(current.State);

                // Retrieve the nodes around the current node
                var successors = current.GenerateSuccessors().Where(successor => !visited.Contains(successor.State));
                numGenerated += successors.ToList().Count;

                // Add each successor to the open list
                foreach (var successor in successors)
                {
                    frontier.Add(successor);
                }
            }

            // Create a stack to store the path
            var path = new Stack <BoardNode>();

            // Starting from the goal, push each parent to the stack
            while (current != null)
            {
                path.Push(current);
                current = current.Parent;
            }

            Logger.WriteLine("Path found. Showing path... ");
            Logger.WriteLine();

            // For each node in the path
            foreach (var item in path)
            {
                // Print the board
                item.State.PrintBoard();

                // If the user chose the misplaced tile heuristic
                if (initialState.UseMisplacedHeuristic)
                {
                    // Print the misplaced tile heuristic
                    Logger.WriteLine($"Misplaced Heuristic: {item.HValMisplaced}");
                }
                else
                {
                    // Print the manhattan distance heuristic
                    Logger.WriteLine($"Manhattan Heuristic: {item.HValManhat}");
                }

                // Print the G and F values
                Logger.WriteLine($"G Value: {item.GVal}");
                Logger.WriteLine($"F Value: {item.FVal}");
                Logger.WriteLine();
            }

            // Print the number of nodes generated, expanded, and the path cost
            Logger.WriteLine("Number of Nodes Generated: " + numGenerated);
            Logger.WriteLine("Number of Nodes Expanded: " + numExpanded);
            Logger.WriteLine("Total Path Cost: " + pathCost);
        }
예제 #2
0
        // Method to allow user input of the starting state and heuristic
        private static BoardNode getInitial()
        {
            // Create variables to get user input for starting state
            BoardNode init;

            string[] start;
            char     input1;
            char     input2;

            // While the input is invalid
            do
            {
                // Ask user if they would like to create a custom starting state
                Console.WriteLine("Would you like to create an intial state? (Y/N) ");
                input1 = Console.ReadLine().ToCharArray()[0];
                Console.WriteLine();
            }while (char.ToUpper(input1) != 'Y' && char.ToUpper(input1) != 'N');

            // If the user wants to create an initial state
            if (char.ToUpper(input1) == 'Y')
            {
                // While the input is invalid
                do
                {
                    // Ask user to input starting state
                    Console.WriteLine("Please enter the starting state(1, 2, ... 8, 0): ");
                    start = Regex.Split(Console.ReadLine(), @"\D+");
                    Console.WriteLine();
                }while (BoardState.SetBoard(start) == null);

                // While the input is invalid
                do
                {
                    // Ask user if they would like to use the misplaced tile heuristic
                    Console.WriteLine("Would you like to use the Misplaced Tile Heuristic? (Y/N) ");
                    input2 = Console.ReadLine().ToCharArray()[0];
                    Console.WriteLine();
                }while (char.ToUpper(input2) != 'Y' && char.ToUpper(input2) != 'N');

                // If the user wants to use the misplaced tile heuristic
                if (char.ToUpper(input2) == 'Y')
                {
                    // Create node with the custom starting board and misplaced tile heuristic
                    init = new BoardNode(BoardState.SetBoard(start), 0, true, null);
                }
                else
                {
                    // Create node with the custom starting board and the manhattan distance heuristic
                    init = new BoardNode(BoardState.SetBoard(start), 0, false, null);
                }
            }
            else
            {
                // While the input is invalid
                do
                {
                    // Ask the user if they would like to use the misplaced tile heuristic
                    Console.WriteLine("Would you like to use the Misplaced Tile Heuristic? (Y/N) ");
                    input2 = Console.ReadLine().ToCharArray()[0];
                    Console.WriteLine();
                }while (char.ToUpper(input2) != 'Y' && char.ToUpper(input2) != 'N');

                // If the user wants to use the misplaced tile heuristic
                if (char.ToUpper(input2) == 'Y')
                {
                    // Create node using random board and misplaced tile heuristic
                    init = new BoardNode(BoardState.BuildRandomBoard(), 0, true, null);
                }
                else
                {
                    // Create node using random board and manhattan distance heuristic
                    init = new BoardNode(BoardState.BuildRandomBoard(), 0, false, null);
                }
            }

            // Return the created node as the starting node
            return(init);
        }