chess-easy
Version:
Chess engine that makes writing chessgame easier than writing a calculator
133 lines • 7.15 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MoveMaker = void 0;
const common_1 = require("../types/common");
const game_1 = require("../types/game");
const MoveIndexes_1 = require("./MoveIndexes");
const utils_1 = require("../utils");
class MoveMaker {
constructor(gameState, enPassantPossibility, movesNext, castlingAvailability) {
this.gameState = (0, utils_1.cloneGameState)(gameState);
this.enPassantPossibility = enPassantPossibility.slice();
this.movesNext = movesNext;
this.castlingAvailability = castlingAvailability.slice();
}
handleEnPassantCapture(moveIndexes) {
const movingPiece = this.gameState[moveIndexes.from.row][moveIndexes.from.column];
if ((movingPiece === null || movingPiece === void 0 ? void 0 : movingPiece.piece) === common_1.ChessPieces.PAWN &&
moveIndexes.to.field === this.enPassantPossibility) {
const colorMultiplier = this.movesNext === common_1.Colors.BLACK ? 1 : -1;
this.gameState[moveIndexes.to.row + 1 * colorMultiplier][moveIndexes.to.column] = null;
}
}
handleCastling(moveIndexes) {
const movingPiece = this.gameState[moveIndexes.from.row][moveIndexes.from.column];
const fieldToLand = this.gameState[moveIndexes.to.row][moveIndexes.to.column];
const castlingRowIndex = this.movesNext === common_1.Colors.WHITE ? 0 : 7;
let newKingIndex = null;
let newRookIndex = null;
let oldRookIndex = null;
if ((fieldToLand === null || fieldToLand === void 0 ? void 0 : fieldToLand.color) === (movingPiece === null || movingPiece === void 0 ? void 0 : movingPiece.color)) {
if (moveIndexes.from.column === 0 || moveIndexes.to.column === 0) {
newKingIndex = 2;
newRookIndex = 3;
oldRookIndex = 0;
}
if (moveIndexes.from.column === 7 || moveIndexes.to.column === 7) {
newKingIndex = 6;
newRookIndex = 5;
oldRookIndex = 7;
}
if (newKingIndex && newRookIndex && oldRookIndex !== null) {
this.gameState[castlingRowIndex][newKingIndex] =
this.gameState[castlingRowIndex][4];
this.gameState[castlingRowIndex][4] = null;
this.gameState[castlingRowIndex][newRookIndex] =
this.gameState[castlingRowIndex][oldRookIndex];
this.gameState[castlingRowIndex][oldRookIndex] = null;
}
(movingPiece === null || movingPiece === void 0 ? void 0 : movingPiece.color) && this.removeCastlingFromColor(movingPiece === null || movingPiece === void 0 ? void 0 : movingPiece.color);
return true;
}
else {
this.revalidateCastlingAvailability(moveIndexes);
return false;
}
}
static isPromotionMove(gameState, moveIndexes, movesNext) {
const movingPiece = gameState[moveIndexes.from.row][moveIndexes.from.column];
const promotionRow = movesNext === common_1.Colors.BLACK ? 0 : 7;
return ((movingPiece === null || movingPiece === void 0 ? void 0 : movingPiece.piece) === common_1.ChessPieces.PAWN &&
moveIndexes.to.row === promotionRow);
}
getNewPiece(moveIndexes, promotion) {
if (MoveMaker.isPromotionMove(this.gameState, moveIndexes, this.movesNext)) {
return utils_1.fenSymbolsToPiecesMapping[this.movesNext === common_1.Colors.BLACK
? promotion
: promotion.toLocaleUpperCase()];
}
return this.gameState[moveIndexes.from.row][moveIndexes.from.column];
}
removeCastlingFromColor(color) {
const castleRegexToRemove = color === common_1.Colors.BLACK ? /[^A-Z]/g : /[^a-z]/g;
this.castlingAvailability = this.castlingAvailability.replace(castleRegexToRemove, "");
}
revalidateCastlingAvailability(moveIndexes) {
const piece_moving = this.gameState[moveIndexes.from.row][moveIndexes.from.column];
if ((piece_moving === null || piece_moving === void 0 ? void 0 : piece_moving.piece) === common_1.ChessPieces.KING) {
this.removeCastlingFromColor(piece_moving.color);
}
this.removeCastilngIfRookStateChange(moveIndexes.from.column, moveIndexes.from.row);
this.removeCastilngIfRookStateChange(moveIndexes.to.column, moveIndexes.to.row);
}
removeCastilngIfRookStateChange(column_index, row_index) {
const piece = this.gameState[row_index][column_index];
if ([0, 7].includes(column_index) &&
[0, 7].includes(row_index) &&
(piece === null || piece === void 0 ? void 0 : piece.piece) === common_1.ChessPieces.ROOK) {
const castleSideToRemove = column_index === 0 ? "q" : "k";
const castleToRemove = piece.color === common_1.Colors.WHITE
? castleSideToRemove.toLocaleUpperCase()
: castleSideToRemove;
this.castlingAvailability = this.castlingAvailability.replace(castleToRemove, "");
}
}
handleEnPassantPossibility(moveIndexes) {
const movingPiece = this.gameState[moveIndexes.from.row][moveIndexes.from.column];
const rowDifference = Math.abs(moveIndexes.from.row - moveIndexes.to.row);
if ((movingPiece === null || movingPiece === void 0 ? void 0 : movingPiece.piece) === common_1.ChessPieces.PAWN && rowDifference === 2) {
const colorMultiplier = this.movesNext === common_1.Colors.BLACK ? 1 : -1;
const enPassantField = (0, utils_1.indexesToField)(moveIndexes.to.row + 1 * colorMultiplier, moveIndexes.to.column);
this.enPassantPossibility = enPassantField;
}
else {
this.enPassantPossibility = "-";
}
}
move(from, to, promotion = game_1.PromotionPossibility.QUEEN) {
const moveIndexes = new MoveIndexes_1.MoveIndexes(from, to);
const initialValues = {
enPassantPossibility: this.enPassantPossibility,
castlingAvailability: this.castlingAvailability,
gameState: (0, utils_1.cloneGameState)(this.gameState),
};
this.handleEnPassantCapture(moveIndexes);
this.handleEnPassantPossibility(moveIndexes);
if (!this.handleCastling(moveIndexes)) {
const newPiece = this.getNewPiece(moveIndexes, promotion);
this.gameState[moveIndexes.to.row][moveIndexes.to.column] = newPiece;
this.gameState[moveIndexes.from.row][moveIndexes.from.column] = null;
}
const newValues = {
gameState: this.gameState,
enPassantPossibility: this.enPassantPossibility,
castlingAvailability: this.castlingAvailability,
};
this.castlingAvailability = initialValues.castlingAvailability;
this.gameState = initialValues.gameState;
this.enPassantPossibility = initialValues.enPassantPossibility;
return newValues;
}
}
exports.MoveMaker = MoveMaker;
//# sourceMappingURL=MoveMaker.js.map