UNPKG

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
"use strict"; 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;