Implement castling
This commit is contained in:
parent
f8f0c794cd
commit
54e4621548
123
takhta.html
123
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');
|
||||
|
|
Loading…
Reference in New Issue