From 42029cdfec9474bcb65817d6b2809fb90d271176 Mon Sep 17 00:00:00 2001 From: Daniel Legt Date: Wed, 25 Feb 2026 21:47:27 +0200 Subject: [PATCH] Stuff --- .gitignore | 1 + main.go | 37 +++++++---- mazer/maze.go | 173 ++++++++++++++++++++++---------------------------- stripes.png | Bin 5357 -> 0 bytes 4 files changed, 103 insertions(+), 108 deletions(-) create mode 100644 .gitignore delete mode 100644 stripes.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..95e60b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +maze.png \ No newline at end of file diff --git a/main.go b/main.go index 6baab47..212d104 100644 --- a/main.go +++ b/main.go @@ -5,32 +5,45 @@ import ( "image/color" "image/png" "os" + "test-maze/mazer" ) -const SIZE_X = 128 -const SIZE_Y = 128 -const CELL_SIZE = 16 -const CELL_SCALE = 8 +const SIZE_X = 48 +const SIZE_Y = 48 +const CELL_SCALE = 10 func main() { + matrix := mazer.GenerateMaze(SIZE_X, SIZE_Y) 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} - for y := 0; y < SIZE_Y*CELL_SCALE; y++ { - for x := 0; x < SIZE_X*CELL_SCALE; x++ { - stripeIndex := (x / CELL_SIZE) % 2 - if stripeIndex == 0 { - img.SetRGBA(x, y, white) - } else { - img.SetRGBA(x, y, black) + for cellY := 0; cellY < SIZE_Y; cellY++ { + startY := cellY * CELL_SCALE + for cellX := 0; cellX < SIZE_X; cellX++ { + startX := cellX * CELL_SCALE + + p := black + if matrix[cellY][cellX] == 1 { + p = white + } + + for dy := 0; dy < CELL_SCALE; dy++ { + row := img.Pix[(startY+dy)*img.Stride:] + for dx := 0; dx < CELL_SCALE; dx++ { + offset := (startX + dx) * 4 + row[offset+0] = p.R + row[offset+1] = p.G + row[offset+2] = p.B + row[offset+3] = p.A + } } } } - f, err := os.Create("stripes.png") + f, err := os.Create("maze.png") if err != nil { panic(err) } diff --git a/mazer/maze.go b/mazer/maze.go index 5667b6c..71aa67f 100644 --- a/mazer/maze.go +++ b/mazer/maze.go @@ -1,124 +1,105 @@ package mazer -import ( - "math/rand/v2" -) +import "math/rand/v2" -func GenerateMaze(width int, height int) { +func GenerateMaze(width int, height int) [][]int { + if width <= 0 || height <= 0 { + return [][]int{} + } - // Init array + cells := make([]int, width*height) matrix := make([][]int, height) - // 2. Allocate each inner slice (width) - for i := range matrix { - matrix[i] = make([]int, width) + for y := 0; y < height; y++ { + rowStart := y * width + matrix[y] = cells[rowStart : rowStart+width] } - startPoint := rand.IntN(width + 1) - matrix[0][startPoint] = 1 - - // Start moving until out of moves - -} - -func pickRandomDirection(matrix [][]int, posX int, posY int) []int { - height := len(matrix) - if posY == height-1 { - return nil + // Keep a full black border: path only exists inside [1..width-2] x [1..height-2]. + if width < 3 || height < 3 { + return matrix } - validDirs := getValidDirections(matrix, posX, posY) - if len(validDirs) == 0 { - return []int{0, 1} + startX, startY := 1, 1 + endX, endY := width-2, height-2 + + parent := make([]int, width*height) + for i := range parent { + parent[i] = -1 + } + visited := make([]bool, width*height) + + dx := [4]int{0, -1, 1, 0} + dy := [4]int{1, 0, 0, -1} + + type node struct { + x int + y int + dirs [4]uint8 + next int } - return validDirs[rand.IntN(len(validDirs))] -} + stack := make([]node, 1, (width-2)*(height-2)) + stack[0] = node{x: startX, y: startY, dirs: shuffledDirections()} + startIdx := startY*width + startX + endIdx := endY*width + endX + visited[startIdx] = true -func getValidDirections(matrix [][]int, posX int, posY int) [][]int { - height := len(matrix) - width := len(matrix[0]) - validDirs := make([][]int, 0, 4) + found := false + for len(stack) > 0 { + last := len(stack) - 1 + top := &stack[last] - possibleDirs := [][]int{ - {0, 1}, // Down - {-1, 0}, // Left - {1, 0}, // Right - {0, -1}, // Up - } - prevX, prevY, hasPrev := getPreviousPathCell(matrix, posX, posY) - if hasPrev && prevX == posX && prevY == posY+1 { - // If we just moved up, force the next step to be side/down (no repeated up). - possibleDirs = [][]int{ - {-1, 0}, // Left - {1, 0}, // Right - {0, 1}, // Down + if top.x == endX && top.y == endY { + found = true + break } - } - neighborDirs := [][]int{ - {0, -1}, - {0, 1}, - {-1, 0}, - {1, 0}, - } - - for _, dir := range possibleDirs { - newX := posX + dir[0] - newY := posY + dir[1] - - if newX < 0 || newX >= width || newY < 0 || newY >= height { - continue - } - if matrix[newY][newX] == 1 { + if top.next == 4 { + stack = stack[:last] continue } - tooClose := false - for _, neighborDir := range neighborDirs { - neighborX := newX + neighborDir[0] - neighborY := newY + neighborDir[1] + d := top.dirs[top.next] + top.next++ - if neighborX < 0 || neighborX >= width || neighborY < 0 || neighborY >= height { - continue - } - if neighborX == posX && neighborY == posY { - continue - } - if matrix[neighborY][neighborX] == 1 { - tooClose = true - break - } - } - if tooClose { + nx := top.x + dx[d] + ny := top.y + dy[d] + if nx <= 0 || nx >= width-1 || ny <= 0 || ny >= height-1 { continue } - validDirs = append(validDirs, dir) - } - - return validDirs -} - -func getPreviousPathCell(matrix [][]int, posX int, posY int) (int, int, bool) { - height := len(matrix) - width := len(matrix[0]) - dirs := [][]int{ - {0, -1}, - {0, 1}, - {-1, 0}, - {1, 0}, - } - - for _, dir := range dirs { - x := posX + dir[0] - y := posY + dir[1] - if x < 0 || x >= width || y < 0 || y >= height { + nIdx := ny*width + nx + if visited[nIdx] { continue } - if matrix[y][x] == 1 { - return x, y, true + + visited[nIdx] = true + parent[nIdx] = top.y*width + top.x + stack = append(stack, node{x: nx, y: ny, dirs: shuffledDirections()}) + } + + if !found { + matrix[startY][startX] = 1 + return matrix + } + + for idx := endIdx; idx != -1; idx = parent[idx] { + x := idx % width + y := idx / width + matrix[y][x] = 1 + if idx == startIdx { + break } } - return 0, 0, false + return matrix +} + +func shuffledDirections() [4]uint8 { + dirs := [4]uint8{0, 1, 2, 3} + for i := 3; i > 0; i-- { + j := rand.IntN(i + 1) + dirs[i], dirs[j] = dirs[j], dirs[i] + } + return dirs } diff --git a/stripes.png b/stripes.png deleted file mode 100644 index d1df6801955e514a9944fa67fee127db6e711a45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5357 zcmeAS@N?(olHy`uVBq!ia0y~yU;#2&7&w@K)Q9>#R~Q&Xws^WYhE&XXbA2Okg98tX zquj;%)63Y>7tHPSpZ?z1`1&!+^sV3D-``*V|KH!=K*s;_fA6nKF);ivWds_c2r|hD zWNHfskl+vm5&}v