diff --git a/00_Alternate_Languages/02_Amazing/go/main.go b/00_Alternate_Languages/02_Amazing/go/main.go new file mode 100644 index 00000000..11b027ef --- /dev/null +++ b/00_Alternate_Languages/02_Amazing/go/main.go @@ -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 +}