Skip to content

Instantly share code, notes, and snippets.

@cgdangelo
Last active April 6, 2018 18:53
Show Gist options
  • Save cgdangelo/b93803013890ecf51486477317065333 to your computer and use it in GitHub Desktop.
Save cgdangelo/b93803013890ecf51486477317065333 to your computer and use it in GitHub Desktop.
import (
"fmt"
"gonum.org/v1/gonum/mat"
"math/rand"
)
const (
NORTH = iota
EAST
SOUTH
WEST
)
const (
EMPTY = 1 << iota
WALL
GOAL
)
type Point struct {
x, y int
}
type Automaton struct {
pos *Point
prevPos *Point
maze *mat.Dense
findNextPoint func(a *Automaton) *Point
}
func (a *Automaton) Move() {
p := a.findNextPoint(a)
a.prevPos = a.pos
a.pos = p
}
func NewMaze(r, c, w int) *mat.Dense {
maze := mat.NewDense(r, c, nil)
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
goal := rng.Intn(c)
maze.Set(r-1, goal, GOAL)
fmt.Printf("Goal: (%d, %d)\n\n", goal, r-1)
for cw := 0; cw < w; {
wx := rng.Intn(c)
wy := rng.Intn(r)
if wx == wy && wx == 0 {
continue
}
if maze.At(wy, wx) == GOAL {
continue
}
maze.Set(wy, wx, WALL)
cw++
}
return maze
}
func (p *Point) Diff(p1 *Point) (int, int) {
return p.x - p1.x, p.y - p1.y
}
func RandomAF(a *Automaton) *Point {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
dx := rng.Intn(3) - 1
dy := rng.Intn(3) - 1
nx := a.pos.x + dx
ny := a.pos.y + dy
r, c := a.maze.Dims()
if nx >= c || nx < 0 {
return RandomAF(a)
}
if ny >= r || ny < 0 {
return RandomAF(a)
}
return &Point{nx, ny}
}
func main() {
m := NewMaze(10, 10, 12)
a := &Automaton{maze: m, pos: &Point{0, 0}, findNextPoint: RandomAF}
var i int
for a.maze.At(a.pos.y, a.pos.x) != GOAL {
a.Move()
i++
fmt.Printf("(%d, %d) -> (%d, %d) in %d moves\n", a.prevPos.x, a.prevPos.y, a.pos.x, a.pos.y, i)
}
fmt.Printf("\n(0, 0) -> (%d, %d) in %d moves\n", a.pos.x, a.pos.y, i)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment