3 * jQuery interface for Quantum Chess
\r
5 * @authors Sam Moore and Mitch Pomery
\r
8 pieceSelected = ""; // currently selected piece
\r
9 playerColour = ""; // 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", m : "black"}}).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
48 $.ajax({url : "/cgi-bin/qchess.cgi", data : {r : "quit"}, success : function() {console.log("Quit game");}});
\r
52 // bind click event to table cells
\r
53 $("#board").on('click', 'td' , function(e)
\r
55 if (canClick === false)
\r
58 var id = $(this).attr("id");
\r
60 if (pieceSelected === "")
\r
62 if ($(this).legalSelection())
\r
65 $(this).setSquareColour("blue");
\r
70 alert("Illegal selection " + id);
\r
75 mover = $("#board").find("#"+pieceSelected);
\r
76 if (mover.legalMove($(this)))
\r
78 $("#status").html(colourString(otherColour(mover.getColour())) + " SELECT?");
\r
79 mover.move($(this));
\r
81 $("#board td").each(function() {$(this).setSquareColour("default");});
\r
86 alert("Illegal move " + id);
\r
93 $.ajax({url : "/cgi-bin/qchess.cgi", data : {x : id[0], y : id[1]}}).done(function(data) {$(this).update(data)});
\r
97 $.fn.showMoves = function()
\r
99 $(this).setSquareColour("green");
\r
100 var that = $(this); //Look [DJA]! I used it!
\r
101 $("#board td").each(function()
\r
103 if (that.legalMove($(this)) === true) // See?
\r
105 //alert("Legal move from " + that.attr("id") + " -> " + $(this).attr("id"));
\r
106 $(this).setSquareColour("red");
\r
112 // Get colour of occupied square
\r
116 $.fn.getColour = function()
\r
118 return $(this).html()[4]; // yeah, I know this is horrible, so sue me
\r
121 // Get type of piece
\r
122 $.fn.getType = function()
\r
124 return $(this).html().match(/<bold>(.*)<\/bold>/)[1]; // again, I know it's horrible, so sue me
\r
128 $.fn.getX = function() {return Number($(this).attr("id")[0]);}
\r
129 $.fn.getY = function() {return Number($(this).attr("id")[1]);}
\r
131 // Check a square is a valid selection
\r
132 $.fn.legalSelection = function()
\r
134 return ($(this).getColour() == playerColour);
\r
137 // determine whether a piece can move into another square
\r
138 $.fn.legalMove = function(target)
\r
140 if (target.getColour() == $(this).getColour())
\r
142 if (target.getX() == $(this).getX() && target.getY() == $(this).getY())
\r
144 switch ($(this).getType())
\r
146 case pieceChar["W"]['p']:
\r
147 if ($(this).getY() == 6 && target.getY() == 4 && $(this).getX() == target.getX() && target.getColour() == '0')
\r
149 if ($(this).getY() - target.getY() != 1 || Math.abs($(this).getX() - target.getX()) > 1)
\r
151 return ($(this).getX() == target.getX() || target.getColour() != '0');
\r
153 case pieceChar["B"]['p']:
\r
154 if ($(this).getY() == 1 && target.getY() == 3 && $(this).getX() == target.getX())
\r
156 if ($(this).getY() - target.getY() != -1 || Math.abs($(this).getX() - target.getX()) > 1)
\r
158 return ($(this).getX() == target.getX() || target.getColour() != '0');
\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
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
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
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
186 if (Math.abs($(this).getX() - target.getX()) != 0 && Math.abs($(this).getY() - target.getY()) != 0)
\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
199 var c = $("#"+x+""+y).getColour();
\r
200 if (c === "W" || c === "B")
\r
202 console.log("Blocked at "+x+""+y);
\r
206 console.log("Scan ok at "+x+""+y);
\r
213 // Move square to another
\r
214 $.fn.move = function(dest)
\r
216 dest.html($(this).html());
\r
217 $(this).html(emptyHTML);
\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
222 oldHTML = dest.html();
\r
223 dest.html(oldHTML.replace(/<bold>.*<\/bold>/i, "<bold>?</bold>"));
\r
227 // Interpret AJAX response
\r
228 $.fn.update = function(data)
\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
235 var tokens = lines[i].split(" ");
\r
237 if (!isNaN(tokens[0]) && !isNaN(tokens[1]))
\r
239 s1 = $("#board").find("#"+tokens[0]+tokens[1])
\r
240 if (tokens[2] === "->")
\r
242 if (s1.html()[4] != '0')
\r
244 s2 = $("#board").find("#"+tokens[3]+tokens[4]);
\r
246 setTimeout((function(x)
\r
251 $("#board td").each(function() {$(this).setSquareColour("default");});
\r
252 x.setSquareColour("blue");
\r
253 setTimeout((function(xx)
\r
257 xx.setSquareColour("default"); canClick = true;
\r
258 $("#status").html(colourString(playerColour) + " SELECT?");
\r
265 else if (tokens.length === 4 && !isNaN(tokens[2]) && isNaN(tokens[3]))
\r
268 if (tokens[3] != "knight")
\r
271 var oldHTML = s1.html();
\r
272 var c = s1.getColour();
\r
273 if (tokens[2] == "1")
\r
275 oldHTML = oldHTML.substring(0, oldHTML.length-1)+pieceChar[c][t];
\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
281 $("#status").html(colourString(s1.getColour()) + " MOVE?");
\r
285 else switch (lines[i])
\r
289 pieceSelected = "";
\r
294 case "START white":
\r
295 if (playerColour == "")
\r
297 playerColour = "W";
\r
300 case "START black":
\r
301 if (playerColour == "")
\r
303 playerColour = "B";
\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
317 if (timeout == false)
\r
321 //Reset the colour of a square
\r
322 $.fn.setSquareColour = function(type)
\r
324 var colour = "000000";
\r
341 id = $(this).attr("id");
\r
342 if ((Number(id[0]) + Number(id[1])) % 2 == 0)
\r
344 colour = addHexColour(colour, "555555");
\r
346 $(this).css("background-color", "#"+colour);
\r
350 $.fn.boardLoad = function()
\r
353 for (var y = 0; y < 8; ++y)
\r
355 boardHTML += "<tr id=\"y"+y+"\">";
\r
356 for (var x = 0; x < 8; ++x)
\r
358 boardHTML += "<td id=\""+x+""+y+"\">"+emptyHTML+"</td>";
\r
360 boardHTML += "</tr>";
\r
362 $(this).html(boardHTML);
\r
364 $(this).find("td").each(function()
\r
366 $(this).setSquareColour("default");
\r
370 for (var x = 0; x < 8; ++x)
\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
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
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
410 // Add two hex colours
\r
411 function addHexColour(c1, c2)
\r
413 var hexStr = (parseInt(c1, 16) + parseInt(c2, 16)).toString(16);
\r
414 while (hexStr.length < 6) { hexStr = '0' + hexStr; } // Zero pad.
\r
418 function colourString(c)
\r
420 return (c == "W") ? "white" : "black";
\r
423 function otherColour(c)
\r
425 return (c == "W") ? "B" : "W";
\r