Source File: curse-you-go-rogue/02_mazes_and_enemies/maze.go

package main

import (
  "math/rand"
  "time"
)

func (game *Game) NeighborWalls(pos Position) []Position {
  neighbors := game.Neighbors(pos)
  result := make([]Position, 0)

  for _, at := range neighbors {
    cell := game.Level[at.Y][at.X]

    if cell == WALL {
      result = append(result, at)
    }
  }

  return result
}

func (game *Game) HuntNext(on *Position, found *Position) bool {
  for y := 1; y < game.Height ; y += 2 {
    for x := 1; x < game.Width ; x += 2 {
      if game.Level[y][x] != WALL {
        continue
      }

      neighbors := game.Neighbors(Position{x, y})

      for _, pos := range neighbors {
        if game.Level[pos.Y][pos.X] == SPACE {
          *on = Position{x, y}
          *found = pos
          return true
        }
      }
    }
  }

  return false
}

func (game *Game) HAKStep(from Position, to Position) {
  game.Level[from.Y][from.X] = SPACE
  row := (from.Y + to.Y) / 2
  col := (from.X + to.X) / 2
  game.Level[row][col] = SPACE
}

func (game *Game) NewMaze() []Position {
  on := Position{1, 1}
  found := Position{1,1}

  dead_ends := make([]Position, 0)

  for {
    neighbors := game.NeighborWalls(on)

    if len(neighbors) == 0 {
      dead_ends = append(dead_ends, on)

      if !game.HuntNext(&on, &found) {
        break
      }

      game.HAKStep(on, found)
    } else {
      rand_neighbor := rand.Int() % len(neighbors)
      nb := neighbors[rand_neighbor]
      game.HAKStep(nb, on)
      on = nb
    }

    if SHOW_RENDER {
      game.Render()
      time.Sleep(50 * time.Millisecond)
    }
  }

  return dead_ends
}