private static GraphicalMazePixel FindStartPixel(GraphicalMaze maze) { var startingY = 0; var endingY = maze.Height; var startingX = 0; var endingX = maze.Width; // Spiral iterate, since the start point is most likely on the outside of the maze while (startingY < endingY && startingX < endingX) { // Iterate over the first row from the remaining rows for (var x = startingX; x < endingX; x++) { if (maze.GetPixel(x, startingY).IsColor(maze.StartColor)) { return(maze.GetPixel(x, startingY)); } } startingY++; // Iterate over the last column from the remaining columns for (var y = startingY; y < endingY; y++) { if (maze.GetPixel(endingX - 1, y).IsColor(maze.StartColor)) { return(maze.GetPixel(endingX - 1, y)); } } endingX--; // Iterate over the last row from the remaining rows for (var x = startingX; x < endingX; x++) { if (maze.GetPixel(x, endingY - 1).IsColor(maze.StartColor)) { return(maze.GetPixel(x, endingY - 1)); } } endingY--; // Iterate over the first column from the remaining columns for (var y = startingY; y < endingY; y++) { if (maze.GetPixel(startingX, y).IsColor(maze.StartColor)) { return(maze.GetPixel(startingX, y)); } } startingX++; } return(null); }
public Image GenerateSolution(GraphicalMaze maze) { // Find start and end pixels Point startPoint = null; Point endPoint = null; for (var y = 0; y < maze.Height; y++) { for (var x = 0; x < maze.Width; x++) { var pixel = maze.GetPixel(x, y); if (pixel.IsColor(maze.StartColor)) { startPoint = pixel; } else if (pixel.IsColor(maze.FinishColor)) { endPoint = pixel; } } } if (startPoint == null || endPoint == null) { return(null); // No start or end points found } // Run best first search var path = BestFirstSearch(maze, startPoint, endPoint); if (path == null) { return(null); // No solution found } var solutionImage = new Bitmap(maze.MazeImage); foreach (var point in path) { solutionImage.SetPixel(point.X, point.Y, maze.SolutionColor); } solutionImage.SetPixel(startPoint.X, startPoint.Y, maze.StartColor); // Reapply start pixel color return(solutionImage); }
private static Tuple <GraphicalMazePixel, Direction, Direction> FollowWall(GraphicalMaze maze, Point currentPoint, Direction travelDirection, Direction wallDirection) { // Left-hand rule conditions only while (maze.GetPixel(currentPoint, travelDirection).IsColor(maze.WallColor)) { // Turn at interior corners switch (wallDirection) { case Direction.Up: travelDirection = Direction.Down; wallDirection = Direction.Right; break; case Direction.Right: travelDirection = Direction.Left; wallDirection = Direction.Down; break; case Direction.Down: travelDirection = Direction.Up; wallDirection = Direction.Left; break; case Direction.Left: travelDirection = Direction.Right; wallDirection = Direction.Up; break; default: throw new ArgumentOutOfRangeException(nameof(wallDirection), wallDirection, null); } } var nextPixel = maze.GetPixel(currentPoint, travelDirection); // Wrap-around if moving away from a wall switch (travelDirection) { case Direction.Up: if (!maze.GetPixel(nextPixel, Direction.Left).IsColor(maze.WallColor)) { travelDirection = Direction.Left; wallDirection = Direction.Down; } break; case Direction.Right: if (!maze.GetPixel(nextPixel, Direction.Up).IsColor(maze.WallColor)) { travelDirection = Direction.Up; wallDirection = Direction.Left; } break; case Direction.Down: if (!maze.GetPixel(nextPixel, Direction.Right).IsColor(maze.WallColor)) { travelDirection = Direction.Right; wallDirection = Direction.Up; } break; case Direction.Left: if (!maze.GetPixel(nextPixel, Direction.Down).IsColor(maze.WallColor)) { travelDirection = Direction.Down; wallDirection = Direction.Right; } break; default: throw new ArgumentOutOfRangeException(nameof(travelDirection), travelDirection, null); } return(new Tuple <GraphicalMazePixel, Direction, Direction>(nextPixel, travelDirection, wallDirection)); }