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

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