diff --git a/xtrn/chess/board.js b/xtrn/chess/board.js
index 84a2aa2d6868372eeefacbd31afb18db2c3e91cc..34fd4dac8b2e11ef290e012926a920c459d0e3cb 100644
--- a/xtrn/chess/board.js
+++ b/xtrn/chess/board.js
@@ -51,6 +51,8 @@ function Board(moves)
 	this.king = {}
 	this.king[COLOUR.white] = this.pieces[0][4];
 	this.king[COLOUR.black] = this.pieces[7][4];
+	this.draw_counter_turns;
+	this.position_count={};
 	this.moves=[];
 	if(moves) {
 		for(move in moves) {
@@ -59,12 +61,10 @@ function Board(moves)
 		}
 	}
 }
+Board.prototype.drawn=false;
 Board.prototype.handleMove=function(move)
 {
-	// TODO: Promotions
 	m=move.match(/^([a-h][1-8])([a-h][1-8])(.*)$/);
-	if(m==null)
-		return false;
 	if(m!=null) {
 		piece=this.getPiece(parsePos(m[1]));
 		if(piece.constructor.name=='Pawn') {
@@ -78,7 +78,7 @@ Board.prototype.handleMove=function(move)
 				case 'b':
 					piece.promote_to=Bishop;
 					break;
-				case 'k':
+				case 'n':
 					piece.promote_to=Knight;
 					break;
 			}
@@ -86,15 +86,89 @@ Board.prototype.handleMove=function(move)
 		if(!piece.moveTo(parsePos(m[2])))
 			return false;
 	}
+	if(move.search(/'D$/) != -1) {
+		if(this.draw_offer && this.draw_offer != this.turn())
+			this.drawn=true;
+		else if(m==null)
+			return false;
+		this.draw_offer = this.turn();
+	}
+	else
+		delete this.draw_offer;
 	this.moves.push(move);
 	return true;
 }
+Board.prototype.checkForMove=function(t)
+{
+	var x,y,p;
+	var x2,y2;
+
+	/*
+	 * This tests for stalemate and checkmate.  Checkmate is simply
+	 * a stalemate where the king is in check
+	 */
+	for(y=0;y<=8;y++) {
+		for(x=0;x<=8;x++) {
+			p=this.getPiece({x:x,y:y});
+			if(p==null)
+				continue;
+			if(p.colour != t)
+				continue;
+			for(y2=1;y2<=8;y2++) {
+				for(x2=1;x2<=8;x2++) {
+					if(p.moveTo({x:x2,y:y2},false))
+						return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+Board.prototype.newTurn=function()
+{
+	var t=this.turn();
+	var s;
+	
+	if(this.drawn)
+		return 'DRAW';
+
+	/* Check for check and check mate */
+	if(!this.checkForMove(t)) {
+		if(this.check(t))
+			return 'CHECKMATE';
+		return 'STALEMATE';
+	}
+
+	/* Check for threefold repitition */
+	s=this.stateString();
+	if(this.position_count[s]==undefined)
+		this.position_count[s]=1;
+	else
+		this.position_count[s]++;
+
+	/* Check for 50 turn limit */
+	this.draw_counter_turns++;
+	if(this.draw_counter_turns >= 100) {
+		if(this.draw_offer && this.draw_offer != t)
+			return 'DRAW';
+		else
+			this.draw_offer = t;
+	}
+	if(this.position_count[s]>=3) {
+		if(this.draw_offer && this.draw_offer != t)
+			return 'DRAW';
+		else
+			this.draw_offer = t;
+	}
+}
 Board.prototype.pieces=null;
 Board.prototype._domove=function(from, to)
 {
 	var piece=this.getPiece(from);
 	if(piece==null)
 		return false;
+	if(piece.constructor.name=='Pawn' || this.pieces[to.y-1][to.x-1])
+		this.draw_counter_turns=-1;
 	this.pieces[to.y-1][to.x-1]=piece;
 	this.pieces[piece.y-1][piece.x-1]=null;
 	piece.x=to.x;
@@ -123,6 +197,19 @@ Board.prototype.check=function(colour)
 Board.prototype.reason=function(str)
 {
 }
+Board.prototype.turn=function()
+{
+	if(this.moves.length % 2)
+		return COLOUR.black;
+	return COLOUR.white;
+}
+Board.prototype.lastTurn=function()
+{
+	if(this.moves.length % 2)
+		return COLOUR.white;
+	return COLOUR.black;
+}
+// TODO: There's a notation (FEN?) for this.
 Board.prototype.stateString= function()
 {
 	var ret='';
@@ -189,7 +276,7 @@ Board.prototype.stateString= function()
 						ret += 'r';
 						break;
 					case 'Knight':
-						ret += 'k';
+						ret += 'n';
 						break;
 				}
 			}
diff --git a/xtrn/chess/pieces.js b/xtrn/chess/pieces.js
index faf25fed99dd3915eca67703649bc88ede9363b4..095503123597ff4afffce71a551e1d99ad15b304 100644
--- a/xtrn/chess/pieces.js
+++ b/xtrn/chess/pieces.js
@@ -24,17 +24,9 @@ Piece.prototype={
 				return false;
 			}
 		}
-		if(this.board.moves.length % 2) {
-			if(this.colour == COLOUR.white) {
-				this.board.reason("White move on black's turn");
-				return false;
-			}
-		}
-		else {
-			if(this.colour == COLOUR.black) {
-				this.board.reason("Black move on white's turn");
-				return false;
-			}
+		if(this.colour != this.board.turn()) {
+			this.board.reason("Attempted move out of turn");
+			return false;
 		}
 		if(update) {
 			var brd=new Board(this.board.moves);
@@ -160,8 +152,10 @@ Pawn.prototype.moveTo=function(pos, update)
 	}
 
 	ret=Piece.prototype.moveTo.apply(this, [pos, update]);
-	if(update && ret && ydist==2)
-		this.double_move_num=this.board.moves.length;
+	if(update && ret) {
+		if(ydist==2)
+			this.double_move_num=this.board.moves.length;
+	}
 	if(ret && this.y == 4.5+(3.5*this.colour)) {
 		// Promotion!
 		if(this.promote_to == null)