diff --git a/takhta.html b/takhta.html
index d08b720..2e494ec 100644
--- a/takhta.html
+++ b/takhta.html
@@ -306,6 +306,10 @@
case 'h':
piece = 'P';
break;
+ case 'O':
+ case '0':
+ // Castling, handled in its own function
+ return doCastle(move);
default:
return {error: 'Not a valid piece: ' + piece};
}
@@ -435,6 +439,125 @@
return {}
}
+ function doCastle(move) {
+ let ballChar = move[0];
+
+ // Figure out distance between king and rook
+ let emptySquares = 1;
+ let index = 1;
+ while (index < move.length) {
+ if (move.slice(index, index + 2) === '-' + ballChar) {
+ emptySquares += 1;
+ index += 2;
+ } else {
+ break;
+ }
+ }
+
+ // Check(mate)
+ if (!['', '+', '++', '#'].includes(move.slice(index))) {
+ // TODO: Implement handling
+ return {error: 'Unexpected contents at the end of the move: ' + move.slice(index)};
+ }
+
+ // Find the king(s)
+ let whiteMove = document.getElementById('tomove').childNodes[0].data === 'White';
+ let renderedKing = whiteMove ? '♔' : '♚';
+ let renderedRook = whiteMove ? '♖' : '♜';
+
+ let kings = [];
+ for (let kingLetter of 'abcdefgh') {
+ for (let kingNumber of '12345678') {
+ let square = document.getElementById(kingLetter + kingNumber);
+ if (square.childNodes.length !== 0 && square.childNodes[0].data === renderedKing) {
+ kings.push([kingLetter, kingNumber]);
+ }
+ }
+ }
+
+ // Find the rook(s)
+ function squareDiff(squareLetter, squareNumber, dLetter, dNumber) {
+ let x = 'abcdefgh'.indexOf(squareLetter) + dLetter;
+ let y = '12345678'.indexOf(squareNumber) + dNumber;
+ if (x < 0 || x > 7 || y < 0 || y > 7) {
+ // Would be outside of the board
+ return null;
+ }
+ return ['abcdefgh'[x], '12345678'[y]]
+ }
+
+ let distance = emptySquares + 1;
+ let possiblePairs = [];
+ for (let [kingLetter, kingNumber] of kings) {
+ for (let [dLetter, dNumber] of [[-distance, 0], [distance, 0], [0, -distance], [0, distance]]) {
+ let rookCoords = squareDiff(kingLetter, kingNumber, dLetter, dNumber);
+ if (rookCoords === null) {
+ continue;
+ }
+ let [rookLetter, rookNumber] = rookCoords;
+
+ let square = document.getElementById(rookLetter + rookNumber);
+ if (square.childNodes.length !== 0 && square.childNodes[0].data === renderedRook) {
+ possiblePairs.push([kingLetter, kingNumber, rookLetter, rookNumber, dLetter, dNumber]);
+ }
+ }
+ }
+
+ if (possiblePairs.length === 0) {
+ return {error: 'Could not find king and rook matching castling criteria'};
+ } else if (possiblePairs.length > 1) {
+ return {error: 'Found ' + String(possiblePairs.length) + ' possible pairs of king and rook to castle'};
+ }
+
+ let [kingLetter, kingNumber, rookLetter, rookNumber, dLetter, dNumber] = possiblePairs[0];
+ let kingStartSquare = document.getElementById(kingLetter + kingNumber);
+ let rookStartSquare = document.getElementById(rookLetter + rookNumber);
+
+ // Make sure there there are no pieces between the king and the rook
+ let signLetter = Math.sign(dLetter);
+ let signNumber = Math.sign(dNumber);
+ let [squareLetter, squareNumber] = squareDiff(kingLetter, kingNumber, signLetter, signNumber);
+ while (squareLetter !== rookLetter || squareNumber !== rookNumber) {
+ if (document.getElementById(squareLetter + squareNumber).childNodes.length !== 0) {
+ return {error: squareLetter + squareNumber + ' is occupied'};
+ }
+ [squareLetter, squareNumber] = squareDiff(squareLetter, squareNumber, signLetter, signNumber);
+ }
+
+ // King moves two squares towards rook
+ let [kingEndLetter, kingEndNumber] = squareDiff(kingLetter, kingNumber, 2 * signLetter, 2 * signNumber);
+ let kingEndSquare = document.getElementById(kingEndLetter + kingEndNumber);
+
+ // Rook moves to the square king crossed
+ let [rookEndLetter, rookEndNumber] = squareDiff(kingLetter, kingNumber, signLetter, signNumber);
+ let rookEndSquare = document.getElementById(rookEndLetter + rookEndNumber);
+
+ // Move pieces
+ kingStartSquare.removeChild(kingStartSquare.childNodes[0]);
+ rookStartSquare.removeChild(rookStartSquare.childNodes[0]);
+ kingEndSquare.appendChild(document.createTextNode(renderedKing));
+ rookEndSquare.appendChild(document.createTextNode(renderedRook));
+
+ // Flip whose turn it is
+ document.getElementById('tomove').childNodes[0].data = whiteMove ? 'Black' : 'White';
+
+ // Record our alterations to the table
+ let removedPieces = {};
+ let placedPieces = {};
+ removedPieces[kingLetter + kingNumber] = renderedKing;
+ removedPieces[rookLetter + rookNumber] = renderedRook;
+ placedPieces[kingEndLetter + kingEndNumber] = renderedKing;
+ placedPieces[rookEndLetter + rookEndNumber] = renderedRook;
+ let moveRecord = {
+ removedPieces: removedPieces,
+ placedPieces: placedPieces,
+ moveText: move
+ };
+ moveHistory.push(moveRecord);
+
+ return {}
+ }
+
function undoMove() {
if (moveHistory.length === 0) {
alert('No moves to undo');