bool[,] passible; using (var img = (Bitmap)Bitmap.FromFile("Data//maze.png")) { passible = new bool[img.Width, img.Height]; for (int x = 0; x < img.Width; x++) { for (int y = 0; y < img.Height; y++) { if (x < 60 && y < 60) continue; passible[x, y] = (img.GetPixel(x, y).ToArgb() != Color.White.ToArgb()); } } } int width = passible.GetLength(0); int height = passible.GetLength(1); int curX = width - 2; int curY = 0; var path = new Stack(); var searched = new bool[width, height]; //int searchCount = 0; //int totalSearchCount = (width - 60) * (height - 60); while (true) { if (curX == 1 && curY == 640) break; if (!searched[curX, curY]) { searched[curX, curY] = true; path.Push(new Point(curX, curY)); //searchCount++; //if (searchCount % 1000 == 0) //{ // Console.CursorLeft = 0; // Console.Write("{0:#0%}", (float)searchCount / (float)totalSearchCount); //} } if (curY > 0 && passible[curX, curY - 1] && !searched[curX, curY - 1]) { curY--; continue; } if (curY < height - 1 && passible[curX, curY + 1] && !searched[curX, curY + 1]) { curY++; continue; } if (curX > 0 && passible[curX - 1, curY] && !searched[curX - 1, curY]) { curX--; continue; } if (curX < width - 1 && passible[curX + 1, curY] && !searched[curX + 1, curY]) { curX++; continue; } var lastPoint = path.Pop(); // <<< "stack empty" exception thrown curX = lastPoint.X; curY = lastPoint.Y; } using (var img = (Bitmap)Bitmap.FromFile("Data//maze.png")) { foreach (var point in path) img.SetPixel(point.X, point.Y, Color.Blue); img.Save("Data//maze_solved.png", ImageFormat.Png); } Console.CursorLeft = 0; Console.WriteLine("Done!");