Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mazes
55 changes: 52 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,54 @@
# Mazes
# Mazes Chapter 3

Based on the book [Mazes for Programmers: Code Your Own Twisty Little Passages](https://pragprog.com/book/jbmaze/mazes-for-programmers)
Finding Solutions. We’ve learned how to populate our mazes. We can now use
Dijkstra’s Algorithm to find the shortest path.

All code are in the chapter branches
Done up to page 44, for now.

```
Binary Tree
+---+---+---+---+---+---+---+---+---+---+
| 0 1 2 3 4 5 6 7 8 9 |
+---+ +---+ +---+ + + +---+ +
| 3 2 | 5 4 | 7 6 | 7 | 8 | b a |
+ + +---+---+---+ +---+---+---+ +
| 4 | 3 | a 9 8 7 | e d c b |
+---+ +---+ +---+---+ + +---+ +
| 5 4 | b a | h g f | e | d c |
+---+---+---+ + + +---+---+ + +
| e d c b | i | h | g f e | d |
+---+---+ +---+ + + +---+ + +
| f e d | k j | i | h | g f | e |
+---+---+---+ +---+ +---+---+---+ +
| o n m l | k j | i h g f |
+ +---+ +---+ +---+ +---+ + +
| p | o n | m l | k j | i h | g |
+---+ +---+---+---+ +---+---+---+ +
| q p | o n m l | k j i h |
+ + +---+---+---+---+ +---+---+ +
| r | q | p o n m l | k j i |
+---+---+---+---+---+---+---+---+---+---+

Sidewinder
+---+---+---+---+---+---+---+---+---+---+
| 0 1 2 3 4 5 6 7 8 9 |
+---+ + +---+---+---+---+ +---+---+
| 3 2 | 3 4 5 6 7 | 8 9 a |
+ +---+---+ +---+ + + + +---+
| 4 | 7 6 5 | 8 7 | 8 | 9 | a b |
+ + +---+ +---+ +---+---+---+ +
| 5 | 8 | 7 6 7 | 8 9 a b | c |
+---+ + +---+---+ +---+ + +---+
| a 9 | 8 9 a | 9 a | b | c d |
+ +---+ + +---+ +---+---+ +---+
| b c | 9 | a | b a | f e d e |
+---+---+ +---+---+ + + +---+ +
| c b a b c | b | g | f | g f |
+ + + + + + +---+ +---+ +
| d | c | b | c | d | c | h g h | g |
+ + + + +---+---+---+---+---+ +
| e | d | c | d e | l k j i h |
+ + +---+ +---+ +---+ + + +
| f | e f | e f | m n | k | j | i |
+---+---+---+---+---+---+---+---+---+---+
```
29 changes: 29 additions & 0 deletions btree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"math/rand"
"time"
)

type BinaryTree struct{}

func (b *BinaryTree) On(g Grider) {
rand.Seed(time.Now().UnixNano())
for c := range g.EachCell() {
neighbors := make([]*Cell, 0)
if c.North != nil {
neighbors = append(neighbors, c.North)
}
if c.East != nil {
neighbors = append(neighbors, c.East)
}
l := len(neighbors)
if l != 0 {
i := rand.Intn(l)
neighbor := neighbors[i]
if neighbor != nil {
c.Link(neighbor, true)
}
}
}
}
92 changes: 92 additions & 0 deletions cell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package main

type Cell struct {
row, col int
North, South, East, West *Cell
links map[*Cell]bool
}

func NewCell(row, col int) *Cell {
c := new(Cell)
c.row, c.col = row, col
c.links = make(map[*Cell]bool)
return c
}

func (c Cell) Row() int {
return c.row
}

func (c Cell) Col() int {
return c.col
}

func (c *Cell) Link(cell *Cell, bidi bool) *Cell {
c.links[cell] = true

if bidi {
cell.Link(c, false)
}
return c
}

func (c *Cell) Unlink(cell *Cell, bidi bool) *Cell {
delete(c.links, cell)
if bidi {
cell.Unlink(c, false)
}
return c
}

func (c Cell) IsLinked(cell *Cell) bool {
for x := range c.links {
if x == cell {
return true
}
}
return false
}

func (c Cell) Links() []*Cell {
list := make([]*Cell, 0)
for x := range c.links {
list = append(list, x)
}
return list
}

func (c Cell) Neighbors() []*Cell {
list := make([]*Cell, 0)
if c.North != nil {
list = append(list, c.North)
}
if c.South != nil {
list = append(list, c.South)
}
if c.East != nil {
list = append(list, c.East)
}
if c.West != nil {
list = append(list, c.West)
}
return list
}

func (c *Cell) Distances() *Distances {
d := NewDistances(c)
frontier := []*Cell{c}
for len(frontier) != 0 { // frontier.any?
newFrontier := make([]*Cell, 0)
for _, cell := range frontier {
for _, link := range cell.Links() {
if link == c || d.Distance(link) > 0 {
continue
}
d.SetDistance(link, d.Distance(cell)+1)
newFrontier = append(newFrontier, link)
}
}
frontier = newFrontier
}
return d
}
64 changes: 64 additions & 0 deletions distancegrid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package main

import "strconv"

type DistanceGrid struct {
Grid
distances *Distances
}

func NewDistanceGrid(rows, cols int) *DistanceGrid {
g := new(DistanceGrid)
g.distances = new(Distances)
g.Rows, g.Cols = rows, cols
g.prepareGrid()
g.configureCells()
return g
}

func (d *DistanceGrid) SetDistances(distances *Distances) {
d.distances = distances
}

func (g *DistanceGrid) ContentsOf(cell *Cell) string {
return strconv.FormatInt(int64(g.distances.Distance(cell)), 36)
}

func (g *DistanceGrid) String() string {
output := "+"
for i := 0; i < g.Cols; i++ {
output += "---+"
}
output += "\n"

for r := range g.EachRow() {
top := "|"
bottom := "+"
for _, c := range r {
body := " " + g.ContentsOf(c) + " "
eastBoundary := ""
if c.IsLinked(c.East) {
eastBoundary = " "
} else {
eastBoundary = "|"
}
top += body
top += eastBoundary

southBoundary := ""
if c.IsLinked(c.South) {
southBoundary = " "
} else {
southBoundary = "---"
}

corner := "+"
bottom += southBoundary
bottom += corner
}
output += top + "\n"
output += bottom + "\n"
}

return output
}
30 changes: 30 additions & 0 deletions distances.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

type Distances struct {
root *Cell
cells map[*Cell]int
}

func NewDistances(root *Cell) *Distances {
d := new(Distances)
d.root = root
d.cells = make(map[*Cell]int)
d.cells[root] = 0
return d
}

func (d *Distances) Cells() []*Cell {
cells := make([]*Cell, len(d.cells))
for k, v := range d.cells {
cells[v] = k
}
return cells
}

func (d *Distances) Distance(cell *Cell) int {
return d.cells[cell]
}

func (d *Distances) SetDistance(cell *Cell, distance int) {
d.cells[cell] = distance
}
Loading