176 lines
2.8 KiB
Go
176 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
|
)
|
|
|
|
const (
|
|
DIR_N = '^'
|
|
DIR_E = '>'
|
|
DIR_S = 'v'
|
|
DIR_W = '<'
|
|
)
|
|
|
|
func walk() {
|
|
bot := NewBot(layout)
|
|
for {
|
|
x, y := bot.GetNextSpot()
|
|
if bot.CanMove() && !bot.LastCoordWas(x, y) {
|
|
bot.Move()
|
|
} else {
|
|
bot.TurnLeft()
|
|
if bot.turns == 4 {
|
|
break
|
|
}
|
|
}
|
|
fmt.Print(helpers.CLEAR_SCREEN)
|
|
fmt.Println(bot.pathCoords)
|
|
bot.PrintLayout()
|
|
time.Sleep(time.Second / 10)
|
|
}
|
|
fmt.Println(bot.path)
|
|
}
|
|
|
|
type Bot struct {
|
|
X, Y int
|
|
Dir byte
|
|
layout [][]byte
|
|
path string
|
|
pathCoords []*helpers.Coordinate
|
|
turns int
|
|
moves int
|
|
}
|
|
|
|
func NewBot(layout [][]byte) *Bot {
|
|
b := &Bot{layout: layout}
|
|
// Find the bot
|
|
for y := range b.layout {
|
|
for x := range b.layout[y] {
|
|
if isBot(b.layout[y][x]) {
|
|
b.X = x
|
|
b.Y = y
|
|
b.Dir = b.layout[y][x]
|
|
b.layout[y][x] = '#'
|
|
}
|
|
}
|
|
}
|
|
return b
|
|
}
|
|
|
|
func (b *Bot) Visited(x, y int) bool {
|
|
for _, v := range b.pathCoords {
|
|
if v.X == x && v.Y == y {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (b *Bot) LastCoordWas(x, y int) bool {
|
|
if len(b.pathCoords) == 0 {
|
|
return false
|
|
}
|
|
c := b.pathCoords[len(b.pathCoords)-1]
|
|
return c.X == x && c.Y == y
|
|
}
|
|
|
|
func (b *Bot) Move() bool {
|
|
if !b.CanMove() {
|
|
return false
|
|
}
|
|
b.pathCoords = append(b.pathCoords, helpers.NewCoordinate(b.X, b.Y))
|
|
b.X, b.Y = b.GetNextSpot()
|
|
if b.turns == 1 { // Left Turn
|
|
b.path = b.path + ",L"
|
|
} else if b.turns == 3 { // Right Turn
|
|
b.path = b.path + ",R"
|
|
}
|
|
b.moves++
|
|
b.turns = 0
|
|
return true
|
|
}
|
|
|
|
func (b *Bot) GetNextSpot() (int, int) {
|
|
testX, testY := b.X, b.Y
|
|
switch b.Dir {
|
|
case DIR_N:
|
|
testY--
|
|
case DIR_E:
|
|
testX++
|
|
case DIR_S:
|
|
testY++
|
|
case DIR_W:
|
|
testX--
|
|
}
|
|
return testX, testY
|
|
}
|
|
|
|
func (b *Bot) CanMove() bool {
|
|
x, y := b.GetNextSpot()
|
|
if y < 0 || y >= len(b.layout) {
|
|
return false
|
|
}
|
|
if x < 0 || x >= len(b.layout[y]) {
|
|
return false
|
|
}
|
|
return b.layout[y][x] == '#'
|
|
}
|
|
|
|
func (b *Bot) TurnLeft() {
|
|
switch b.Dir {
|
|
case DIR_N:
|
|
b.Dir = DIR_W
|
|
case DIR_E:
|
|
b.Dir = DIR_N
|
|
case DIR_S:
|
|
b.Dir = DIR_E
|
|
case DIR_W:
|
|
b.Dir = DIR_S
|
|
}
|
|
b.turns++
|
|
if b.moves > 0 {
|
|
b.path = b.path + "," + helpers.Itoa(b.moves)
|
|
b.moves = 0
|
|
}
|
|
}
|
|
|
|
func (b *Bot) TurnRight() {
|
|
switch b.Dir {
|
|
case DIR_N:
|
|
b.Dir = DIR_E
|
|
case DIR_E:
|
|
b.Dir = DIR_S
|
|
case DIR_S:
|
|
b.Dir = DIR_W
|
|
case DIR_W:
|
|
b.Dir = DIR_N
|
|
}
|
|
b.turns++
|
|
if b.moves > 0 {
|
|
b.path = b.path + "," + helpers.Itoa(b.moves)
|
|
b.moves = 0
|
|
}
|
|
}
|
|
|
|
func isBot(b byte) bool {
|
|
return b == DIR_N || b == DIR_E || b == DIR_S || b == DIR_W
|
|
}
|
|
|
|
func (b *Bot) PrintLayout() {
|
|
for y := range b.layout {
|
|
for x := range b.layout[y] {
|
|
if x == b.X && y == b.Y {
|
|
fmt.Print(string(b.Dir))
|
|
} else if b.Visited(x, y) {
|
|
fmt.Print("█")
|
|
} else {
|
|
fmt.Print(string(b.layout[y][x]))
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
}
|