kokopu
Version:
A JavaScript/TypeScript library implementing the chess game rules and providing tools to read/write the standard chess file formats.
127 lines • 6.21 kB
JavaScript
;
/*!
* -------------------------------------------------------------------------- *
* *
* Kokopu - A JavaScript/TypeScript chess library. *
* <https://www.npmjs.com/package/kokopu> *
* Copyright (C) 2018-2025 Yoann Le Montagner <yo35 -at- melix.net> *
* *
* Kokopu is free software: you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License *
* as published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version. *
* *
* Kokopu is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General *
* Public License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* -------------------------------------------------------------------------- */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ATTACK_DIRECTIONS = void 0;
exports.isAttacked = isAttacked;
exports.getAttacks = getAttacks;
/**
* Attack directions per colored piece.
*/
exports.ATTACK_DIRECTIONS = [
[-17, -16, -15, -1, 1, 15, 16, 17], // king/queen
[-17, -16, -15, -1, 1, 15, 16, 17], // king/queen
[-17, -16, -15, -1, 1, 15, 16, 17], // king/queen
[-17, -16, -15, -1, 1, 15, 16, 17], // king/queen
[-16, -1, 1, 16], // rook
[-16, -1, 1, 16], // rook
[-17, -15, 15, 17], // bishop
[-17, -15, 15, 17], // bishop
[-33, -31, -18, -14, 14, 18, 31, 33], // knight
[-33, -31, -18, -14, 14, 18, 31, 33], // knight
[15, 17], // white pawn
[-17, -15], // black pawn
];
// -----------------------------------------------------------------------------
// isAttacked
// -----------------------------------------------------------------------------
/**
* Check if any piece of the given color attacks a given square.
*/
function isAttacked(position, square, attackerColor) {
return isAttackedByNonSliding(position, square, 0 /* PieceImpl.KING */ * 2 + attackerColor) ||
isAttackedByNonSliding(position, square, 4 /* PieceImpl.KNIGHT */ * 2 + attackerColor) ||
isAttackedByNonSliding(position, square, 5 /* PieceImpl.PAWN */ * 2 + attackerColor) ||
isAttackedBySliding(position, square, 2 /* PieceImpl.ROOK */ * 2 + attackerColor, 1 /* PieceImpl.QUEEN */ * 2 + attackerColor) ||
isAttackedBySliding(position, square, 3 /* PieceImpl.BISHOP */ * 2 + attackerColor, 1 /* PieceImpl.QUEEN */ * 2 + attackerColor);
}
function isAttackedByNonSliding(position, square, nonSlidingAttacker) {
for (const attackDirection of exports.ATTACK_DIRECTIONS[nonSlidingAttacker]) {
const sq = square - attackDirection;
if ((sq & 0x88) === 0 && position.board[sq] === nonSlidingAttacker) {
return true;
}
}
return false;
}
function isAttackedBySliding(position, square, slidingAttacker, queenAttacker) {
for (const attackDirection of exports.ATTACK_DIRECTIONS[slidingAttacker]) {
let sq = square;
while (true) {
sq -= attackDirection;
if ((sq & 0x88) === 0) {
const cp = position.board[sq];
if (cp === -1 /* SpI.EMPTY */) {
continue;
}
else if (cp === slidingAttacker || cp === queenAttacker) {
return true;
}
}
break;
}
}
return false;
}
// -----------------------------------------------------------------------------
// getAttacks
// -----------------------------------------------------------------------------
/**
* Return the squares from which a piece of the given color attacks a given square.
*/
function getAttacks(position, square, attackerColor) {
const result = [];
findNonSlidingAttacks(position, square, result, 0 /* PieceImpl.KING */ * 2 + attackerColor);
findNonSlidingAttacks(position, square, result, 4 /* PieceImpl.KNIGHT */ * 2 + attackerColor);
findNonSlidingAttacks(position, square, result, 5 /* PieceImpl.PAWN */ * 2 + attackerColor);
findSlidingAttacks(position, square, result, 2 /* PieceImpl.ROOK */ * 2 + attackerColor, 1 /* PieceImpl.QUEEN */ * 2 + attackerColor);
findSlidingAttacks(position, square, result, 3 /* PieceImpl.BISHOP */ * 2 + attackerColor, 1 /* PieceImpl.QUEEN */ * 2 + attackerColor);
return result;
}
function findNonSlidingAttacks(position, square, result, nonSlidingAttacker) {
for (const attackDirection of exports.ATTACK_DIRECTIONS[nonSlidingAttacker]) {
const sq = square - attackDirection;
if ((sq & 0x88) === 0 && position.board[sq] === nonSlidingAttacker) {
result.push(sq);
}
}
}
function findSlidingAttacks(position, square, result, slidingAttacker, queenAttacker) {
for (const attackDirection of exports.ATTACK_DIRECTIONS[slidingAttacker]) {
let sq = square;
while (true) {
sq -= attackDirection;
if ((sq & 0x88) === 0) {
const cp = position.board[sq];
if (cp === -1 /* SpI.EMPTY */) {
continue;
}
else if (cp === slidingAttacker || cp === queenAttacker) {
result.push(sq);
}
}
break;
}
}
}
//# sourceMappingURL=attacks.js.map