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 }