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

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