-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
155 lines (144 loc) · 3.97 KB
/
main.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"bufio"
"flag"
"fmt"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
_ "image/png"
"log"
"net"
"net/rpc"
"strconv"
"strings"
"time"
c "workshop/client"
"workshop/util"
)
func success(conn *net.Conn, g *c.Game, task c.Task) {
// close the channel to prevent blocking
g.VisQueue <- task
fmt.Fprintln(*conn, fmt.Sprintf("CLIENT-%d:OK", task.Id))
}
func read(conn *net.Conn, g *c.Game, idChan chan int, done chan bool) {
reader := bufio.NewReader(*conn)
id := -1
for {
msg, err := reader.ReadString('\n')
util.Check(err)
msg = msg[:len(msg)-1]
msgSlice := strings.Split(msg, ":")
command := msgSlice[0]
message := msgSlice[1]
fmt.Println(msg)
switch command {
case "ID":
id, err = strconv.Atoi(message)
util.Check(err)
idChan <- id
fmt.Fprintln(*conn, fmt.Sprintf("CLIENT-%d:OK", id))
case "CLOSED":
done <- true
break
case "START":
task := c.Task{0, util.START, message}
success(conn, g, task)
case "STOP":
task := c.Task{0, util.STOP, message}
success(conn, g, task)
case "ELF_ENTER":
contentSlice := strings.Split(message, ";")
id, err := strconv.Atoi(contentSlice[0])
util.Check(err)
child := contentSlice[1]
task := c.Task{id, util.ELF_ENTER, child}
success(conn, g, task)
case "ELF_EXIT":
contentSlice := strings.Split(message, ";")
id, err := strconv.Atoi(contentSlice[0])
util.Check(err)
child := contentSlice[1]
task := c.Task{id, util.ELF_EXIT, child}
success(conn, g, task)
case "ROUTE":
task := c.Task{0, util.ROUTE, message} // TODO: consider displaying Santa's route visually
success(conn, g, task)
default: // TODO: have more messages sent back to server depending on situation, e.g. a message isn't received correctly idk
fmt.Fprintln(*conn, fmt.Sprintf("CLIENT-%d:ERROR", id))
}
}
}
func main() {
// RPC dial to server
server := flag.String("server", "127.0.0.1:8080", "IP:port string to connect to for RPC")
client, err := rpc.Dial("tcp", *server)
flag.Parse()
util.Check(err)
defer client.Close()
// Set up
visQueue := make(chan c.Task, 100)
workshopSpace := []int{-1, -1, -1, -1}
start := make(chan bool)
game := &c.Game { // Set up game
Children: []util.Child{},
Completed: map[string]bool{},
VisSanta: c.VisSprite{},
VisElves: []c.VisSprite{},
Addresses: []util.Address{},
Route: []util.Address{},
VisQueue: visQueue,
WorkshopSpace: workshopSpace,
Start: start,
Stage: c.STANDBY,
}
ebiten.SetWindowSize(c.ScreenWidth, c.ScreenHeight)
ebiten.SetWindowTitle("Santa's Workshop")
// Set up IO
idChan := make(chan int)
done := make(chan bool)
var conn net.Conn
go func() {
ioAddr := flag.String("ip", "127.0.0.1:8081", "IP:port string to connect to for bufio")
flag.Parse()
conn, err = net.Dial("tcp", *ioAddr)
util.Check(err)
read(&conn, game, idChan, done)
}()
id := <-idChan
c.Init()
// Initialise elves
elfW, elfH := c.ElfImg.Size()
for i := 0; i < 8; i++ {
x := float64(2 * i * elfW)
y := float64(c.ScreenHeight - 2*elfH)
img, _, err := ebitenutil.NewImageFromFile("sprites/elf_"+strconv.Itoa(i)+".png")
util.Check(err)
c.MVisElves.Lock()
elf := c.VisSprite{i, 0, c.STAND, x, y, x, y, x, y, img}
game.VisElves = append(game.VisElves, elf)
c.MVisElves.Unlock()
}
// Initialise santa
x := float64(0)
y := float64(0)
game.VisSanta = c.VisSprite{0, 0, c.STAND, x, y, x, y, x, y, c.SantaImg}
// RPC dial to server
go func() {
for {
<-start // will start when Enter is pressed
children := util.ConvertCSV("input.csv") // by adding it here, means you will use latest version of csv
game.Children = children
results := []util.Child{}
route := []util.Address{}
time.Sleep(2 * time.Second)
c.Run(id, client, children, &results, &route)
}
}()
// Run window
if err := ebiten.RunGame(game); err != nil {
log.Fatal(err)
} else {
fmt.Fprintln(conn, fmt.Sprintf("CLIENT-%d:CLOSE", id))
<-done
}
}