Skip to content

Instantly share code, notes, and snippets.

@iamjwc
Last active October 16, 2015 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iamjwc/8bc7fb219616c5336d60 to your computer and use it in GitHub Desktop.
Save iamjwc/8bc7fb219616c5336d60 to your computer and use it in GitHub Desktop.
// go-race
// width: `tput cols`
// height: `tput lines`
// Our generated maze needs to be just less than 1/2 the size of our
// terminal size, so we can have room to print walls.
//
// Each cell is an integer. Each wall on the cell (N, E, S, W) are
// represented by a bit. If a wall exists only on the north side,
// our cell value is 8=b1000. If we have walls on all sides but north,
// our value is 7=b0111.
// fmt.Print("▒")
package main
import (
"fmt"
"log"
"os"
"os/exec"
"time"
"strconv"
"strings"
"math/rand"
)
const NORTH int = 1
const EAST int = 2
const SOUTH int = 4
const WEST int = 8
var DX = map[int]int{
EAST: 1, WEST: -1, NORTH: 0, SOUTH: 0,
}
var DY = map[int]int{
EAST: 0, WEST: 0, NORTH: -1, SOUTH: 1,
}
var OPPOSITE = map[int]int{
EAST: WEST, WEST: EAST, NORTH: SOUTH, SOUTH: NORTH,
}
func randomly_sort_slice(arr []int) []int{
for i := range arr {
j := rand.Intn(i + 1)
arr[i], arr[j] = arr[j], arr[i]
}
return arr
}
func carve_passages_from(x int, y int, width int, height int, maze [][]int){
//d :=[]int{NORTH, SOUTH, EAST, WEST}
//directions := randomly_sort_slice(d)
directions := randomly_sort_slice([]int{NORTH, SOUTH, EAST, WEST})
for i := range directions {
direction := directions[i]
nx := x + DX[direction]
ny := y + DY[direction]
if ny >= 0 && ny <= height-1 && nx >= 0 && nx <= width-1 && maze[ny][nx] == 0 {
maze[y][x] = maze[y][x] | direction
maze[ny][nx] = maze[ny][nx] | OPPOSITE[direction]
carve_passages_from(nx, ny, width, height, maze)
}
}
}
func print_maze(width int, height int, maze [][]int) {
fmt.Println(" " + strings.Repeat("_", width * 2 - 1))
for y := 0; y < height; y++ {
fmt.Print("|")
for x := 0; x < width; x++ {
if maze[y][x] & SOUTH == 0 {
fmt.Print("_")
} else {
fmt.Print(" ")
}
if maze[y][x] & EAST == 0 {
fmt.Print("|")
} else {
//fmt.Print(" ")
cell_or_cell_to_right := maze[y][x]
if x < width-1 {
cell_or_cell_to_right = cell_or_cell_to_right | maze[y][x+1]
}
if cell_or_cell_to_right & SOUTH == 0 {
fmt.Print("_")
} else {
fmt.Print(" ")
}
}
}
fmt.Print("\n")
}
}
func main() {
rand.Seed( time.Now().UTC().UnixNano())
term_height, term_width := height_and_width()
//term_height = 40
//term_width = 40
term_height = term_height / 2 - 1
term_width = term_width - 1
term_height, term_width = term_width, term_height
maze := generate_maze(term_height, term_width)
carve_passages_from(0, 0, term_width, term_height, maze)
print_maze(term_width, term_height, maze)
}
func generate_maze(height int, width int) [][]int {
arr := make([][]int, height) // One row per unit of y.
for i := range arr {
arr[i] = make([]int, width)
for j := range arr[i] {
arr[i][j] = 0
}
}
return arr
}
func height_and_width() (int, int) {
cmd := exec.Command("stty", "size")
cmd.Stdin = os.Stdin
out, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
width_and_height := strings.Split(strings.Trim(string(out), "\n"), " ")
width, _ := strconv.Atoi(width_and_height[0])
height, _ := strconv.Atoi(width_and_height[1])
return height, width
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment