-
Notifications
You must be signed in to change notification settings - Fork 2
/
day25.go
104 lines (92 loc) · 1.64 KB
/
day25.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"github.com/dhconnelly/advent-of-code-2019/geom"
"github.com/dhconnelly/advent-of-code-2019/intcode"
)
type game struct {
in chan<- int64
out <-chan int64
r *bufio.Scanner
}
func NewGame(data []int64, r io.Reader) game {
in := make(chan int64)
out := intcode.RunProgram(data, in)
return game{in, out, bufio.NewScanner(r)}
}
func (g game) readLine() (string, bool) {
var b []byte
var ok bool
var c int64
for c, ok = <-g.out; ok && c != '\n'; c = <-g.out {
b = append(b, byte(c))
}
if len(b) > 0 {
return string(b), true
}
return "", ok
}
func (g game) getCommand() (string, bool) {
if g.r.Scan() {
return g.r.Text(), true
}
if err := g.r.Err(); err != nil {
log.Fatalf("failed to read command: %s", err)
}
return "", false
}
func (g game) writeLine(line string) {
for _, c := range line {
g.in <- int64(c)
}
g.in <- '\n'
}
var commandToDir = map[string]geom.Direction{
"north": geom.Up,
"south": geom.Down,
"west": geom.Left,
"east": geom.Right,
}
func isDir(line string) bool {
for cmd := range commandToDir {
if cmd == line {
return true
}
}
return false
}
func (g game) loop() {
for {
line, ok := g.readLine()
if !ok {
fmt.Println("machine halted; exiting")
return
}
if line != prompt {
fmt.Println(line)
continue
}
fmt.Println(prompt)
cmd, ok := g.getCommand()
if !ok {
fmt.Println("no more commands; exiting")
return
}
g.writeLine(cmd)
}
}
const (
prompt = "Command?"
)
func main() {
data, err := intcode.ReadProgram(os.Args[1])
if err != nil {
log.Fatal(err)
}
g := NewGame(data, os.Stdin)
g.loop()
}