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() } }