202 lines
3.5 KiB
Go
202 lines
3.5 KiB
Go
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
|
|
}
|