public void Achievable() { var src = new Puzzle(new int[, ] { { 1, 2, 3 }, { 4, 5, 0 } }); var dst = src.MoveSelf(Direction.Left).MoveSelf(Direction.Left).MoveSelf(Direction.Up); Assert.IsTrue(PuzzleUtility.Reachable(src, dst)); Assert.IsFalse(PuzzleUtility.Reachable(src, new Puzzle(new int[, ] { { 1, 2, 3 }, { 5, 4, 0 } }))); }
public static void Main() { //Read from console int rowCount = ReadInteger("Row count: "); int colCount = ReadInteger("Column count: "); Puzzle src = ReadPuzzle(rowCount, colCount, "Source puzzle:\n"); Puzzle dst = ReadPuzzle(rowCount, colCount, "Destination puzzle:\n"); //Check reachability before searching bool?reachable; try { reachable = PuzzleUtility.Reachable(src, dst); } catch (Exception ex) { Console.WriteLine(ex.Message); return; } if (reachable == false) { Console.WriteLine("Not reachable"); return; } //Read the heuristic function to be used. Function name must be presented in Evaluator class string funcName; do { Console.Write("Heuristic function: "); funcName = Console.ReadLine(); }while (typeof(Evaluator).GetField(funcName) == null); Search <Puzzle> .Evaluator estimate = (dynamic)(typeof(Evaluator).GetField(funcName).GetValue(null)); //Start searching var search = new Search <Puzzle>(src, dst, PuzzleUtility.Transform); var cost = search.AStar(estimate); if (!cost.HasValue) { Console.WriteLine("Not reachable"); return; } Console.WriteLine($"Number of steps: {cost}"); //Render the search tree to an image var graph = search.SearchSource.BuildSearchTree(out var indexToNode); var stateToIndex = new Dictionary <Puzzle, int>(); for (int i = 0; i < indexToNode.Length; ++i) { stateToIndex.Add(indexToNode[i].State, i); } graph.SetNodeAttribute(attr => { attr.Padding = 0.1; attr.Color = Color.Black; }); graph.FindNode(stateToIndex[search.Source].ToString()).Attr.Color = Color.Red; graph.FindNode(stateToIndex[search.Destination].ToString()).Attr.Color = Color.Yellow; graph.PaintPath(search.Path.Select(puzzle => stateToIndex[puzzle].ToString()), Color.Cyan); string fileName = "search states.jpg"; graph.RenderImage(fileName, height: search.SearchSource.Height * 40 * (rowCount + 2)); Process.Start(new ProcessStartInfo() { FileName = fileName, UseShellExecute = true }); }
public void CountReversePairs() { Assert.AreEqual(0, PuzzleUtility.CountReversePairs(new int[] { 1, 2, 3, 4, 5 })); Assert.AreEqual(10, PuzzleUtility.CountReversePairs(new int[] { 5, 4, 3, 2, 1 })); Assert.AreEqual(13, PuzzleUtility.CountReversePairs(new int[] { 1, 9, 2, 6, 0, 8, 1, 7 })); }