/
view_reporter.go
109 lines (90 loc) · 2.36 KB
/
view_reporter.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
package main
import (
"github.com/gorilla/websocket"
"github.com/kir-dev/torpedo/engine"
"github.com/kir-dev/torpedo/util"
)
type messageType int
const (
MSG_HITRESULT messageType = iota
MSG_GAMESTARTED
MSG_GAMEOVER
MSG_ELAPSEDTIME
MSG_TURNSTART
MSG_PLAYERJOINED
)
const MAX_VIEW_ERROR_COUNT = 3
type viewReporter struct {
conn *websocket.Conn
remoteAddr string
errorCount int
}
type viewMsg struct {
Type messageType `json:"type"`
Payload interface{} `json:"payload"`
}
func (v *viewReporter) ReportHitResult(row, col int, result engine.HitResult) {
var color string
isSunken := false
switch result {
case engine.HIT:
color = currentGame.Board.Fields[row][col].ShipPart.Ship.Player.Color.Hit
case engine.MISS:
color = CELL_MISS_COLOR
case engine.HIT_SUNK:
color = currentGame.Board.Fields[row][col].ShipPart.Ship.Player.Color.HitAndSunk
isSunken = true
case engine.INVALID:
color = ""
}
values := map[string]interface{}{
"row": row,
"col": col,
"result": color,
"isSunken": isSunken,
}
v.send(MSG_HITRESULT, values)
}
func (v *viewReporter) ReportGameStarted() {
v.send(MSG_GAMESTARTED, nil)
}
func (v *viewReporter) ReportGameOver(winner *engine.Player) {
v.send(MSG_GAMEOVER, winner.Name)
}
func (v *viewReporter) ReportElapsedTime(elapsed float64) {
v.send(MSG_ELAPSEDTIME, elapsed)
}
func (v *viewReporter) ReportPlayerJoined(player *engine.Player) {
value := map[string]interface{}{
"name": player.Name,
"hitColor": player.Color.Hit,
"sunkColor": player.Color.HitAndSunk,
}
v.send(MSG_PLAYERJOINED, value)
}
func (v *viewReporter) ReportPlayerTurnStart(current *engine.Player, next *engine.Player) {
var nextPlayerName string
if next == nil {
nextPlayerName = "error: could not determine next player"
} else {
nextPlayerName = next.Name
}
names := map[string]string{
"current": current.Name,
"next": nextPlayerName,
}
v.send(MSG_TURNSTART, names)
}
func (v *viewReporter) send(aType messageType, payload interface{}) {
// try to write in the socket
err := v.conn.WriteJSON(viewMsg{aType, payload})
if err != nil {
if v.errorCount >= MAX_VIEW_ERROR_COUNT {
currentGame.DiscardView(v)
util.LogWarn("Discarded view for %s after %d errors", v.remoteAddr, v.errorCount)
return
}
util.LogWarn("Could not send data to %s. Error msg: %s", v.remoteAddr, err)
v.errorCount += 1
}
}