adventofcode/2019/day15/main.go

148 lines
3.2 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
var auto bool
var maze *Maze
func main() {
progFileName := "input"
if len(os.Args) > 1 && os.Args[1] == "-auto" {
auto = true
}
prog := intcode.ReadIntCodeFile(progFileName)
maze = NewMaze()
play(prog)
}
func play(prog []int) {
p := intcode.NewProgram(prog)
go func() {
var roadTaken []helpers.Coordinate
for {
time.Sleep(500)
fmt.Println(helpers.CLEAR_SCREEN)
maze.Print()
for !p.NeedsInput() {
time.Sleep(1)
}
var movingDir int
var moveToCoord *helpers.Coordinate
if auto {
var picked bool
directions := []int{DIR_N, DIR_E, DIR_S, DIR_W}
// If we have an unexplored location, try it
for _, tryDir := range directions {
v := maze.GetCoord(maze.GetDirFromBot(tryDir))
if v == MAZE_UNKNOWN {
movingDir = tryDir
picked = true
break
}
}
if !picked {
movingDir = maze.GetDirectionToLast()
if movingDir == -1 {
fmt.Println("Maze Created")
p.ForceQuit()
return
}
picked = true
}
moveToCoord = maze.GetDirFromBot(movingDir)
} else {
for movingDir == 0 {
fmt.Print("Input (vimlike): ")
reader := bufio.NewReader(os.Stdin)
inp, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
inp = strings.TrimSpace(inp)
switch inp {
case "h": // West
movingDir = DIR_W
moveToCoord = maze.bot.GetWestCoord()
case "j": // South
movingDir = DIR_S
moveToCoord = maze.bot.GetSouthCoord()
case "k": // North
movingDir = DIR_N
moveToCoord = maze.bot.GetNorthCoord()
case "l": // East
movingDir = DIR_E
moveToCoord = maze.bot.GetEastCoord()
}
}
}
p.Input(movingDir)
for !p.NeedsOutput() {
time.Sleep(1)
}
moveRes := p.Output()
maze.SetCoord(moveToCoord, moveRes)
switch moveRes {
case 1, 2: // Moved
roadTaken = append(roadTaken, *maze.bot)
maze.MoveBot(movingDir)
}
if p.State() == intcode.RET_DONE || p.State() == intcode.RET_ERR {
break
}
}
}()
p.Run()
//We force quit the program when the maze is built.
// Now we find the quickest path through the maze.
fmt.Println(helpers.CLEAR_SCREEN)
maze.Print()
fmt.Println("Now find shortest path")
done, ret := BFS(maze.bfs[maze.startCoord], maze.bfs[maze.o2Coord])
if done {
fmt.Println("Found Route")
} else {
fmt.Println("No Route Found")
}
fmt.Println("Steps:", len(ret))
}
func BFS(start, goal *BFSNode) (bool, []*BFSNode) {
var queue, explored []*BFSNode
queue = append(queue, start)
if start == goal {
return true, queue
}
explored = append(explored, start)
for len(queue) > 0 {
var current *BFSNode
if len(queue) > 1 {
current, queue = queue[0], queue[1:]
if current == goal {
return true, explored
} else {
children := current.getChildren()
if len(children) != 0 {
queue = append(queue, children...)
} else {
return false, explored
}
}
}
explored = append(explored, current)
}
return false, explored
}