chess-legal-moves
Version:
Analyses a given chess game position in Fen notation to return legal moves and provides the next game position after a given move
119 lines (118 loc) • 5.07 kB
JavaScript
;
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getKnightAndColor = exports.knightsMoves = void 0;
var BitBoard_1 = require("../BitBoard/BitBoard");
var positionsHashTable_1 = require("./../BitBoard/positionsHashTable");
function knightsMoves(board, hasToPlay) {
// @TODO document
var opponent = hasToPlay === 'w' ? 'blacks' : 'whites';
var allKnightMovesTable = generateAllKnightMovesBBTable();
var knightsList = board[getKnightAndColor(hasToPlay)]
.extractBits()
.map(function (knightPositionCode) {
var from = positionsHashTable_1.positionsTable[knightPositionCode];
var quietMoves = allKnightMovesTable[knightPositionCode]
.and(board.quietDestinations)
.extractBits()
.map(function (knightDestination) { return positionsHashTable_1.positionsTable[knightDestination]; });
var killMoves = allKnightMovesTable[knightPositionCode]
.and(board[opponent])
.extractBits()
.map(function (knightDestination) { return positionsHashTable_1.positionsTable[knightDestination]; });
return {
from: from,
quietMoves: quietMoves,
killMoves: killMoves,
};
});
return knightsList;
}
exports.knightsMoves = knightsMoves;
function generateAllKnightMovesBBTable() {
// Knight moves from a given position
//
// noNoWe noNoEa
// +15 +17
// | |
// noWeWe +6 __| |__+10 noEaEa
// \ /
// >0<
// __ / \ __
// soWeWe -10 | | -6 soEaEa
// | |
// -17 -15
// soSoWe soSoEa
// A list of 64 bitboards representing the knight possible moves from any board position
var AFile = [0, 8, 16, 24, 32, 40, 48, 56];
var BFile = [1, 9, 17, 25, 33, 41, 49, 57];
var ABFile = __spreadArray(__spreadArray([], AFile, true), BFile, true);
var HFile = [7, 15, 23, 31, 39, 47, 55, 63];
var GFile = [6, 14, 22, 30, 38, 46, 54, 62];
var GHFile = __spreadArray(__spreadArray([], GFile, true), HFile, true);
function noNoEa(position) {
// if knight is on H file northNorthEast move would land on A file because of +17 -> return null in that particular case
return !AFile.includes(position + 17) ? position + 17 : null;
}
function noEaEa(position) {
// if knight is on G or H file northEastEast move would land on A or B file because of +10 -> return null in that particular case
return !ABFile.includes(position + 10) ? position + 10 : null;
}
function soEaEa(position) {
// if knight is on G or H file southEastEast move would land on A file because of -6 -> return null in that particular case
return !ABFile.includes(position - 6) ? position - 6 : null;
}
function soSoEa(position) {
return !AFile.includes(position - 15) ? position - 15 : null;
}
function noNoWe(position) {
return !HFile.includes(position + 15) ? position + 15 : null;
}
function noWeWe(position) {
return !GHFile.includes(position + 6) ? position + 6 : null;
}
function soWeWe(position) {
return !GHFile.includes(position - 10) ? position - 10 : null;
}
function soSoWe(position) {
return !HFile.includes(position - 17) ? position - 17 : null;
}
var allKnightMoves = [];
for (var position = 0; position < 64; position++) {
var movesFromThisPosition = [];
// if destination is not out of the board, add it to the list
if (noNoEa(position))
movesFromThisPosition.push(noNoEa(position));
if (noEaEa(position))
movesFromThisPosition.push(noEaEa(position));
if (soEaEa(position))
movesFromThisPosition.push(soEaEa(position));
if (soSoEa(position))
movesFromThisPosition.push(soSoEa(position));
if (noNoWe(position))
movesFromThisPosition.push(noNoWe(position));
if (noWeWe(position))
movesFromThisPosition.push(noWeWe(position));
if (soWeWe(position))
movesFromThisPosition.push(soWeWe(position));
if (soSoWe(position))
movesFromThisPosition.push(soSoWe(position));
allKnightMoves.push(BitBoard_1.default.fromPositions(movesFromThisPosition));
}
return allKnightMoves;
}
function getKnightAndColor(hasToPlay) {
if (hasToPlay === 'w')
return 'whiteKnights';
if (hasToPlay === 'b')
return 'blackKnights';
}
exports.getKnightAndColor = getKnightAndColor;