diff --git a/main.go b/main.go index a36c3ad..c25e8f1 100644 --- a/main.go +++ b/main.go @@ -8,17 +8,24 @@ import ( "test-maze/mazer" ) -const SIZE_X = 61 -const SIZE_Y = 61 +const SIZE_X = 13 +const SIZE_Y = 13 const CELL_SCALE = 1 +const COLOR_SOLUTION_PATH = true func main() { matrix := mazer.GenerateMaze(SIZE_X, SIZE_Y) + var solutionPath [][]bool + if COLOR_SOLUTION_PATH { + solutionPath = mazer.FindSolutionPath(matrix) + } + img := image.NewRGBA(image.Rect(0, 0, SIZE_X*CELL_SCALE, SIZE_Y*CELL_SCALE)) white := color.RGBA{R: 255, G: 255, B: 255, A: 255} black := color.RGBA{R: 0, G: 0, B: 0, A: 255} + green := color.RGBA{R: 0, G: 180, B: 0, A: 255} for cellY := 0; cellY < SIZE_Y; cellY++ { startY := cellY * CELL_SCALE @@ -28,6 +35,9 @@ func main() { p := black if matrix[cellY][cellX] == 1 { p = white + if COLOR_SOLUTION_PATH && solutionPath != nil && solutionPath[cellY][cellX] { + p = green + } } for dy := 0; dy < CELL_SCALE; dy++ { diff --git a/mazer/maze.go b/mazer/maze.go index dff63c7..6352f87 100644 --- a/mazer/maze.go +++ b/mazer/maze.go @@ -89,6 +89,99 @@ func GenerateMaze(width int, height int) [][]int { return matrix } +func FindSolutionPath(matrix [][]int) [][]bool { + height := len(matrix) + if height == 0 { + return nil + } + width := len(matrix[0]) + if width == 0 { + return nil + } + + startX := -1 + endX := -1 + for x := 0; x < width; x++ { + if matrix[0][x] == 1 { + startX = x + break + } + } + for x := 0; x < width; x++ { + if matrix[height-1][x] == 1 { + endX = x + break + } + } + if startX == -1 || endX == -1 { + return nil + } + + start := startX + end := (height-1)*width + endX + parent := make([]int, width*height) + for i := range parent { + parent[i] = -1 + } + visited := make([]bool, width*height) + queue := make([]int, 1, width*height) + queue[0] = start + visited[start] = true + + dx := [4]int{0, 1, 0, -1} + dy := [4]int{-1, 0, 1, 0} + + found := false + for head := 0; head < len(queue); head++ { + idx := queue[head] + if idx == end { + found = true + break + } + + x := idx % width + y := idx / width + for i := 0; i < 4; i++ { + nx := x + dx[i] + ny := y + dy[i] + if nx < 0 || nx >= width || ny < 0 || ny >= height { + continue + } + if matrix[ny][nx] == 0 { + continue + } + + nIdx := ny*width + nx + if visited[nIdx] { + continue + } + visited[nIdx] = true + parent[nIdx] = idx + queue = append(queue, nIdx) + } + } + + if !found { + return nil + } + + pathCells := make([]bool, width*height) + for idx := end; idx != -1; idx = parent[idx] { + pathCells[idx] = true + if idx == start { + break + } + } + + path := make([][]bool, height) + for y := 0; y < height; y++ { + rowStart := y * width + path[y] = pathCells[rowStart : rowStart+width] + } + + return path +} + func shuffledDirections() [4]uint8 { dirs := [4]uint8{0, 1, 2, 3} for i := 3; i > 0; i-- {