]> Untitled Git - go.git/blob - htdocs/go.js
d02e55d25f9a007b213f2eeb534f1dc9845bb232
[go.git] / htdocs / go.js
1 var canvas = document.getElementById("game-canvas");
2 var context = canvas.getContext("2d");
3
4 var backgroundColor = '#F5DEB3';
5 var gridColor = '#8B4513';
6 var boardSize = 19;
7
8 var border = canvas.width / 10;
9 var boardWidth = canvas.width - (border * 2);
10 var boardHeight = canvas.height - (border * 2);
11
12 var cellWidth = boardWidth / (boardSize - 1);
13 var cellHeight = boardHeight / (boardSize - 1);
14
15 var lastX;
16 var lastY;
17 var playCount = 0;
18
19 /* state of pieces 
20     0: empty
21     1: white
22     2: black
23 */
24 function getStone(i) {
25     switch (i) {
26         case 1:
27             return 'white';
28         case 2:
29             return 'black';
30         default:
31             return 'empty';
32     }
33 }
34
35 var session = 0;
36 var state = [];
37 for (var i = 0; i < boardSize; i++)
38 {
39     state[i] = [];
40     for (var j = 0; j < boardSize; j++)
41     {
42         state[i][j] = 0;
43     }
44 }
45
46 // @connect
47 // Connect to the websocket
48 var socket;
49 const connect = function() {
50     return new Promise((resolve, reject) => {
51         const socketProtocol = (window.location.protocol === 'https:' ? 'wss:' : 'ws:')
52         const port = 3000;
53         const socketUrl = `${socketProtocol}//${window.location.hostname}:${port}/ws/`
54
55         // Define socket
56         socket = new WebSocket(socketUrl);
57
58         socket.onopen = (e) => {
59             // Send a little test data, which we can use on the server if we want
60             // Resolve the promise - we are connected
61             resolve();
62         }
63
64         socket.onmessage = (msg) => {
65             // Any data from the server can be manipulated here.
66             let parsed = JSON.parse(msg.data);
67             switch (parsed.type) {
68                 case "board":
69                     console.log("Setting board state");
70                     parsed.data.forEach( function (move, index) {
71                         state[move.x][move.y] =
72                             move.state === 'white' ? 1 :
73                             move.state === 'black' ? 2 :
74                             0;
75                     });
76                     drawGrid();
77                     break;
78                 default:
79                     console.log(msg);
80             }
81         }
82
83         socket.onerror = (e) => {
84             // Return an error if any occurs
85             console.log(e);
86             resolve();
87             // Try to connect again
88             connect();
89         }
90     });
91 }
92
93 // @isOpen
94 // check if a websocket is open
95 const isOpen = function(ws) {
96     console.log(ws.readyState);
97     return ws.readyState === ws.OPEN
98 }
99
100
101 // finish grid
102 function drawGrid()
103 {    
104     
105     /* draw board square */
106     context.fillStyle = backgroundColor;
107     context.fillRect(0, 0, canvas.width, canvas.height);
108     
109     /* draw board grid */
110     context.fillStyle = gridColor;
111     for (var i = 0; i < boardSize - 1; i++)
112     {
113         for (var j = 0; j < boardSize - 1; j++)
114         {
115             context.fillRect(
116                 i * cellWidth + border, 
117                 j * cellHeight + border, 
118                 cellWidth - 1, 
119                 cellHeight - 1
120             );
121         }
122     }
123     
124     /* draw quarter marks and center mark on grid */
125     var quarter = Math.floor((boardSize - 1) / 4);
126     var markerSize = 8;
127     var markerMargin = (markerSize / 2) + 0.5;
128     
129     context.fillStyle = backgroundColor;
130     if (!!(boardSize % 2))
131     {
132         context.fillRect(
133             (((boardSize - 1) / 2) * cellWidth) + border - markerMargin, 
134             (((boardSize - 1) / 2) * cellWidth) + border - markerMargin,
135             markerSize, 
136             markerSize
137         );
138     }
139     context.fillRect(
140         (quarter * cellWidth) + border - markerMargin, 
141         (quarter * cellWidth) + border - markerMargin, 
142         markerSize, 
143         markerSize
144     );
145     context.fillRect(
146         (((boardSize - 1) - quarter) * cellWidth) + border - markerMargin, 
147         (quarter * cellWidth) + border - markerMargin, 
148         markerSize, 
149         markerSize
150     );
151     context.fillRect(
152         (((boardSize - 1) - quarter) * cellWidth) + border - markerMargin, 
153         (((boardSize - 1) - quarter) * cellWidth) + border - markerMargin, 
154         markerSize, 
155         markerSize
156     );
157     context.fillRect(
158         (quarter * cellWidth) + border - markerMargin,
159         (((boardSize - 1) - quarter) * cellWidth) + border - markerMargin,
160         markerSize, 
161         markerSize
162     );
163     
164     /* draw text labels for grid */
165     var size = canvas.width / 40;
166     var textSpacing = 10;
167     context.fillStyle = '#000000';
168     context.font = size + "px Arial";
169     
170     for (i = 0; i < boardSize; i++)
171     {
172         context.fillText(
173             (i + 1), textSpacing, 
174             ((canvas.height - border) - (i * cellHeight)) + (size / 3)
175         );
176         context.fillText(
177             (i + 1), canvas.width - (size + textSpacing), 
178             ((canvas.height - border) - (i * cellHeight)) + (size / 3)
179         );
180
181         context.fillText(
182             (String.fromCharCode(97 + i)),
183             (border + (i * cellHeight) + (size / 3)) - (size / 1.5), 
184             textSpacing + size
185         );
186         context.fillText(
187             (String.fromCharCode(97 + i)), 
188             (border + (i * cellHeight) + (size / 3)) - (size / 1.5), 
189             canvas.height - (textSpacing * 2)
190         );
191     }
192
193     drawPieces();
194 }
195
196 function drawPieces() {
197     /* draw pieces */
198     for (var i = 0; i < boardSize; i++)
199     {
200         for (var j = 0; j < boardSize; j++)
201         {
202             switch(state[i][j]) {
203                 case 1:
204                     placeStone(
205                         (i * cellWidth) + border, 
206                         (j * cellWidth) + border, 
207                         'rgba(255, 255, 255, 1)'
208                     );
209                     break;
210                 case 2:
211                     placeStone(
212                         (i * cellWidth) + border, 
213                         (j * cellWidth) + border, 
214                         'rgba(0, 0, 0, 1)'
215                     );
216                     break;
217                 default:
218             }
219         }
220     }
221 }
222
223 canvas.addEventListener('mousedown', function(evt) 
224 {
225     try {
226         // push state change to backend
227         if(isOpen(socket)) {
228             var stone;
229             if (state[lastX][lastY] === 0) {
230                 stone = playCount++ % 2 + 1;
231             } else {
232                 stone = 0;
233             }
234             socket.send(JSON.stringify({
235                 "type":"move",
236                 "data": {
237                     "session":session,
238                     "x":lastX,
239                     "y":lastY,
240                     "state":getStone(stone)
241                 }
242             }));
243         } else {
244             console.log("Websocket is closed");
245         }
246     } catch(e) {
247         console.log(e);
248     }
249 });
250
251 canvas.addEventListener('mousemove', function(evt) 
252 {
253     var position = getGridPoint(evt);
254
255     if ((position.x != lastX) || (position.y != lastY))
256     {
257         drawGrid();
258         if (
259             ((position.x >=0) && (position.x < boardSize)) && 
260             ((position.y >=0) && (position.y < boardSize))
261         ) {
262             placeStone(
263                 (position.x * cellWidth) + border, 
264                 (position.y * cellWidth) + border, 
265                 'rgba(0, 0, 0, 0.2)'
266             );
267         }
268     }
269     lastX = position.x;
270     lastY = position.y;        
271 });
272
273 function placeStone(x, y, color)
274 {
275     var radius = cellWidth / 2;
276     
277     context.beginPath();
278     context.arc(x, y, radius, 0, 2 * Math.PI, false);
279     context.fillStyle = color;    
280     context.fill();
281     context.lineWidth = 5;
282 }
283
284 function getGridPoint(evt)
285 {
286     var rect = canvas.getBoundingClientRect();
287         
288     var x = Math.round(
289         (evt.clientX-border-rect.left) / (rect.right-2*border-rect.left) * boardWidth
290     );
291     var y = Math.round(
292         (evt.clientY-border-rect.top) / (rect.bottom-2*border-rect.top) * boardHeight
293     );
294     
295     var roundX = Math.round(x / cellWidth);
296     var roundY = Math.round(y / cellHeight);
297     
298     return {
299         x: roundX,
300         y: roundY
301     };
302 }
303
304 // finish
305 connect();