db91e14d7dd7c01f6d59f0fd709e09d533653b90
[progcomp2013.git] / web / qwebchess / js.js
1 /**\r
2  * qwebchess.js\r
3  * jQuery interface for Quantum Chess\r
4  *\r
5  * @authors Sam Moore and Mitch Pomery\r
6  */\r
7 \r
8 pieceSelected = ""; // currently selected piece\r
9 playerColour = "W"; // colour of this player\r
10 \r
11 // Unicode representations of chess pieces\r
12 pieceChar = {"W" : { "p" : "\u2659", "h" : "\u2658", "b" : "\u2657", "r" : "\u2656", "q" : "\u2655", "k" : "\u2654", "?" : "?"},\r
13              "B" : { "p" : "\u265F", "h" : "\u265E", "b" : "\u265D", "r" : "\u265C", "q" : "\u265B", "k" : "\u265A", "?" : "?"}};\r
14 \r
15 emptyHTML = "<!--0-->&nbsp; <big> <bold>&nbsp;</bold> </big> &nbsp;"\r
16 \r
17 gameStarted = false;\r
18 canClick = true;\r
19 \r
20 // jQuery foo goes in here\r
21 $(document).ready(function()\r
22 {\r
23         // Click the start/quit button\r
24         $("#start").click(function() \r
25         {\r
26                 if (gameStarted === false)\r
27                 {\r
28                         gameStarted = true;\r
29                         $("#board").boardLoad();\r
30                         $("#welcome").hide();\r
31                         $("#status").show();\r
32                         $("#status").html("white SELECT?");\r
33                         $("#start").html("Quit Game");\r
34                         pieceSelected = "";\r
35                         canClick = true;\r
36                         $.ajax({url : "/cgi-bin/qchess.cgi", data : {r : "force_quit"}, success : function() {}});\r
37                         $.ajax({url : "/cgi-bin/qchess.cgi", data : {r : "start"}}).done(function(data) {$(this).update(data)});\r
38                 \r
39                                 \r
40                 }\r
41                 else\r
42                 {\r
43                         gameStarted = false;\r
44                         $("#welcome").show();\r
45                         $("#status").html("Game over");\r
46                         $("#start").html("New Game");\r
47                         $.ajax({url : "/cgi-bin/qchess.cgi", data : {r : "quit"}, success : function() {console.log("Quit game");}});\r
48                 }\r
49         });\r
50 \r
51         // bind click event to table cells\r
52         $("#board").on('click', 'td' , function(e)\r
53         {\r
54                 if (canClick === false)\r
55                         return;\r
56         \r
57                 var id = $(this).attr("id");    \r
58                 legal = true;\r
59                 if (pieceSelected === "")\r
60                 {\r
61                         if ($(this).legalSelection())\r
62                         {\r
63                                 pieceSelected = id;\r
64                                 $(this).setSquareColour("blue");\r
65                         }\r
66                         else\r
67                         {\r
68                                 legal = false;\r
69                                 alert("Illegal selection " + id);\r
70                         }\r
71                 }\r
72                 else\r
73                 {\r
74                         mover = $("#board").find("#"+pieceSelected);\r
75                         if (mover.legalMove($(this)))\r
76                         {\r
77                                 $("#status").html(colourString(otherColour(mover.getColour())) + " SELECT?");\r
78                                 mover.move($(this));\r
79                                 pieceSelected = "";\r
80                                 $("#board td").each(function() {$(this).setSquareColour("default");});\r
81                         }\r
82                         else\r
83                         {\r
84                                 legal = false;\r
85                                 alert("Illegal move " + id);\r
86                         }\r
87                 }\r
88                 \r
89                 if (legal)\r
90                         $.ajax({url : "/cgi-bin/qchess.cgi", data : {x : id[0], y : id[1]}}).done(function(data) {$(this).update(data)});\r
91         });\r
92 \r
93         $.fn.showMoves = function()\r
94         {\r
95                 $(this).setSquareColour("green");\r
96                 var that = $(this); //Look [DJA]! I used it!\r
97                 $("#board td").each(function()\r
98                 {\r
99                         if (that.legalMove($(this)) === true) // See?\r
100                         {\r
101                                 //alert("Legal move from " + that.attr("id") + " -> " + $(this).attr("id"));\r
102                                 $(this).setSquareColour("red");\r
103                         }\r
104                 });\r
105                 \r
106         }\r
107 \r
108         // Get colour of occupied square\r
109         // W - white\r
110         // B - black\r
111         // 0 - unoccupied\r
112         $.fn.getColour = function()\r
113         {\r
114                 return $(this).html()[4]; // yeah, I know this is horrible, so sue me\r
115         }\r
116 \r
117         // Get type of piece\r
118         $.fn.getType = function()\r
119         {\r
120                 return $(this).html().match(/<bold>(.*)<\/bold>/)[1]; // again, I know it's horrible, so sue me\r
121         }\r
122 \r
123         // Get coords\r
124         $.fn.getX = function() {return Number($(this).attr("id")[0]);}\r
125         $.fn.getY = function() {return Number($(this).attr("id")[1]);}\r
126         \r
127         // Check a square is a valid selection\r
128         $.fn.legalSelection = function()\r
129         {\r
130                 return ($(this).getColour() == playerColour);\r
131         }\r
132 \r
133         // determine whether a piece can move into another square\r
134         $.fn.legalMove = function(target)\r
135         {\r
136                 if (target.getColour() == $(this).getColour())\r
137                         return false;\r
138                 if (target.getX() == $(this).getX() && target.getY() == $(this).getY())\r
139                         return false;\r
140                 switch ($(this).getType())\r
141                 {\r
142                         case pieceChar["W"]['p']:\r
143                                 if ($(this).getY() == 6 && target.getY() == 4 && $(this).getX() == target.getX() && target.getColour() == '0')\r
144                                         return true;\r
145                                 if ($(this).getY() - target.getY() != 1 || Math.abs($(this).getX() - target.getX()) > 1)\r
146                                         return false;\r
147                                 return ($(this).getX() == target.getX() || target.getColour() != '0');\r
148 \r
149                         case pieceChar["B"]['p']:\r
150                                 if ($(this).getY() == 1 && target.getY() == 3 && $(this).getX() == target.getX())\r
151                                         return true;\r
152                                 if ($(this).getY() - target.getY() != -1 || Math.abs($(this).getX() - target.getX()) > 1)\r
153                                         return false;\r
154                                 return ($(this).getX() == target.getX() || target.getColour() != '0');\r
155 \r
156                         case pieceChar["W"]['h']:\r
157                         case pieceChar["B"]['h']:\r
158                                 return ((Math.abs($(this).getY() - target.getY()) == 2 && Math.abs($(this).getX() - target.getX()) == 1)\r
159                                         || (Math.abs($(this).getX() - target.getX()) == 2 && Math.abs($(this).getY() - target.getY()) == 1));\r
160 \r
161                         case pieceChar["W"]['k']:\r
162                         case pieceChar["B"]['k']:\r
163                                 return (Math.abs($(this).getX() - target.getX()) <= 1 && Math.abs($(this).getY() - target.getY()) <= 1);\r
164                         case pieceChar["W"]['b']:\r
165                         case pieceChar["B"]['b']:\r
166                                 //console.log("" + Math.abs($(this).getX() - target.getX()) + " vs " + Math.abs($(this).getY() - target.getY()));\r
167                                 if (Math.abs($(this).getX() - target.getX()) != Math.abs($(this).getY() - target.getY()))\r
168                                         return false;\r
169                                 break;\r
170                         case pieceChar["W"]['r']:\r
171                         case pieceChar["B"]['r']:\r
172                                 //console.log("" + Math.abs($(this).getX() - target.getX()) + " vs " + Math.abs($(this).getY() - target.getY()));\r
173                                 console.log("Rook");\r
174                                 if (Math.abs($(this).getX() - target.getX()) != 0 && Math.abs($(this).getY() - target.getY()) != 0)\r
175                                         return false;\r
176                                 break;\r
177                         case pieceChar["W"]['q']:\r
178                         case pieceChar["B"]['q']:\r
179                                 //console.log("" + Math.abs($(this).getX() - target.getX()) + " vs " + Math.abs($(this).getY() - target.getY()));\r
180                                 if (Math.abs($(this).getX() - target.getX()) != Math.abs($(this).getY() - target.getY()))\r
181                                 {\r
182                                         if (Math.abs($(this).getX() - target.getX()) != 0 && Math.abs($(this).getY() - target.getY()) != 0)\r
183                                                 return false;\r
184                                 }\r
185                                 break;\r
186                         default:\r
187                                 return false;\r
188                 }\r
189                 console.log("scanning");\r
190                 var vx = ($(this).getX() == target.getX()) ? 0 : (($(this).getX() < target.getX()) ? 1 : -1);\r
191                 var vy = ($(this).getY() == target.getY()) ? 0 : (($(this).getY() < target.getY()) ? 1 : -1);\r
192                 var x = $(this).getX() + vx; var y = $(this).getY() + vy;\r
193                 while ((x != target.getX() || y != target.getY()) && x >= 0 && y >= 0 && x < 8 && y < 8)\r
194                 {\r
195                         var c = $("#"+x+""+y).getColour();\r
196                         if (c === "W" || c === "B")\r
197                         {\r
198                                 console.log("Blocked at "+x+""+y);\r
199                                 return false;\r
200                         }\r
201                         else\r
202                                 console.log("Scan ok at "+x+""+y);\r
203                         x += vx;\r
204                         y += vy;                        \r
205                 }       \r
206                 return true;\r
207         }\r
208 \r
209         // Move square to another\r
210         $.fn.move = function(dest)\r
211         {\r
212                 dest.html($(this).html());\r
213                 $(this).html(emptyHTML);\r
214 \r
215                 // Collapse into quantum state if on a black square\r
216                 if ((dest.getX() + dest.getY()) % 2 != 0 && (dest.html()[0] == '?' || dest.html()[dest.html().length-1] == '?'))\r
217                 {\r
218                         oldHTML = dest.html();\r
219                         dest.html(oldHTML.replace(/<bold>.*<\/bold>/i, "<bold>?</bold>"));\r
220                 }\r
221         }\r
222 \r
223         // Interpret AJAX response\r
224         $.fn.update = function(data)\r
225         {\r
226                 console.log("AJAX Response:\n"+data);\r
227                 var lines = data.split("\n");\r
228                 for (var i = 0; i < lines.length; ++i)\r
229                 {\r
230                         var tokens = lines[i].split(" ");\r
231 \r
232                         if (!isNaN(tokens[0]) && !isNaN(tokens[1]))\r
233                         {\r
234                                 s1 = $("#board").find("#"+tokens[0]+tokens[1])\r
235                                 if (tokens[2] === "->")\r
236                                 {\r
237                                         if (s1.html()[4] != '0')\r
238                                         {\r
239                                                 s2 = $("#board").find("#"+tokens[3]+tokens[4]);\r
240                                                 canClick = false;\r
241                                                 setTimeout((function(x) \r
242                                                 {\r
243                                                         return function() \r
244                                                         {\r
245                                                                 s1.move(x);\r
246                                                                 $("#board td").each(function() {$(this).setSquareColour("default");});\r
247                                                                 x.setSquareColour("blue");\r
248                                                                 setTimeout((function(xx) \r
249                                                                 {\r
250                                                                         return function() \r
251                                                                         {\r
252                                                                                 xx.setSquareColour("default"); canClick = true;\r
253                                                                                 $("#status").html(colourString(playerColour) + " SELECT?");\r
254                                                                         };\r
255                                                                 }(x)), 500);\r
256                                                         };\r
257                                                 }(s2)), 500);\r
258                                         }\r
259                                 }\r
260                                 else if (tokens.length === 4 && !isNaN(tokens[2]) && isNaN(tokens[3]))\r
261                                 {\r
262                                         var t = "h";\r
263                                         if (tokens[3] != "knight")\r
264                                                 t = tokens[3][0];\r
265                         \r
266                                         var oldHTML = s1.html();\r
267                                         var c = s1.getColour();\r
268                                         if (tokens[2] == "1")\r
269                                         {\r
270                                                 oldHTML = oldHTML.substring(0, oldHTML.length-1)+pieceChar[c][t];\r
271                                         }\r
272                                         s1.html(oldHTML.replace(/<bold>.*<\/bold>/i, "<bold>"+pieceChar[c][t]+"</bold>"));\r
273                                         //console.log(oldHTML + " ==> " + s1.html());\r
274                                         s1.setSquareColour("green");\r
275                                         s1.showMoves();\r
276                                         $("#status").html(colourString(s1.getColour()) + " MOVE?");\r
277                                         \r
278                                 }\r
279                         }\r
280                         else switch (lines[i])\r
281                         {\r
282                                 case "SELECT?":\r
283                                         pieceSelected = "";\r
284                                 case "MOVE?":\r
285                                 case "":\r
286                                 case "New game.":\r
287                                         break;\r
288                                 default:\r
289                                         alert("Game ends: " + lines[i]);\r
290                                         gameStarted = false;\r
291                                         $("#start").html("New Game");\r
292                                         $("#status").html("Game over");\r
293                                         //$("#board").html("");\r
294                                         \r
295                                         \r
296                                         break;\r
297                         }\r
298                 }\r
299         }\r
300 \r
301         //Reset the colour of a square\r
302         $.fn.setSquareColour = function(type)\r
303         {\r
304                 var colour = "000000";\r
305                 switch (type)\r
306                 {\r
307                         case "blue":\r
308                                 colour = "5555aa";\r
309                                 break;\r
310                         case "green":\r
311                                 colour = "55aa55";\r
312                                 break;\r
313                         case "red":\r
314                                 colour = "aa5555";\r
315                                 break;\r
316                         default:\r
317                                 colour = "aaaaaa";\r
318                                 break;\r
319                 }\r
320 \r
321                 id = $(this).attr("id");\r
322                 if ((Number(id[0]) + Number(id[1])) % 2 == 0)\r
323                 {       \r
324                         colour = addHexColour(colour, "555555");\r
325                 }\r
326                 $(this).css("background-color", "#"+colour);\r
327         }\r
328 \r
329         // Loads the board\r
330         $.fn.boardLoad = function()\r
331         {\r
332                 boardHTML = "";\r
333                 for (var y = 0; y < 8; ++y)\r
334                 {\r
335                         boardHTML += "<tr id=\"y"+y+"\">";\r
336                         for (var x = 0; x < 8; ++x)\r
337                         {\r
338                                 boardHTML += "<td id=\""+x+""+y+"\">"+emptyHTML+"</td>";\r
339                         }\r
340                         boardHTML += "</tr>";\r
341                 }\r
342                 $(this).html(boardHTML);\r
343 \r
344                 $(this).find("td").each(function()\r
345                 {\r
346                         $(this).setSquareColour("default");\r
347                 });\r
348 \r
349                 // Add pieces\r
350                 for (var x = 0; x < 8; ++x)\r
351                 {\r
352                         // pawns\r
353                         $(this).find("#"+x+"1").html("<!--B--> "+pieceChar["B"]["p"]+"<big> <bold>?</bold> </big> ?");\r
354                         $(this).find("#"+x+"6").html("<!--W--> "+pieceChar["W"]["p"]+"<big> <bold>?</bold> </big> ?");\r
355                 \r
356                         t = "?";\r
357                         switch (x)\r
358                         {\r
359                                 case 0:\r
360                                 case 7:\r
361                                         t = 'r';\r
362                                         break;\r
363                                 case 1:\r
364                                 case 6:\r
365                                         t = 'h';\r
366                                         break;\r
367                                 case 2:\r
368                                 case 5:\r
369                                         t = 'b';\r
370                                         break;\r
371                                 case 4:\r
372                                         t = 'q';\r
373                                         break;\r
374                         }\r
375                         if (x == 3)\r
376                                 continue;\r
377                         $(this).find("#"+x+"0").html("<!--B--> "+pieceChar["B"][t]+"<big> <bold>?</bold> </big> ?");\r
378                         $(this).find("#"+x+"7").html("<!--W--> "+pieceChar["W"][t]+"<big> <bold>?</bold> </big> ?");\r
379                 }\r
380                 t = pieceChar["B"]["k"];\r
381                 $(this).find("#30").html("<!--B--> "+t+"<big> <bold>"+t+"</bold> </big> "+t);\r
382                 t = pieceChar["W"]["k"];\r
383                 $(this).find("#37").html("<!--W--> "+t+"<big> <bold>"+t+"</bold> </big> "+t);\r
384                 \r
385         }\r
386 \r
387 });\r
388 \r
389 \r
390 // Add two hex colours\r
391 function addHexColour(c1, c2) \r
392 {\r
393   var hexStr = (parseInt(c1, 16) + parseInt(c2, 16)).toString(16);\r
394   while (hexStr.length < 6) { hexStr = '0' + hexStr; } // Zero pad.\r
395   return hexStr;\r
396 }\r
397 \r
398 function colourString(c)\r
399 {\r
400         return (c == "W") ? "white" : "black";\r
401 }\r
402 \r
403 function otherColour(c)\r
404 {\r
405         return (c == "W") ? "B" : "W";\r
406 }\r

UCC git Repository :: git.ucc.asn.au