package main import ( "bufio" "fmt" "os" "time" termbox "github.com/nsf/termbox-go" ) const ( N = iota E S W ERR ) var network [][]byte var message string var ticks int var nodes []byte var width, height int var printMap bool func main() { // Grab the window size if len(os.Args) > 1 { if os.Args[1] == "-print" { fmt.Println("Not working right now... Sorry.") os.Exit(1) printMap = true } } if err := termbox.Init(); err != nil { panic(err) } go func() { for { event := termbox.PollEvent() if event.Key == termbox.KeyCtrlC { termbox.Close() os.Exit(0) } } }() width, height = termbox.Size() network = StdinTo2DBytes() if printMap { ClearScreen() PrintMap(0, 0) PrintStatus() } posX, posY, dir := FindEntry(), 0, S for dir != ERR { posX, posY, dir = Move(posX, posY, dir) ticks++ switch network[posY][posX] { case '|', '-', '+': case ' ': dir = ERR break default: if len(nodes) == 0 || nodes[len(nodes)-1] != network[posY][posX] { message = fmt.Sprint("Found node ", string(network[posY][posX]), "!") nodes = append(nodes, network[posY][posX]) } } ClearScreen() if printMap { PrintMap(posX, posY) time.Sleep(time.Second / 30) } PrintStatus() } fmt.Println("Ctrl+C to Quit") } func GetNodesAsString(nodes []byte) string { ret := "[ " for i := range nodes { ret += string(nodes[i]) + " " } return ret + "]" } func Move(posX, posY, dir int) (int, int, int) { chkX, chkY := posX, posY switch dir { case N: chkY-- case E: chkX++ case S: chkY++ case W: chkX-- } if chkX < 0 || chkY < 0 || chkX > len(network[0]) || chkY > len(network) { // Went off the map return posX, posY, ERR } if network[chkY][chkX] == '+' { // Which direction do we need to turn? switch dir { case N, S: if CanMoveTo(chkX+1, chkY) { dir = E } else if CanMoveTo(chkX-1, chkY) { dir = W } case E, W: fmt.Println(len(network), chkY+1) if CanMoveTo(chkX, chkY+1) { dir = S } else if CanMoveTo(chkX, chkY-1) { dir = N } } } return chkX, chkY, dir } func CanMoveTo(chkX, chkY int) bool { if chkY < 0 && chkX < 0 && chkY > len(network) && chkX > len(network[chkY]) { return false } fmt.Println(chkX, chkY) return network[chkY][chkX] != ' ' } func FindEntry() int { for i := range network[0] { if network[0][i] == '|' { return i } } return -1 } func ClearScreen() { fmt.Print("\033[H\033[2J") } func PrintMap(posX, posY int) { stX, stY := 0, 0 useHeight, useWidth := height-2, width if posY > useHeight/2 { stY = posY - (useHeight / 2) } if posX > width/2 { stX = posX - (width / 2) } totHeight := useHeight/2 + posY if totHeight < useHeight { useHeight = useHeight + (useHeight - totHeight) + 4 } totWidth := useWidth/2 + posX if totWidth < useWidth { useWidth = useWidth + (useWidth - totWidth) + 4 } for y := stY; y < posY+(useHeight/2); y++ { for x := stX; x < posX+(useWidth/2); x++ { if len(network) > y { if len(network[y]) > x { if y == posY && x == posX { fmt.Print("*") } else { fmt.Print(string(network[y][x])) } } } } fmt.Println("") } } func PrintStatus() { fmt.Print(ticks, " Ticks ", GetNodesAsString(nodes), "\n") fmt.Println(message) } func StdinTo2DBytes() [][]byte { var ret [][]byte scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { bts := scanner.Bytes() t := make([]byte, len(bts)) copy(t, bts) ret = append(ret, t) } return ret }