This repository has been archived by the owner on Jun 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhellojs.nim
244 lines (212 loc) · 7.45 KB
/
hellojs.nim
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
import lib, json
import htmlgen, dom, strutils, enemynames
proc consolelog(a: cstring) {.importc.}
proc log(s: string) =
consolelog(cstring(s))
proc logint(i:int) =
log(intToStr(i))
const ship = "🚢"
const empty = " "
const miss = "∘"
const hit = "☠"
type
WebSocket* {.importc.} = object of RootObj
onopen*: proc (event: ref TEvent) {.nimcall.}
onmessage*: proc (event: ref MessageEvent) {.nimcall.}
send: proc(val: cstring)
MessageEvent {.importc.} = object of RootObj
data*: cstring
proc newWebsocket(): WebSocket {.importc:""" function() {
return new WebSocket('ws://' + location.hostname + ':5001', ['battleship'])
}"""}
var ws: WebSocket = newWebsocket()
ws.onopen = proc(ev: ref TEvent) =
log("connected")
proc shoot(x, y: int) =
ws.send($ %*["shoot", x, y])
var playerField = newField()
var enemyField = newField()
var enemy_connected = false
var player_ready = false
var enemy_ready = false
var your_name = ""
var enemy_name = ""
var waiting_enemy_turn = true
proc setDisclaimer(message: string) =
let el = window.document.getElementById("disclaimer")
el.innerHTML = message
proc clearDisclaimer() =
setDisclaimer("")
proc exampleShip(elemid:string, number: int, size: int) =
let el = window.document.getElementById(elemid)
for i in 1..size:
var row = document.createElement("div")
var cell = document.createElement("span")
cell.innerHTML = ship;
cell.classList.add("cell")
row.appendChild(cell);
el.appendChild(row);
var row = document.createElement("div")
var cell = document.createElement("span")
cell.innerHTML = intToStr(number)
cell.classList.add("cell")
row.appendChild(cell);
el.appendChild(row);
proc drawExample() =
exampleShip("ship4", 1, 4)
exampleShip("ship3", 2, 3)
exampleShip("ship2", 3, 2)
exampleShip("ship1", 4, 1)
proc clearExample() =
let el = window.document.getElementById("rules")
el.innerHTML = ""
proc bindSetupFieldClick(field: var Matrix, i,j: int, setupFinished: proc()): proc(event: ref TEvent)=
result = proc (event: ref TEvent)=
if field[i][j] == cEmpty:
field[i][j] = cShip
if not validateField(field):
field[i][j] = cEmpty
return
event.target.innerHTML = ship
else:
field[i][j] = cEmpty
if not validateField(field):
field[i][j] = cShip
return
event.target.innerHTML = empty
if isFilled(field):
log("FILLED")
setupFinished()
proc clear_enemy_turn()=
let el = document.getElementById("turn")
el.innerHTML = "(SHOOT)"
waiting_enemy_turn = false
proc set_enemy_turn()=
let el = document.getElementById("turn")
el.innerHTML = "(WAIT)"
waiting_enemy_turn = true
proc bindEnemyFieldClick(field: var Matrix, i,j: int): proc(event: ref TEvent)=
result = proc (event: ref TEvent)=
if waiting_enemy_turn:
return
if field[i][j] == cDead:
return
if field[i][j] == cMiss:
return
if field[i][j] == cShip:
field[i][j] = cDead
if field[i][j] == cEmpty:
field[i][j] = cMiss
set_enemy_turn()
log("Attack at [" & intToStr(i) & ", " & intToStr(j) & "]")
shoot(i, j)
proc drawSetupGrid(elementid: cstring, field: var Matrix, setupFinished: proc()) =
let el = window.document.getElementById(elementid)
el.innerHTML = ""
for i in 1..10:
var row = document.createElement("div")
el.appendChild(row)
for j in 1..10:
let f = bindSetupFieldClick(field, i, j, setupFinished);
var cell = document.createElement("span")
cell.innerHTML = empty
cell.classList.add("cell")
{.emit:"`cell`.onclick=`f`; "}
el.appendChild(cell)
proc drawPlayerGrid(elementid: cstring, field: var Matrix) =
let el = window.document.getElementById(elementid)
el.innerHTML = ""
for i in 1..10:
var row = document.createElement("div")
el.appendChild(row)
for j in 1..10:
var cell = document.createElement("span")
if field[i][j] == cShip:
cell.innerHTML = ship
elif field[i][j] == cEmpty:
cell.innerHTML = empty
elif field[i][j] == cDead:
cell.innerHTML = hit
else:
cell.innerHTML = miss
cell.classList.add("cell")
el.appendChild(cell)
proc drawEnemyGrid(elementid: cstring, field: var Matrix) =
let el = window.document.getElementById(elementid)
el.innerHTML = ""
for i in 1..10:
var row = document.createElement("div")
el.appendChild(row)
for j in 1..10:
let f = bindEnemyFieldClick(field, i, j);
var cell = document.createElement("span")
cell.classList.add("cell")
if field[i][j] == cShip:
cell.innerHTML = ship
elif field[i][j] == cEmpty:
cell.innerHTML = empty
elif field[i][j] == cDead:
cell.innerHTML = hit
else:
cell.innerHTML = miss
{.emit:"`cell`.onclick=`f`; "}
el.appendChild(cell)
proc setup(setupFinished: proc()) =
setDisclaimer("Waiting for enemy...")
drawSetupGrid("player", playerField, setupFinished)
drawExample()
proc play() =
ws.send(matrixToJson(playerField))
clearExample()
drawPlayerGrid("player", playerField)
if enemy_ready:
drawEnemyGrid("enemy", playerField)
else:
setDisclaimer("Waiting for " & enemy_name & " to setup board...")
ws.onmessage = proc(ev: ref MessageEvent) =
log("Message", ev.data)
var parsed = parseJson($ev.data)
var message_kind = parsed[0].getStr()
if message_kind == "incoming":
var incoming_kind = parsed[1].getStr()
var x = parsed[2].getNum()
var y = parsed[3].getNum()
if incoming_kind == "hit":
playerField[x][y] = cDead
elif incoming_kind == "miss":
playerField[x][y] = cMiss
clear_enemy_turn()
drawPlayerGrid("player", playerField)
elif message_kind == "outgoing":
var outgoing_kind = parsed[1].getStr()
var x = parsed[2].getNum()
var y = parsed[3].getNum()
if outgoing_kind == "hit":
enemyField[x][y] = cDead
clear_enemy_turn()
elif outgoing_kind == "miss":
enemyField[x][y] = cMiss
drawEnemyGrid("enemy", enemyField)
elif message_kind == "commenced":
your_name = parsed[1].getStr()
enemy_name = parsed[2].getStr()
let el = document.getElementById("names")
el.innerHTML = your_name & " VS " & enemy_name
enemy_connected = true
setDisclaimer("Enemy " & enemy_name & " connected")
elif message_kind == "start":
if parsed[1].getStr() == "you":
clear_enemy_turn()
elif parsed[1].getStr() == "enemy":
set_enemy_turn()
clearDisclaimer()
drawEnemyGrid("enemy", enemyField)
elif message_kind == "win":
set_enemy_turn()
let el = document.getElementById("names")
el.innerHTML = your_name & " WINS!"
elif message_kind == "loose":
set_enemy_turn()
let el = document.getElementById("names")
el.innerHTML = your_name & " LOOSES!"
setup(play)