diff --git a/qchess/qchess.py b/qchess/qchess.py
old mode 100644
new mode 100755
index 092a121dedd871abede9903298d324cdf4f247fd..da4cab7d8b2e2bb37cb10010c5682af3a21f7bab
--- a/qchess/qchess.py
+++ b/qchess/qchess.py
@@ -890,9 +890,11 @@ class HumanPlayer(Player):
 				sys.stdout.write("SELECTION?\n")
 				try:
 					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
+					return p
 				except:
 					sys.stderr.write("ILLEGAL GIBBERISH\n")
 					continue
+
 	# It's your move captain
 	def get_move(self):
 		if isinstance(graphics, GraphicsThread):
@@ -908,6 +910,7 @@ class HumanPlayer(Player):
 				sys.stdout.write("MOVE?\n")
 				try:
 					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
+					return p
 				except:
 					sys.stderr.write("ILLEGAL GIBBERISH\n")
 					continue
@@ -1673,11 +1676,10 @@ class GameThread(StoppableThread):
 		self.cond = threading.Condition() # conditional for some reason, I forgot
 		self.final_result = ""
 		self.server = server
+		self.retry_illegal = False
 		
 		
-			
-		
-		
+	
 
 	# Run the game (run in new thread with start(), run in current thread with run())
 	def run(self):
@@ -1804,14 +1806,17 @@ class GameThread(StoppableThread):
 						break
 				except Exception,e:
 				#if False:
-					result = e.message
-					sys.stderr.write("qchess.py exception: "+result + "\n")
-					
-					self.stop()
+
 					
-					with self.lock:
-						self.final_result = self.state["turn"].colour + " " + e.message
-					break
+					result = e.message
+					if self.retry_illegal:
+						self.state["turn"].update(result);
+					else:
+						sys.stderr.write("qchess.py exception: "+result + "\n")
+						self.stop()
+						with self.lock:
+							self.final_result = self.state["turn"].colour + " " + e.message
+						break
 
 
 
@@ -2701,6 +2706,7 @@ def main(argv):
 	global sleep_timeout
 
 
+	retry_illegal = False
 	server_addr = None
 
 	max_moves = None
@@ -2798,7 +2804,8 @@ def main(argv):
 				sleep_timeout = -1
 			else:
 				sleep_timeout = float(arg[2:].split("=")[1])
-				
+		elif (arg[1] == '-' and arg[2:] == "retry-illegal"):
+			retry_illegal = not retry_illegal
 		elif (arg[1] == '-' and arg[2:] == "help"):
 			# Help
 			os.system("less data/help.txt") # The best help function
@@ -2845,6 +2852,7 @@ def main(argv):
 		board = Board(style)
 		board.max_moves = max_moves
 		game = GameThread(board, players) 
+		game.retry_illegal = retry_illegal
 
 
 
@@ -2987,4 +2995,4 @@ if __name__ == "__main__":
 		
 
 # --- main.py --- #
-# EOF - created from make on Sun May 19 12:36:10 WST 2013
+# EOF - created from make on Thursday 20 June  18:09:07 WST 2013
diff --git a/qchess/src/game.py b/qchess/src/game.py
index 73adfe75cb078c1c87bc08b231ce2b2cacc2db6f..15c53b1315086129fcc8dd21497b1ad7b3393bd9 100644
--- a/qchess/src/game.py
+++ b/qchess/src/game.py
@@ -15,11 +15,10 @@ class GameThread(StoppableThread):
 		self.cond = threading.Condition() # conditional for some reason, I forgot
 		self.final_result = ""
 		self.server = server
+		self.retry_illegal = False
 		
 		
-			
-		
-		
+	
 
 	# Run the game (run in new thread with start(), run in current thread with run())
 	def run(self):
@@ -146,14 +145,17 @@ class GameThread(StoppableThread):
 						break
 				except Exception,e:
 				#if False:
-					result = e.message
-					sys.stderr.write("qchess.py exception: "+result + "\n")
-					
-					self.stop()
+
 					
-					with self.lock:
-						self.final_result = self.state["turn"].colour + " " + e.message
-					break
+					result = e.message
+					if self.retry_illegal:
+						self.state["turn"].update(result);
+					else:
+						sys.stderr.write("qchess.py exception: "+result + "\n")
+						self.stop()
+						with self.lock:
+							self.final_result = self.state["turn"].colour + " " + e.message
+						break
 
 
 
diff --git a/qchess/src/main.py b/qchess/src/main.py
index 6ebf70c0972984a4a7db73cb3196a237084b940a..44aa36075a8444ace5777991b5d1141923d020ac 100644
--- a/qchess/src/main.py
+++ b/qchess/src/main.py
@@ -88,6 +88,7 @@ def main(argv):
 	global sleep_timeout
 
 
+	retry_illegal = False
 	server_addr = None
 
 	max_moves = None
@@ -185,7 +186,8 @@ def main(argv):
 				sleep_timeout = -1
 			else:
 				sleep_timeout = float(arg[2:].split("=")[1])
-				
+		elif (arg[1] == '-' and arg[2:] == "retry-illegal"):
+			retry_illegal = not retry_illegal
 		elif (arg[1] == '-' and arg[2:] == "help"):
 			# Help
 			os.system("less data/help.txt") # The best help function
@@ -232,6 +234,7 @@ def main(argv):
 		board = Board(style)
 		board.max_moves = max_moves
 		game = GameThread(board, players) 
+		game.retry_illegal = retry_illegal
 
 
 
diff --git a/qchess/src/player.py b/qchess/src/player.py
index 346674b227bc9296ade7bba59a19945733ceb555..fffa73855df09f31f61bfd967764214e47541c78 100644
--- a/qchess/src/player.py
+++ b/qchess/src/player.py
@@ -265,9 +265,11 @@ class HumanPlayer(Player):
 				sys.stdout.write("SELECTION?\n")
 				try:
 					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
+					return p
 				except:
 					sys.stderr.write("ILLEGAL GIBBERISH\n")
 					continue
+
 	# It's your move captain
 	def get_move(self):
 		if isinstance(graphics, GraphicsThread):
@@ -283,6 +285,7 @@ class HumanPlayer(Player):
 				sys.stdout.write("MOVE?\n")
 				try:
 					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
+					return p
 				except:
 					sys.stderr.write("ILLEGAL GIBBERISH\n")
 					continue
diff --git a/web/qwebchess/index.html b/web/qwebchess/index.html
index 73b77c01865bc3bd3aa274321ab2a1d98973b1d9..aaf170fb5c6943d430a429c619b6f4db02fe3b59 100644
--- a/web/qwebchess/index.html
+++ b/web/qwebchess/index.html
@@ -1,26 +1,52 @@
 <html>
 <head>
-	<title>QChess Web UI</title>
+	<title id="status">QChess Web UI</title>
 	<!--<link rel="stylesheet" href="css.css" />-->
+	<script type="text/javascript" src="jquery-1.10.1.min.js"></script>
 	<script type="text/javascript" src="js.js"></script>
+
+	<style>
+		div
+		{
+			position:relative;
+			width:600px;
+			height:800px;
+			text-align:center;
+		}
+
+		input 
+		{
+			position:relative;
+			width:80px;
+			height:30px;
+		}
+
+	</style>
+
 </head>
 
-<body onload="javascript:boardLoad();" style="width: 100%">
-
-<div>
-<table style="margin-left: auto; margin-right: auto; font-size: 20" width=600px height=600px>
-<tr><td onclick="javascript:selectPiece('00');" id="00"></td><td onclick="javascript:selectPiece('01');" id="01"></td><td onclick="javascript:selectPiece('02');" id="02"></td><td onclick="javascript:selectPiece('03');" id="03"></td><td onclick="javascript:selectPiece('04');" id="04"></td><td onclick="javascript:selectPiece('05');" id="05"></td><td onclick="javascript:selectPiece('06');" id="06"></td><td onclick="javascript:selectPiece('07');" id="07"></td></tr>
-<tr><td onclick="javascript:selectPiece('10');" id="10"></td><td onclick="javascript:selectPiece('11');" id="11"></td><td onclick="javascript:selectPiece('12');" id="12"></td><td onclick="javascript:selectPiece('13');" id="13"></td><td onclick="javascript:selectPiece('14');" id="14"></td><td onclick="javascript:selectPiece('15');" id="15"></td><td onclick="javascript:selectPiece('16');" id="16"></td><td onclick="javascript:selectPiece('17');" id="17"></td></tr>
-<tr><td onclick="javascript:selectPiece('20');" id="20"></td><td onclick="javascript:selectPiece('21');" id="21"></td><td onclick="javascript:selectPiece('22');" id="22"></td><td onclick="javascript:selectPiece('23');" id="23"></td><td onclick="javascript:selectPiece('24');" id="24"></td><td onclick="javascript:selectPiece('25');" id="25"></td><td onclick="javascript:selectPiece('26');" id="26"></td><td onclick="javascript:selectPiece('27');" id="27"></td></tr>
-<tr><td onclick="javascript:selectPiece('30');" id="30"></td><td onclick="javascript:selectPiece('31');" id="31"></td><td onclick="javascript:selectPiece('32');" id="32"></td><td onclick="javascript:selectPiece('33');" id="33"></td><td onclick="javascript:selectPiece('34');" id="34"></td><td onclick="javascript:selectPiece('35');" id="35"></td><td onclick="javascript:selectPiece('36');" id="36"></td><td onclick="javascript:selectPiece('37');" id="37"></td></tr>
-<tr><td onclick="javascript:selectPiece('40');" id="40"></td><td onclick="javascript:selectPiece('41');" id="41"></td><td onclick="javascript:selectPiece('42');" id="42"></td><td onclick="javascript:selectPiece('43');" id="43"></td><td onclick="javascript:selectPiece('44');" id="44"></td><td onclick="javascript:selectPiece('45');" id="45"></td><td onclick="javascript:selectPiece('46');" id="46"></td><td onclick="javascript:selectPiece('47');" id="47"></td></tr>
-<tr><td onclick="javascript:selectPiece('50');" id="50"></td><td onclick="javascript:selectPiece('51');" id="51"></td><td onclick="javascript:selectPiece('52');" id="52"></td><td onclick="javascript:selectPiece('53');" id="53"></td><td onclick="javascript:selectPiece('54');" id="54"></td><td onclick="javascript:selectPiece('55');" id="55"></td><td onclick="javascript:selectPiece('56');" id="56"></td><td onclick="javascript:selectPiece('57');" id="57"></td></tr>
-<tr><td onclick="javascript:selectPiece('60');" id="60"></td><td onclick="javascript:selectPiece('61');" id="61"></td><td onclick="javascript:selectPiece('62');" id="62"></td><td onclick="javascript:selectPiece('63');" id="63"></td><td onclick="javascript:selectPiece('64');" id="64"></td><td onclick="javascript:selectPiece('65');" id="65"></td><td onclick="javascript:selectPiece('66');" id="66"></td><td onclick="javascript:selectPiece('67');" id="67"></td></tr>
-<tr><td onclick="javascript:selectPiece('70');" id="70"></td><td onclick="javascript:selectPiece('71');" id="71"></td><td onclick="javascript:selectPiece('72');" id="72"></td><td onclick="javascript:selectPiece('73');" id="73"></td><td onclick="javascript:selectPiece('74');" id="74"></td><td onclick="javascript:selectPiece('75');" id="75"></td><td onclick="javascript:selectPiece('76');" id="76"></td><td onclick="javascript:selectPiece('77');" id="77"></td></tr>
-</table>
-<br />
-<br />
-<small>Made By Sam Moore [SZM] and Mitchell Pomery [BG3]</small>
+<body style="width: 100%">
+
+
+<p id="welcome"> Press the button to start </p>
+
+<div style="width:100%;">
+	<!-- Board and UI -->
+	<div>
+		<table style="margin-left: auto; margin-right: auto; font-size: 18" width=500px height=500px id="board"></table>
+		<button id="start">New Game</button>
+		<p id="loglink"></p>
+	</div>
+
+	<!-- Message box 
+	<div style="float:right;">
+		<h2>Messages</h2>
+		<input type="text" value="" id="messages" style="width:80%; height:80%;">
+		<input type="text" value="" id="say" style="width:60%;">
+		<button id="message" style="width:20%;">Send</button>
+	</div> -->
 </div>
+
+
 </body>
 </html>
diff --git a/web/qwebchess/js.js b/web/qwebchess/js.js
index 7baea20bd8f86ce938ed984ba18ea58083cc2399..db91e14d7dd7c01f6d59f0fd709e09d533653b90 100644
--- a/web/qwebchess/js.js
+++ b/web/qwebchess/js.js
@@ -1,11 +1,12 @@
-//progcomp.ucc.asn.au/cgi-bin/qchess.cgi?r=start
-//progcomp.ucc.asn.au/cgi-bin/qchess.cgi?r=quit
-//progcomp.ucc.asn.au/cgi-bin/qchess.cgi?x=X&y=Y (0 indexed)
+/**
+ * qwebchess.js
+ * jQuery interface for Quantum Chess
+ *
+ * @authors Sam Moore and Mitch Pomery
+ */
 
 pieceSelected = ""; // currently selected piece
-piece = "";
-colour = "W"; // colour of this player
-canClick = true;
+playerColour = "W"; // colour of this player
 
 // Unicode representations of chess pieces
 pieceChar = {"W" : { "p" : "\u2659", "h" : "\u2658", "b" : "\u2657", "r" : "\u2656", "q" : "\u2655", "k" : "\u2654", "?" : "?"},
@@ -13,250 +14,393 @@ pieceChar = {"W" : { "p" : "\u2659", "h" : "\u2658", "b" : "\u2657", "r" : "\u26
 
 emptyHTML = "<!--0-->&nbsp; <big> <bold>&nbsp;</bold> </big> &nbsp;"
 
-// Select (or move) a piece
-function selectPiece(loc) {
-	if (!canClick)
-		return;
-
-	x = (""+loc).charAt(1);
-	y = (""+loc).charAt(0);
-	//alert(loc);
+gameStarted = false;
+canClick = true;
 
-	// work out whether to select or move based on the comment tag for the clicked location
-	// It is either "<!--W-->" (white; select) or <!--B-->" (black) or "<!--0-->" (empty)
-	if (pieceSelected == "") 
+// jQuery foo goes in here
+$(document).ready(function()
+{
+	// Click the start/quit button
+	$("#start").click(function() 
 	{
-		square = document.getElementById(loc);
-		if (square.innerHTML.charAt(4) == colour) 
+		if (gameStarted === false)
 		{
-			console.log("Piece Selected: " + loc);
-			pieceSelected = loc;
-			ajaxUpdate("x=" + x + "&y=" + y);
-			if ((+x + +y) % 2 == 0)
-				square.style.background = "#DFD";
-			else
-				square.style.background = "#8F8";
-		}
-	}
-	else {
-		//alert("pieceMoved");
-		if (validMove(pieceSelected, piece, loc)) {
-			doMove(pieceSelected, loc);
-			ajaxUpdate("x=" + x + "&y=" + y);
+			gameStarted = true;
+			$("#board").boardLoad();
+			$("#welcome").hide();
+			$("#status").show();
+			$("#status").html("white SELECT?");
+			$("#start").html("Quit Game");
 			pieceSelected = "";
+			canClick = true;
+			$.ajax({url : "/cgi-bin/qchess.cgi", data : {r : "force_quit"}, success : function() {}});
+			$.ajax({url : "/cgi-bin/qchess.cgi", data : {r : "start"}}).done(function(data) {$(this).update(data)});
+		
+				
 		}
-		else {
-			console.log("Invalid Move");
+		else
+		{
+			gameStarted = false;
+			$("#welcome").show();
+			$("#status").html("Game over");
+			$("#start").html("New Game");
+			$.ajax({url : "/cgi-bin/qchess.cgi", data : {r : "quit"}, success : function() {console.log("Quit game");}});
 		}
-	}
-}
+	});
 
-function resetColour(loc)
-{
-	square = document.getElementById(loc);
-	if ((+loc[loc.length-1] + +loc[loc.length-2]) % 2 == 0)
-		square.style.background = "#FFF";
-	else
-		square.style.background = "#DDD";
+	// bind click event to table cells
+	$("#board").on('click', 'td' , function(e)
+	{
+		if (canClick === false)
+			return;
+	
+		var id = $(this).attr("id");	
+		legal = true;
+		if (pieceSelected === "")
+		{
+			if ($(this).legalSelection())
+			{
+				pieceSelected = id;
+				$(this).setSquareColour("blue");
+			}
+			else
+			{
+				legal = false;
+				alert("Illegal selection " + id);
+			}
+		}
+		else
+		{
+			mover = $("#board").find("#"+pieceSelected);
+			if (mover.legalMove($(this)))
+			{
+				$("#status").html(colourString(otherColour(mover.getColour())) + " SELECT?");
+				mover.move($(this));
+				pieceSelected = "";
+				$("#board td").each(function() {$(this).setSquareColour("default");});
+			}
+			else
+			{
+				legal = false;
+				alert("Illegal move " + id);
+			}
+		}
 		
-}
+		if (legal)
+			$.ajax({url : "/cgi-bin/qchess.cgi", data : {x : id[0], y : id[1]}}).done(function(data) {$(this).update(data)});
+	});
 
-function validMove(start, piece, end) {
-	return true;
-}
-
-function doMove(start, end) {
-	alert("doMove("+start+","+end+")");
-	s1 = document.getElementById(start);
-	s2 = document.getElementById(end);
-	s2.innerHTML = s1.innerHTML;
-	s1.innerHTML = emptyHTML;
+	$.fn.showMoves = function()
+	{
+		$(this).setSquareColour("green");
+		var that = $(this); //Look [DJA]! I used it!
+		$("#board td").each(function()
+		{
+			if (that.legalMove($(this)) === true) // See?
+			{
+				//alert("Legal move from " + that.attr("id") + " -> " + $(this).attr("id"));
+				$(this).setSquareColour("red");
+			}
+		});
+		
+	}
 
-	resetColour(start);
+	// Get colour of occupied square
+	// W - white
+	// B - black
+	// 0 - unoccupied
+	$.fn.getColour = function()
+	{
+		return $(this).html()[4]; // yeah, I know this is horrible, so sue me
+	}
 
-	if ((+end[end.length-1] + +end[end.length-2]) % 2 == 1)
+	// Get type of piece
+	$.fn.getType = function()
 	{
-		s2.innerHTML = s2.innerHTML.replace(/<bold>.*<\/bold>/i, "<bold>?</bold>");
+		return $(this).html().match(/<bold>(.*)<\/bold>/)[1]; // again, I know it's horrible, so sue me
 	}
-	//console.log("Piece Moved");
-}
 
-function boardLoad() {
-	ajaxUpdate("r=force_quit");
-	
+	// Get coords
+	$.fn.getX = function() {return Number($(this).attr("id")[0]);}
+	$.fn.getY = function() {return Number($(this).attr("id")[1]);}
 	
-	
-	for (i = 0; i < 8; i++) {
-		for (j = 0; j < 8; j++) {
-			e = ""+i + "" + j;
-			resetColour(e);
-		}
+	// Check a square is a valid selection
+	$.fn.legalSelection = function()
+	{
+		return ($(this).getColour() == playerColour);
 	}
-	
-	//Place pieces on the board
-	for (i = 0; i < 8; i++) {
-		black = document.getElementById("1" + i);
-		white = document.getElementById("6" + i);
-		//pawns
-		black.innerHTML = "<!--B--> " + pieceChar["B"]["p"] + " <big> <bold>?</bold> </big> ?";
-		white.innerHTML = "<!--W--> " + pieceChar["W"]["p"] + " <big> <bold>?</bold> </big> ?";
-		
-		black = document.getElementById("0" + i);
-		white = document.getElementById("7" + i);
-		piece = "p";
-		if (i == 0 || i == 7)
-			piece = "r";
-		if (i == 1 || i == 6)
-			piece = "h";
-		if (i == 2 || i == 5)
-			piece = "b";
-		if (i == 3)
-			piece = "k";
-		if (i == 4)
-			piece = "q";
-		//major pieces
-		black.innerHTML = "<!--B--> " + pieceChar["B"][piece] + "<big> <bold>?</bold> </big> ?";
-		white.innerHTML = "<!--W--> " + pieceChar["W"][piece] + "<big> <bold>?</bold> </big> ?";
 
-		// empty squares
-		for (j = 2; j < 6; j++)
+	// determine whether a piece can move into another square
+	$.fn.legalMove = function(target)
+	{
+		if (target.getColour() == $(this).getColour())
+			return false;
+		if (target.getX() == $(this).getX() && target.getY() == $(this).getY())
+			return false;
+		switch ($(this).getType())
 		{
-			square = document.getElementById(""+j + i);
-			square.innerHTML = emptyHTML;
-		}
-	}
-	
-	setTimeout(function(){ajaxUpdate("r=start");}, 1000);
-}
+			case pieceChar["W"]['p']:
+				if ($(this).getY() == 6 && target.getY() == 4 && $(this).getX() == target.getX() && target.getColour() == '0')
+					return true;
+				if ($(this).getY() - target.getY() != 1 || Math.abs($(this).getX() - target.getX()) > 1)
+					return false;
+				return ($(this).getX() == target.getX() || target.getColour() != '0');
+
+			case pieceChar["B"]['p']:
+				if ($(this).getY() == 1 && target.getY() == 3 && $(this).getX() == target.getX())
+					return true;
+                                if ($(this).getY() - target.getY() != -1 || Math.abs($(this).getX() - target.getX()) > 1)
+	                                return false;
+                                return ($(this).getX() == target.getX() || target.getColour() != '0');
 
-//AJAX Stuff
-function ajaxUpdate(queryString) {
-	var ajaxRequest;  // The variable that makes Ajax possible!
+			case pieceChar["W"]['h']:
+			case pieceChar["B"]['h']:
+				return ((Math.abs($(this).getY() - target.getY()) == 2 && Math.abs($(this).getX() - target.getX()) == 1)
+					|| (Math.abs($(this).getX() - target.getX()) == 2 && Math.abs($(this).getY() - target.getY()) == 1));
 
-	try {
-		// Opera 8.0+, Firefox, Safari
-		ajaxRequest = new XMLHttpRequest();
-	} catch (e) {
-		// Internet Explorer Browsers
-		try {
-			ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
-		} catch (e) {
-			try {
-				ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
-			} catch (e) {
-				// Something went wrong
-				alert("Your Browser is not Ajax Compatible, Please Upgrade to Google Chrome.");
+			case pieceChar["W"]['k']:
+			case pieceChar["B"]['k']:
+				return (Math.abs($(this).getX() - target.getX()) <= 1 && Math.abs($(this).getY() - target.getY()) <= 1);
+			case pieceChar["W"]['b']:
+			case pieceChar["B"]['b']:
+				//console.log("" + Math.abs($(this).getX() - target.getX()) + " vs " + Math.abs($(this).getY() - target.getY()));
+				if (Math.abs($(this).getX() - target.getX()) != Math.abs($(this).getY() - target.getY()))
+					return false;
+				break;
+			case pieceChar["W"]['r']:
+			case pieceChar["B"]['r']:
+				//console.log("" + Math.abs($(this).getX() - target.getX()) + " vs " + Math.abs($(this).getY() - target.getY()));
+				console.log("Rook");
+				if (Math.abs($(this).getX() - target.getX()) != 0 && Math.abs($(this).getY() - target.getY()) != 0)
+					return false;
+				break;
+			case pieceChar["W"]['q']:
+			case pieceChar["B"]['q']:
+				//console.log("" + Math.abs($(this).getX() - target.getX()) + " vs " + Math.abs($(this).getY() - target.getY()));
+				if (Math.abs($(this).getX() - target.getX()) != Math.abs($(this).getY() - target.getY()))
+				{
+					if (Math.abs($(this).getX() - target.getX()) != 0 && Math.abs($(this).getY() - target.getY()) != 0)
+						return false;
+				}
+				break;
+			default:
 				return false;
-			}
 		}
+		console.log("scanning");
+		var vx = ($(this).getX() == target.getX()) ? 0 : (($(this).getX() < target.getX()) ? 1 : -1);
+		var vy = ($(this).getY() == target.getY()) ? 0 : (($(this).getY() < target.getY()) ? 1 : -1);
+		var x = $(this).getX() + vx; var y = $(this).getY() + vy;
+		while ((x != target.getX() || y != target.getY()) && x >= 0 && y >= 0 && x < 8 && y < 8)
+		{
+			var c = $("#"+x+""+y).getColour();
+			if (c === "W" || c === "B")
+			{
+				console.log("Blocked at "+x+""+y);
+				return false;
+			}
+			else
+				console.log("Scan ok at "+x+""+y);
+			x += vx;
+			y += vy;			
+		}	
+		return true;
 	}
-	
-	//alert(queryString);
-	
-	// Create a function that will receive data sent from the server
-	ajaxRequest.onreadystatechange = function () 
+
+	// Move square to another
+	$.fn.move = function(dest)
 	{
-		//alert("RS" + ajaxRequest.readyState);
-		if (ajaxRequest.readyState == 4) {
-			console.log("AJAX Response: " + ajaxRequest.responseText);
-			lines = ajaxRequest.responseText.split("\n");
+		dest.html($(this).html());
+		$(this).html(emptyHTML);
 
-			for (var i = 0; i < lines.length; ++i)
-			{
-				tokens = lines[i].split(" ")
-				x = Number(tokens[0]);
+		// Collapse into quantum state if on a black square
+		if ((dest.getX() + dest.getY()) % 2 != 0 && (dest.html()[0] == '?' || dest.html()[dest.html().length-1] == '?'))
+		{
+			oldHTML = dest.html();
+			dest.html(oldHTML.replace(/<bold>.*<\/bold>/i, "<bold>?</bold>"));
+		}
+	}
 
-				if (isNaN(tokens[0]) || isNaN(tokens[1]))
-					continue;
+	// Interpret AJAX response
+	$.fn.update = function(data)
+	{
+		console.log("AJAX Response:\n"+data);
+		var lines = data.split("\n");
+		for (var i = 0; i < lines.length; ++i)
+		{
+			var tokens = lines[i].split(" ");
 
-                                var s1 = document.getElementById("" + tokens[1] + "" + tokens[0]);
-				var s2 = document.getElementById("" + tokens[4] + "" + tokens[3]);
-				if (tokens[2] == "->" && s1.innerHTML.charAt(4) != '0')
+			if (!isNaN(tokens[0]) && !isNaN(tokens[1]))
+			{
+				s1 = $("#board").find("#"+tokens[0]+tokens[1])
+				if (tokens[2] === "->")
 				{
-					canClick = false;
-					if ((+tokens[0] + +tokens[1]) % 2 == 0)
-						s1.style.background = "#DFD";
-					else
-						s1.style.background = "#8F8";
-
-					var doThisMove = function(start, end) {doMove(start, end); canClick = true;}(""+tokens[1]+""+tokens[0], ""+tokens[4]+""+tokens[3]);
-					setTimeout(function() {doThisMove(); canClick = true;}, 500);
+					if (s1.html()[4] != '0')
+					{
+						s2 = $("#board").find("#"+tokens[3]+tokens[4]);
+						canClick = false;
+						setTimeout((function(x) 
+						{
+							return function() 
+							{
+								s1.move(x);
+								$("#board td").each(function() {$(this).setSquareColour("default");});
+								x.setSquareColour("blue");
+								setTimeout((function(xx) 
+								{
+									return function() 
+									{
+										xx.setSquareColour("default"); canClick = true;
+										$("#status").html(colourString(playerColour) + " SELECT?");
+									};
+								}(x)), 500);
+							};
+						}(s2)), 500);
+					}
 				}
-				else if (tokens.length == 4 && !isNaN(tokens[0]) && !isNaN(tokens[1]) && !isNaN(tokens[2]) && isNaN(tokens[3]))
+				else if (tokens.length === 4 && !isNaN(tokens[2]) && isNaN(tokens[3]))
 				{
-					html = s1.innerHTML;
-					c = html.charAt(4);
-					piece = tokens[3];
-					if (piece == "knight") //HACK
-						piece = "h";	
-					else
-						piece = ""+piece.charAt(0);
+					var t = "h";
+					if (tokens[3] != "knight")
+						t = tokens[3][0];
+			
+					var oldHTML = s1.html();
+					var c = s1.getColour();
 					if (tokens[2] == "1")
-						html[html.length-1] = pieceChar[c][piece];
-
-					s1.innerHTML = html.replace(/<bold>.*<\/bold>/i, "<bold>"+pieceChar[c][piece]+"</bold>");	
-				}
-			}
-
-			/*
-			if (ret.charAt(4) == "-" && ret.charAt(5) == ">") {
-				//Piece has been moved
-				//console.log("Moving other piece");
-				lines = ret.split("\n");
-				//if (lines[3] != "SELECT?") {
-				if (lines[2] != "SELECT?") {
-					x1 = lines[2].charAt(0);
-					y1 = lines[2].charAt(2);
-					x2 = lines[2].charAt(7);
-					y2 = lines[2].charAt(9);
-					console.log("Black Move: " + x1 + "" + y1 + " -> " + x2 + "" + y2);
-					doMove(y1 + "" + x1, y2 + "" + x2);
-				}
-				else {
-					console.log("Black Unable to move");
-				}
-			}
-			else {
-				lines = ret.split("\n");
-				if (lines[1] == "MOVE?") {
-					//We selected a piece
-					//console.log("choose where to move our piece");
-					piece = lines[0].charAt(6);
-					//console.log("Piece: " + piece);
-					content = document.getElementById(pieceSelected);
-					contentHTML = content.innerHTML;
-					//contentHTML = contentHTML.replace("?", piece);
-					//"W<br /><small>p</small> <bold>?</bold> <small>?</small></span>";
-					if (lines[0].charAt(4) == "1") {
-						//console.log("changing quantum piece");
-						contentHTML = replaceAt(contentHTML, 44, piece);
+					{
+						oldHTML = oldHTML.substring(0, oldHTML.length-1)+pieceChar[c][t];
 					}
-					contentHTML = replaceAt(contentHTML, 28, piece);
-					//console.log(contentHTML);
-					//contentHTML = "CHANGED" + contentHTML;
-					content.innerHTML = contentHTML;
+					s1.html(oldHTML.replace(/<bold>.*<\/bold>/i, "<bold>"+pieceChar[c][t]+"</bold>"));
+					//console.log(oldHTML + " ==> " + s1.html());
+					s1.setSquareColour("green");
+					s1.showMoves();
+					$("#status").html(colourString(s1.getColour()) + " MOVE?");
+					
 				}
 			}
-			*/
-			//alert(ret);
+			else switch (lines[i])
+			{
+				case "SELECT?":
+					pieceSelected = "";
+				case "MOVE?":
+				case "":
+				case "New game.":
+					break;
+				default:
+					alert("Game ends: " + lines[i]);
+					gameStarted = false;
+					$("#start").html("New Game");
+					$("#status").html("Game over");
+					//$("#board").html("");
+					
+					
+					break;
+			}
 		}
 	}
-	
-	//ar = "http://progcomp.ucc.asn.au/cgi-bin/qchess.cgi?" + queryString;
-	ar = "/../../../cgi-bin/qchess.cgi?" + queryString;
-	
-	console.log("AJAX Request: " + ar);
-	
-	ajaxRequest.open("GET", ar, true);
-	ajaxRequest.send();
-}
 
+	//Reset the colour of a square
+	$.fn.setSquareColour = function(type)
+	{
+		var colour = "000000";
+	        switch (type)
+        	{
+	                case "blue":
+                	        colour = "5555aa";
+        	                break;
+			case "green":
+				colour = "55aa55";
+				break;
+			case "red":
+				colour = "aa5555";
+				break;
+	                default:
+                	        colour = "aaaaaa";
+        	                break;
+	        }
+
+	        id = $(this).attr("id");
+        	if ((Number(id[0]) + Number(id[1])) % 2 == 0)
+	        {	
+        	        colour = addHexColour(colour, "555555");
+	        }
+        	$(this).css("background-color", "#"+colour);
+	}
+
+	// Loads the board
+	$.fn.boardLoad = function()
+	{
+        	boardHTML = "";
+	        for (var y = 0; y < 8; ++y)
+	        {
+                	boardHTML += "<tr id=\"y"+y+"\">";
+        	        for (var x = 0; x < 8; ++x)
+	                {
+                        	boardHTML += "<td id=\""+x+""+y+"\">"+emptyHTML+"</td>";
+                	}
+        	        boardHTML += "</tr>";
+	        }
+        	$(this).html(boardHTML);
+
+	        $(this).find("td").each(function()
+        	{
+	                $(this).setSquareColour("default");
+	        });
 
+		// Add pieces
+		for (var x = 0; x < 8; ++x)
+		{
+			// pawns
+			$(this).find("#"+x+"1").html("<!--B--> "+pieceChar["B"]["p"]+"<big> <bold>?</bold> </big> ?");
+			$(this).find("#"+x+"6").html("<!--W--> "+pieceChar["W"]["p"]+"<big> <bold>?</bold> </big> ?");
+		
+			t = "?";
+			switch (x)
+			{
+				case 0:
+				case 7:
+					t = 'r';
+					break;
+				case 1:
+				case 6:
+					t = 'h';
+					break;
+				case 2:
+				case 5:
+					t = 'b';
+					break;
+				case 4:
+					t = 'q';
+					break;
+			}
+			if (x == 3)
+				continue;
+			$(this).find("#"+x+"0").html("<!--B--> "+pieceChar["B"][t]+"<big> <bold>?</bold> </big> ?");
+			$(this).find("#"+x+"7").html("<!--W--> "+pieceChar["W"][t]+"<big> <bold>?</bold> </big> ?");
+		}
+		t = pieceChar["B"]["k"];
+		$(this).find("#30").html("<!--B--> "+t+"<big> <bold>"+t+"</bold> </big> "+t);
+		t = pieceChar["W"]["k"];
+                $(this).find("#37").html("<!--W--> "+t+"<big> <bold>"+t+"</bold> </big> "+t);
+		
+	}
 
+});
 
 
+// Add two hex colours
+function addHexColour(c1, c2) 
+{
+  var hexStr = (parseInt(c1, 16) + parseInt(c2, 16)).toString(16);
+  while (hexStr.length < 6) { hexStr = '0' + hexStr; } // Zero pad.
+  return hexStr;
+}
+
+function colourString(c)
+{
+	return (c == "W") ? "white" : "black";
+}
 
-function replaceAt(s, n, t) {
-	//console.log(s.substring(0, n) + "\n" + t + "\n" + s.substring(n + 1) + "\n");
-	return (s.substring(0, n) + t + s.substring(n + 1));
+function otherColour(c)
+{
+	return (c == "W") ? "B" : "W";
 }