chlss
Version:
Open-Source Chess Engine in TypeScript.
104 lines (103 loc) • 4.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TerminationApi = exports.Terminations = void 0;
const colour_1 = require("./colour");
const piece_1 = require("./piece");
const boardPosition_1 = require("./boardPosition");
// TODO: Make it prettier...
exports.Terminations = {
// win / lose
Mate: 0,
Timeout: 1,
Resignation: 2,
// draws
Stalemate: 3,
InsufficientMaterial: 4,
FiftyMoveRule: 5,
Repetition: 6,
Agreement: 7
};
function isEmpty(arr) {
return arr.length == 0;
}
function attacksEnemyKing(moves, ourColour) {
const enemyKing = piece_1.Piece.getKing(ourColour);
for (let move of moves) {
if (move.targetPiece == enemyKing)
return true;
}
return false;
}
exports.TerminationApi = {
getTermination(board, legalMoves, enemyMoves) {
// TODO: To implement repetition I need a Move History.
// TODO: There's a few things I can't implement in here [Like Resign, Timeout, Agreement etc...]
if (isEmpty(legalMoves)) {
const attacksOurKing = attacksEnemyKing(enemyMoves, board.toMove);
if (this.isInMateWhenNoLegalMoves(board, attacksOurKing))
return exports.Terminations.Mate;
else if (this.isInStalemateWhenNoLegalMoves(board, attacksOurKing))
return exports.Terminations.Stalemate;
}
else {
if (this.isFiftyMoveRule(board))
return exports.Terminations.FiftyMoveRule;
else if (this.isInsufficientMaterial(board))
return exports.Terminations.InsufficientMaterial;
}
return null;
},
isInMateWhenNoLegalMoves(board, attacksOurKing) {
return attacksOurKing ? board.toMove : null;
},
isInStalemateWhenNoLegalMoves(board, attacksOurKing) {
return !attacksOurKing;
},
isFiftyMoveRule(board) {
return board.halfMoveNumber >= 50;
},
isInsufficientMaterial(board) {
function countKnights(knight, pieces) {
return pieces.filter(p => p == knight).length;
}
function isPiecesEnough(colour, pieces) {
return pieces.includes(piece_1.Piece.getPawn(colour)) ||
pieces.includes(piece_1.Piece.getRook(colour)) ||
pieces.includes(piece_1.Piece.getQueen(colour)) ||
countKnights(piece_1.Piece.getKnight(colour), pieces) >= 2;
}
function bishopsEnough(pieces) {
// {Piece-Colour}{Bishop-Square-Colour}
let whiteWhite = 0;
let whiteBlack = 0;
let blackBlack = 0;
let blackWhite = 0;
for (let i = 0; i < 64; i++) {
const piece = pieces[i];
if (!piece_1.Piece.isBishop(piece))
continue;
const pieceColour = (piece_1.Piece.getColour(piece));
const sqColour = piece_1.Piece.getBishopSquareColour(i);
if (pieceColour == colour_1.Colours.white) {
if (sqColour == colour_1.Colours.white)
whiteWhite++;
else
whiteBlack++;
}
else {
if (sqColour == colour_1.Colours.white)
blackWhite++;
else
blackBlack++;
}
}
return ((whiteWhite > 0) ? 1 : 0) + ((whiteBlack > 0) ? 1 : 0) >= 2 || ((blackBlack > 0) ? 1 : 0) + ((blackWhite > 0) ? 1 : 0) >= 2;
}
const whiteEnough = isPiecesEnough(colour_1.Colours.white, boardPosition_1.BoardPosition.getAllPiecesByColour(board.position, colour_1.Colours.white));
const blackEnough = isPiecesEnough(colour_1.Colours.black, boardPosition_1.BoardPosition.getAllPiecesByColour(board.position, colour_1.Colours.black));
if (whiteEnough || blackEnough) {
return false;
}
return !bishopsEnough(board.position);
}
};