Improv
This commit is contained in:
6
main.go
6
main.go
@@ -8,9 +8,9 @@ import (
|
|||||||
"test-maze/mazer"
|
"test-maze/mazer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SIZE_X = 48
|
const SIZE_X = 61
|
||||||
const SIZE_Y = 48
|
const SIZE_Y = 61
|
||||||
const CELL_SCALE = 10
|
const CELL_SCALE = 1
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
matrix := mazer.GenerateMaze(SIZE_X, SIZE_Y)
|
matrix := mazer.GenerateMaze(SIZE_X, SIZE_Y)
|
||||||
|
|||||||
118
mazer/maze.go
118
mazer/maze.go
@@ -14,84 +14,78 @@ func GenerateMaze(width int, height int) [][]int {
|
|||||||
matrix[y] = cells[rowStart : rowStart+width]
|
matrix[y] = cells[rowStart : rowStart+width]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep a full black border: path only exists inside [1..width-2] x [1..height-2].
|
|
||||||
if width < 3 || height < 3 {
|
if width < 3 || height < 3 {
|
||||||
return matrix
|
return matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
startX, startY := 1, 1
|
startX, startY := 1, 1
|
||||||
endX, endY := width-2, height-2
|
matrix[startY][startX] = 1
|
||||||
|
|
||||||
parent := make([]int, width*height)
|
stackX := make([]int, 1, width*height/2)
|
||||||
for i := range parent {
|
stackY := make([]int, 1, width*height/2)
|
||||||
parent[i] = -1
|
stackX[0], stackY[0] = startX, startY
|
||||||
}
|
|
||||||
visited := make([]bool, width*height)
|
|
||||||
|
|
||||||
dx := [4]int{0, -1, 1, 0}
|
for len(stackX) > 0 {
|
||||||
dy := [4]int{1, 0, 0, -1}
|
last := len(stackX) - 1
|
||||||
|
x, y := stackX[last], stackY[last]
|
||||||
|
dirs := shuffledDirections()
|
||||||
|
|
||||||
type node struct {
|
carved := false
|
||||||
x int
|
for _, d := range dirs {
|
||||||
y int
|
dx, dy := 0, 0
|
||||||
dirs [4]uint8
|
switch d {
|
||||||
next int
|
case 0:
|
||||||
}
|
dy = -2
|
||||||
|
case 1:
|
||||||
|
dx = 2
|
||||||
|
case 2:
|
||||||
|
dy = 2
|
||||||
|
default:
|
||||||
|
dx = -2
|
||||||
|
}
|
||||||
|
|
||||||
stack := make([]node, 1, (width-2)*(height-2))
|
nx, ny := x+dx, y+dy
|
||||||
stack[0] = node{x: startX, y: startY, dirs: shuffledDirections()}
|
if nx <= 0 || nx >= width-1 || ny <= 0 || ny >= height-1 {
|
||||||
startIdx := startY*width + startX
|
continue
|
||||||
endIdx := endY*width + endX
|
}
|
||||||
visited[startIdx] = true
|
if matrix[ny][nx] == 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
found := false
|
matrix[y+dy/2][x+dx/2] = 1
|
||||||
for len(stack) > 0 {
|
matrix[ny][nx] = 1
|
||||||
last := len(stack) - 1
|
stackX = append(stackX, nx)
|
||||||
top := &stack[last]
|
stackY = append(stackY, ny)
|
||||||
|
carved = true
|
||||||
if top.x == endX && top.y == endY {
|
|
||||||
found = true
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if top.next == 4 {
|
if !carved {
|
||||||
stack = stack[:last]
|
stackX = stackX[:last]
|
||||||
continue
|
stackY = stackY[:last]
|
||||||
}
|
|
||||||
|
|
||||||
d := top.dirs[top.next]
|
|
||||||
top.next++
|
|
||||||
|
|
||||||
nx := top.x + dx[d]
|
|
||||||
ny := top.y + dy[d]
|
|
||||||
if nx <= 0 || nx >= width-1 || ny <= 0 || ny >= height-1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
nIdx := ny*width + nx
|
|
||||||
if visited[nIdx] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Entrance on top border at a random connected X.
|
||||||
|
topChoices := make([]int, 0, width/2)
|
||||||
|
for x := 1; x < width-1; x++ {
|
||||||
|
if matrix[1][x] == 1 {
|
||||||
|
topChoices = append(topChoices, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entranceX := topChoices[rand.IntN(len(topChoices))]
|
||||||
|
matrix[0][entranceX] = 1
|
||||||
|
|
||||||
|
// Exit on bottom border at a random connected X.
|
||||||
|
bottomChoices := make([]int, 0, width/2)
|
||||||
|
for x := 1; x < width-1; x++ {
|
||||||
|
if matrix[height-2][x] == 1 {
|
||||||
|
bottomChoices = append(bottomChoices, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exitX := bottomChoices[rand.IntN(len(bottomChoices))]
|
||||||
|
matrix[height-1][exitX] = 1
|
||||||
|
|
||||||
return matrix
|
return matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user