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); }
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); }
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);
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); }