mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-12 07:40:50 -08:00
Added go for Amazing
This commit is contained in:
217
00_Alternate_Languages/02_Amazing/go/main.go
Normal file
217
00_Alternate_Languages/02_Amazing/go/main.go
Normal file
@@ -0,0 +1,217 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
printWelcome()
|
||||
|
||||
h, w := getDimensions()
|
||||
m := NewMaze(h, w)
|
||||
m.draw()
|
||||
}
|
||||
|
||||
type direction int64
|
||||
|
||||
const (
|
||||
LEFT direction = iota
|
||||
UP
|
||||
RIGHT
|
||||
DOWN
|
||||
)
|
||||
|
||||
const (
|
||||
EXIT_DOWN = 1
|
||||
EXIT_RIGHT = 2
|
||||
)
|
||||
|
||||
type maze struct {
|
||||
width int
|
||||
length int
|
||||
used [][]int
|
||||
walls [][]int
|
||||
enterCol int
|
||||
}
|
||||
|
||||
func NewMaze(w, l int) maze {
|
||||
if (w < 2) || (l < 2) {
|
||||
log.Fatal("invalid dimensions supplied")
|
||||
}
|
||||
|
||||
m := maze{width: w, length: l}
|
||||
|
||||
m.used = make([][]int, l)
|
||||
for i := range m.used {
|
||||
m.used[i] = make([]int, w)
|
||||
}
|
||||
|
||||
m.walls = make([][]int, l)
|
||||
for i := range m.walls {
|
||||
m.walls[i] = make([]int, w)
|
||||
}
|
||||
|
||||
// randomly determine the entry column
|
||||
m.enterCol = rand.Intn(w)
|
||||
|
||||
// determine layout of walls
|
||||
m.build()
|
||||
|
||||
// add an exit
|
||||
col := rand.Intn(m.width - 1)
|
||||
row := m.length - 1
|
||||
m.walls[row][col] = m.walls[row][col] + 1
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *maze) build() {
|
||||
row := 0
|
||||
col := 0
|
||||
count := 2
|
||||
|
||||
for {
|
||||
possibleDirs := m.getPossibleDirections(row, col)
|
||||
|
||||
if len(possibleDirs) != 0 {
|
||||
row, col, count = m.makeOpening(possibleDirs, row, col, count)
|
||||
} else {
|
||||
for {
|
||||
if col != m.width-1 {
|
||||
col = col + 1
|
||||
} else if row != m.length-1 {
|
||||
row = row + 1
|
||||
col = 0
|
||||
} else {
|
||||
row = 0
|
||||
col = 0
|
||||
}
|
||||
|
||||
if m.used[row][col] != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if count == (m.width*m.length)+1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (m *maze) getPossibleDirections(row, col int) []direction {
|
||||
possible_dirs := make(map[direction]bool, 4)
|
||||
possible_dirs[LEFT] = true
|
||||
possible_dirs[UP] = true
|
||||
possible_dirs[RIGHT] = true
|
||||
possible_dirs[DOWN] = true
|
||||
|
||||
if (col == 0) || (m.used[row][col-1] != 0) {
|
||||
possible_dirs[LEFT] = false
|
||||
}
|
||||
if (row == 0) || (m.used[row-1][col] != 0) {
|
||||
possible_dirs[UP] = false
|
||||
}
|
||||
if (col == m.width-1) || (m.used[row][col+1] != 0) {
|
||||
possible_dirs[RIGHT] = false
|
||||
}
|
||||
if (row == m.length-1) || (m.used[row+1][col] != 0) {
|
||||
possible_dirs[DOWN] = false
|
||||
}
|
||||
|
||||
ret := make([]direction, 0)
|
||||
for d, v := range possible_dirs {
|
||||
if v {
|
||||
ret = append(ret, d)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (m *maze) makeOpening(dirs []direction, row, col, count int) (int, int, int) {
|
||||
dir := rand.Intn(len(dirs))
|
||||
|
||||
if dirs[dir] == LEFT {
|
||||
col = col - 1
|
||||
m.walls[row][col] = int(EXIT_RIGHT)
|
||||
} else if dirs[dir] == UP {
|
||||
row = row - 1
|
||||
m.walls[row][col] = int(EXIT_DOWN)
|
||||
} else if dirs[dir] == RIGHT {
|
||||
m.walls[row][col] = m.walls[row][col] + EXIT_RIGHT
|
||||
col = col + 1
|
||||
} else if dirs[dir] == DOWN {
|
||||
m.walls[row][col] = m.walls[row][col] + EXIT_DOWN
|
||||
row = row + 1
|
||||
}
|
||||
|
||||
m.used[row][col] = count
|
||||
count = count + 1
|
||||
return row, col, count
|
||||
}
|
||||
|
||||
// draw the maze
|
||||
func (m *maze) draw() {
|
||||
for col := 0; col < m.width; col++ {
|
||||
if col == m.enterCol {
|
||||
fmt.Print(". ")
|
||||
} else {
|
||||
fmt.Print(".--")
|
||||
}
|
||||
}
|
||||
fmt.Println(".")
|
||||
|
||||
for row := 0; row < m.length; row++ {
|
||||
fmt.Print("|")
|
||||
for col := 0; col < m.width; col++ {
|
||||
if m.walls[row][col] < 2 {
|
||||
fmt.Print(" |")
|
||||
} else {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
for col := 0; col < m.width; col++ {
|
||||
if (m.walls[row][col] == 0) || (m.walls[row][col] == 2) {
|
||||
fmt.Print(":--")
|
||||
} else {
|
||||
fmt.Print(": ")
|
||||
}
|
||||
}
|
||||
fmt.Println(".")
|
||||
}
|
||||
}
|
||||
|
||||
func printWelcome() {
|
||||
fmt.Println(" AMAZING PROGRAM")
|
||||
fmt.Print(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
|
||||
}
|
||||
|
||||
func getDimensions() (int, int) {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
|
||||
fmt.Println("Enter a width ( > 1 ):")
|
||||
scanner.Scan()
|
||||
w, err := strconv.Atoi(scanner.Text())
|
||||
if err != nil {
|
||||
log.Fatal("invalid dimension")
|
||||
}
|
||||
|
||||
fmt.Println("Enter a height ( > 1 ):")
|
||||
scanner.Scan()
|
||||
h, err := strconv.Atoi(scanner.Text())
|
||||
if err != nil {
|
||||
log.Fatal("invalid dimension")
|
||||
}
|
||||
|
||||
return w, h
|
||||
}
|
||||
Reference in New Issue
Block a user