3 * jQuery interface for Quantum Chess
\r
5 * @authors Sam Moore and Mitch Pomery
\r
8 pieceSelected = ""; // currently selected piece
\r
9 playerColour = "W"; // colour of this player
\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
15 emptyHTML = "<!--0--> <big> <bold> </bold> </big> "
\r
17 gameStarted = false;
\r
20 // jQuery foo goes in here
\r
21 $(document).ready(function()
\r
23 // Click the start/quit button
\r
24 $("#start").click(function()
\r
26 if (gameStarted === false)
\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
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
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
51 // bind click event to table cells
\r
52 $("#board").on('click', 'td' , function(e)
\r
54 if (canClick === false)
\r
57 var id = $(this).attr("id");
\r
59 if (pieceSelected === "")
\r
61 if ($(this).legalSelection())
\r
64 $(this).setSquareColour("blue");
\r
69 alert("Illegal selection " + id);
\r
74 mover = $("#board").find("#"+pieceSelected);
\r
75 if (mover.legalMove($(this)))
\r
77 $("#status").html(colourString(otherColour(mover.getColour())) + " SELECT?");
\r
78 mover.move($(this));
\r
80 $("#board td").each(function() {$(this).setSquareColour("default");});
\r
85 alert("Illegal move " + id);
\r
90 $.ajax({url : "/cgi-bin/qchess.cgi", data : {x : id[0], y : id[1]}}).done(function(data) {$(this).update(data)});
\r
93 $.fn.showMoves = function()
\r
95 $(this).setSquareColour("green");
\r
96 var that = $(this); //Look [DJA]! I used it!
\r
97 $("#board td").each(function()
\r
99 if (that.legalMove($(this)) === true) // See?
\r
101 //alert("Legal move from " + that.attr("id") + " -> " + $(this).attr("id"));
\r
102 $(this).setSquareColour("red");
\r
108 // Get colour of occupied square
\r
112 $.fn.getColour = function()
\r
114 return $(this).html()[4]; // yeah, I know this is horrible, so sue me
\r
117 // Get type of piece
\r
118 $.fn.getType = function()
\r
120 return $(this).html().match(/<bold>(.*)<\/bold>/)[1]; // again, I know it's horrible, so sue me
\r
124 $.fn.getX = function() {return Number($(this).attr("id")[0]);}
\r
125 $.fn.getY = function() {return Number($(this).attr("id")[1]);}
\r
127 // Check a square is a valid selection
\r
128 $.fn.legalSelection = function()
\r
130 return ($(this).getColour() == playerColour);
\r
133 // determine whether a piece can move into another square
\r
134 $.fn.legalMove = function(target)
\r
136 if (target.getColour() == $(this).getColour())
\r
138 if (target.getX() == $(this).getX() && target.getY() == $(this).getY())
\r
140 switch ($(this).getType())
\r
142 case pieceChar["W"]['p']:
\r
143 if ($(this).getY() == 6 && target.getY() == 4 && $(this).getX() == target.getX() && target.getColour() == '0')
\r
145 if ($(this).getY() - target.getY() != 1 || Math.abs($(this).getX() - target.getX()) > 1)
\r
147 return ($(this).getX() == target.getX() || target.getColour() != '0');
\r
149 case pieceChar["B"]['p']:
\r
150 if ($(this).getY() == 1 && target.getY() == 3 && $(this).getX() == target.getX())
\r
152 if ($(this).getY() - target.getY() != -1 || Math.abs($(this).getX() - target.getX()) > 1)
\r
154 return ($(this).getX() == target.getX() || target.getColour() != '0');
\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
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
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
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
182 if (Math.abs($(this).getX() - target.getX()) != 0 && Math.abs($(this).getY() - target.getY()) != 0)
\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
195 var c = $("#"+x+""+y).getColour();
\r
196 if (c === "W" || c === "B")
\r
198 console.log("Blocked at "+x+""+y);
\r
202 console.log("Scan ok at "+x+""+y);
\r
209 // Move square to another
\r
210 $.fn.move = function(dest)
\r
212 dest.html($(this).html());
\r
213 $(this).html(emptyHTML);
\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
218 oldHTML = dest.html();
\r
219 dest.html(oldHTML.replace(/<bold>.*<\/bold>/i, "<bold>?</bold>"));
\r
223 // Interpret AJAX response
\r
224 $.fn.update = function(data)
\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
230 var tokens = lines[i].split(" ");
\r
232 if (!isNaN(tokens[0]) && !isNaN(tokens[1]))
\r
234 s1 = $("#board").find("#"+tokens[0]+tokens[1])
\r
235 if (tokens[2] === "->")
\r
237 if (s1.html()[4] != '0')
\r
239 s2 = $("#board").find("#"+tokens[3]+tokens[4]);
\r
241 setTimeout((function(x)
\r
246 $("#board td").each(function() {$(this).setSquareColour("default");});
\r
247 x.setSquareColour("blue");
\r
248 setTimeout((function(xx)
\r
252 xx.setSquareColour("default"); canClick = true;
\r
253 $("#status").html(colourString(playerColour) + " SELECT?");
\r
260 else if (tokens.length === 4 && !isNaN(tokens[2]) && isNaN(tokens[3]))
\r
263 if (tokens[3] != "knight")
\r
266 var oldHTML = s1.html();
\r
267 var c = s1.getColour();
\r
268 if (tokens[2] == "1")
\r
270 oldHTML = oldHTML.substring(0, oldHTML.length-1)+pieceChar[c][t];
\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
276 $("#status").html(colourString(s1.getColour()) + " MOVE?");
\r
280 else switch (lines[i])
\r
283 pieceSelected = "";
\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
301 //Reset the colour of a square
\r
302 $.fn.setSquareColour = function(type)
\r
304 var colour = "000000";
\r
321 id = $(this).attr("id");
\r
322 if ((Number(id[0]) + Number(id[1])) % 2 == 0)
\r
324 colour = addHexColour(colour, "555555");
\r
326 $(this).css("background-color", "#"+colour);
\r
330 $.fn.boardLoad = function()
\r
333 for (var y = 0; y < 8; ++y)
\r
335 boardHTML += "<tr id=\"y"+y+"\">";
\r
336 for (var x = 0; x < 8; ++x)
\r
338 boardHTML += "<td id=\""+x+""+y+"\">"+emptyHTML+"</td>";
\r
340 boardHTML += "</tr>";
\r
342 $(this).html(boardHTML);
\r
344 $(this).find("td").each(function()
\r
346 $(this).setSquareColour("default");
\r
350 for (var x = 0; x < 8; ++x)
\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
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
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
390 // Add two hex colours
\r
391 function addHexColour(c1, c2)
\r
393 var hexStr = (parseInt(c1, 16) + parseInt(c2, 16)).toString(16);
\r
394 while (hexStr.length < 6) { hexStr = '0' + hexStr; } // Zero pad.
\r
398 function colourString(c)
\r
400 return (c == "W") ? "white" : "black";
\r
403 function otherColour(c)
\r
405 return (c == "W") ? "B" : "W";
\r