private void AddAllUnvisitedChildren(MazeNode current, Stack <MazeNode> q, int nCurrentLevel, int nMaxLimit) { int x = current.GetX(); int y = current.GetY(); // Left pixel. If it is not out of bounds and previously not visited if (x - 1 >= 0 && !visited[x - 1, y]) { visited[x - 1, y] = true; q.Push(new MazeNode(x - 1, y, current)); } // Right pixel. If it is not out of bounds and previously not visited if (x + 1 < maze.Width && !visited[x + 1, y]) { visited[x + 1, y] = true; q.Push(new MazeNode(x + 1, y, current)); } // top pixel. If it is not out of bounds and previously not visited if (y - 1 >= 0 && !visited[x, y - 1]) { visited[x, y - 1] = true; q.Push(new MazeNode(x, y - 1, current)); } // bottom pixel. If it is not out of bounds and previously not visited if (y + 1 < maze.Height && !visited[x, y + 1]) { visited[x, y + 1] = true; q.Push(new MazeNode(x, y + 1, current)); } }
// Given a valid finish node with a linked list back to the start node // will draw a path on the bitmap image from finish to start public void ColorPathFromFinishToStart(MazeNode finishNode) { MazeNode current = finishNode; while (current != null) { maze.SetPixel(current.GetX(), current.GetY(), pathColor); current = current.GetParent(); } }
private void BTN_Solve_Click(object sender, RoutedEventArgs e) { DateTime startedTime; DateTime finalizedTime; // Get the file names that will be working on from command line string outputPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); // For this project these define the start, end, wall and path colors for the maze // Just change these if you want to solve a maze with different requirements System.Drawing.Color start = System.Drawing.Color.Red; System.Drawing.Color end = System.Drawing.Color.Blue; System.Drawing.Color wall = System.Drawing.Color.Black; System.Drawing.Color path = System.Drawing.Color.GreenYellow; // Load the maze from the first argument filename Bitmap mazeImage = new Bitmap(ImagePath); // initialize path finder with the image and colors to operate with PathFinder pf = new PathFinder(mazeImage, start, end, wall, path); // get the solved maze bitmap from pathfinder startedTime = DateTime.Now; MazeNode resultPath = pf.SolveMaze(COMBO_Type.SelectedValue.ToString()); finalizedTime = DateTime.Now; Lbl_coordinates.Content = "Elapsed Time:" + finalizedTime.Subtract(startedTime).TotalSeconds.ToString() + " seconds. "; mazeImage = pf.Maze; if (mazeImage == null) { MessageBox.Show("Could not solve maze"); } else { LIST_Solution.Items.Clear(); MazeNode current = resultPath; while (current != null) { LIST_Solution.Items.Add("(" + current.GetX() + ", " + current.GetY() + ")"); current = current.GetParent(); } Lbl_coordinates.Content = Lbl_coordinates.Content + LIST_Solution.Items.Count.ToString() + " elements"; // Save the solved maze image into the output file path mazeImage.Save(outputPath + @"\solved_maze.png"); fileUri = new Uri(outputPath + @"\solved_maze.png"); IMG_Maze.Source = new BitmapImage(fileUri); } }
//This method is used for A* algorithm private void AddAllUnvisitedChildren(MazeNode current, List <MazeNode> q, MazeNode Goal, MazeNode Start) { int x = current.GetX(); int y = current.GetY(); List <MazeNode> temp = new List <MazeNode>(); // Left pixel. If it is not out of bounds and previously not visited if (x - 1 >= 0 && !visited[x - 1, y]) { visited[x - 1, y] = true; temp.Add(new MazeNode(x - 1, y, current)); } // Right pixel. If it is not out of bounds and previously not visited if (x + 1 < maze.Width && !visited[x + 1, y]) { visited[x + 1, y] = true; temp.Add(new MazeNode(x + 1, y, current)); } // top pixel. If it is not out of bounds and previously not visited if (y - 1 >= 0 && !visited[x, y - 1]) { visited[x, y - 1] = true; temp.Add(new MazeNode(x, y - 1, current)); } // bottom pixel. If it is not out of bounds and previously not visited if (y + 1 < maze.Height && !visited[x, y + 1]) { visited[x, y + 1] = true; temp.Add(new MazeNode(x, y + 1, current)); } AStarSC MyComparer = new AStarSC(); foreach (MazeNode child in temp) { child.Heurs(Goal, Start); } temp.Sort(MyComparer); foreach (MazeNode child in temp) { q.Add(child); } }
public MazeNode DoIterativeDepthFirstSearch(MazeNode start) { Stack <MazeNode> nodeStack = new Stack <MazeNode>(); visited = new bool[maze.Width, maze.Height]; int maxLevel = 0; while (true) { nodeStack.Clear(); clearVisited(maze.Width, maze.Height); int nCurrentLevel; nodeStack.Push(start); maxLevel += 1; // keep looking until there are no more nodes in the queue while (nodeStack.Count > 0) { MazeNode current = nodeStack.Pop(); visited[current.GetX(), current.GetY()] = true; // Skip any walls if (IsWallNode(current)) { continue; } // If its a finish node, we are done return this node if (IsFinishNode(current)) { return(current); } AddAllUnvisitedChildren(current, nodeStack); nCurrentLevel = getCurrentLevel(current); if (nCurrentLevel >= maxLevel) { //Console.WriteLine(maxLevel.ToString()); break; } } } }
// checks if the node has the same color as a finishing pixel. // this can be edited to put any custom finish point public bool IsFinishNode(MazeNode node) { return(maze.GetPixel(node.GetX(), node.GetY()).ToArgb().Equals(finishColor.ToArgb())); }
// Returns true if the node's pixel color is a wallColor public bool IsWallNode(MazeNode node) { // Dont need to check out of bounds since AddAllUnvisitedChildren does bounds checking return(maze.GetPixel(node.GetX(), node.GetY()).ToArgb().Equals(wallColor.ToArgb())); }