示例#1
0
        private static nPuzzle readProblemFile(string fileName)         // this allow only one puzzle to be specified in a problem file
        {
            try
            {
                //create file reading objects
                StreamReader reader = new StreamReader(fileName);
                StreamReader puzzle = new StreamReader(reader);
                nPuzzle      result;

                string puzzleDimension = puzzle.ReadLine();
                //split the string by letter "x"
                string[] bothDimensions = puzzleDimension.Split("x", true);

                //work out the "physical" size of the puzzle
                //here we only deal with NxN puzzles, so the puzzle size is taken to be the first number
                int puzzleSize = int.Parse(bothDimensions[0]);

//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: int[][] startPuzzleGrid = new int[puzzleSize][puzzleSize];
                int[][] startPuzzleGrid = RectangularArrays.RectangularIntArray(puzzleSize, puzzleSize);
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: int[][] goalPuzzleGrid = new int[puzzleSize][puzzleSize];
                int[][] goalPuzzleGrid = RectangularArrays.RectangularIntArray(puzzleSize, puzzleSize);

                //fill in the start state
                string startStateString = puzzle.ReadLine();
                startPuzzleGrid = ParseStateString(startStateString, startPuzzleGrid, puzzleSize);

                //fill in the end state
                string goalStateString = puzzle.ReadLine();
                goalPuzzleGrid = ParseStateString(goalStateString, goalPuzzleGrid, puzzleSize);

                //create the nPuzzle object...
                result = new nPuzzle(startPuzzleGrid, goalPuzzleGrid);

                puzzle.Close();
                return(result);
            }
            catch (FileNotFoundException)
            {
                //The file didn't exist, show an error
                Console.WriteLine("Error: File \"" + fileName + "\" not found.");
                Console.WriteLine("Please check the path to the file.");
                Environment.Exit(1);
            }
            catch (IOException)
            {
                //There was an IO error, show and error message
                Console.WriteLine("Error in reading \"" + fileName + "\". Try closing it and programs that may be accessing it.");
                Console.WriteLine("If you're accessing this file over a network, try making a local copy.");
                Environment.Exit(1);
            }

            //this code should be unreachable. This statement is simply to satisfy Eclipse.
            return(null);
        }
示例#2
0
        public override direction[] Solve(nPuzzle puzzle)
        {
            //This method uses the fringe as a queue.
            //Therefore, nodes are searched in order of cost, with the lowest cost
            // unexplored node searched next.
            //-----------------------------------------

            //put the start state in the Fringe to get explored.
            addToFrontier(puzzle.StartState);


            List <PuzzleState> newStates = new List <PuzzleState>();

            while (Frontier.Count > 0)
            {
                //get the next item off the fringe
                PuzzleState thisState = popFrontier();

                //is it the goal item?
                if (thisState.Equals(puzzle.GoalState))
                {
                    //We have found a solution! return it!
                    return(thisState.GetPathToState());
                }
                else
                {
                    //This isn't the goal, just explore the node
                    newStates = thisState.explore();

                    for (int i = 0; i < newStates.Count; i++)
                    {
                        //add this state to the fringe, addToFringe() will take care of duplicates
                        //
                        // TODO: is this the correct way to add to frontier as specified in the Assignment:
                        // When all else is equal, nodes should be expanded according to the following order:
                        // the agent should try to move the empty cell UP before attempting LEFT, before
                        // attempting DOWN, before attempting RIGHT, in that order.
                        addToFrontier(newStates[i]);
                    }
                }
            }

            //No solution found and we've run out of nodes to search
            //return null.
            return(null);
        }
        public override direction[] Solve(nPuzzle aPuzzle)
        {
            //keep searching the fringe until it's empty.
            //Items are "popped" from the fringe in order of lowest heuristic value.

            //Add the start state to the fringe
            addToFrontier(aPuzzle.StartState);
            while (Frontier.Count > 0)
            {
                //get the next State
                PuzzleState thisState = popFrontier();

                //is this the goal state?
                if (thisState.Equals(aPuzzle.GoalState))
                {
                    return(thisState.GetPathToState());
                }

                //not the goal state, explore this node
                List <PuzzleState> newStates = thisState.explore();

                for (int i = 0; i < newStates.Count; i++)
                {
                    PuzzleState newChild = newStates[i];
                    //if you can add these new states to the fringe
                    if (addToFrontier(newChild))
                    {
                        //then, work out it's heuristic value
                        newChild.HeuristicValue     = HeuristicValue(newStates[i], aPuzzle.GoalState);
                        newChild.EvaluationFunction = newChild.HeuristicValue;
                    }
                }

                //Sort the fringe by it's Heuristic Value. The PuzzleComparator uses each nodes EvaluationFunction
                // to determine a node's value, based on another. The sort method uses this to sort the Fringe.
                //
                // TODO: is this the correct way to sort the frontier as specified in the Assignment:
                // When all else is equal, nodes should be expanded according to the following order:
                // the agent should try to move the empty cell UP before attempting LEFT, before
                // attempting DOWN, before attempting RIGHT, in that order.
                Frontier.Sort(new PuzzleComparator());
            }

            //no more nodes and no path found?
            return(null);
        }
示例#4
0
 public string longName;     //the actual name of the method.
 //public List<PuzzleState> nodeList;	//this is for catching repeated states and counting total nodes.
 public abstract direction[] Solve(nPuzzle aPuzzle);
示例#5
0
        public static void Main(string[] args)
        {
            //Create method objects
            InitMethods();

            //args contains:
            //  [0] - filename containing puzzle(s)
            //  [1] - method name

            if (args.Length < 2)
            {
                Console.WriteLine("Usage: nPuzzler <filename> <search-method>.");
                Environment.Exit(1);
            }

            //Get the puzzle from the file
            gPuzzle = readProblemFile(args[0]);

            string       method     = args[1];
            SearchMethod thisMethod = null;

            //determine which method the user wants to use to solve the puzzles
            for (int i = 0; i < METHOD_COUNT; i++)
            {
                //do they want this one?
                if (lMethods[i].code.CompareTo(method) == 0)
                {
                    //yes, use this method.
                    thisMethod = lMethods[i];
                }
            }

            //Has the method been implemented?
            if (thisMethod == null)
            {
                //No, give an error
                Console.WriteLine("Search method identified by " + method + " not implemented. Methods are case sensitive.");
                Environment.Exit(1);
            }

            //Solve the puzzle, using the method that the user chose
            direction[] thisSolution = thisMethod.Solve(gPuzzle);

            //Print information about this solution
            Console.WriteLine(args[0] + "   " + method + "   " + thisMethod.Searched.Count);
            if (thisSolution == null)
            {
                //No solution found :(
                Console.WriteLine("No solution found.");
            }
            else
            {
                //We found a solution, print all the steps to success!
                for (int j = 0; j < thisSolution.Length; j++)
                {
                    Console.Write(thisSolution[j].ToString() + ";");
                }
                Console.WriteLine();
            }
            //Reset the search method for next use.
            thisMethod.reset();
            Environment.Exit(0);
        }