@real_one_chess_king/game-logic
Version:
R.O.C.K. chess game logic
141 lines • 5.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Board = void 0;
const cell_1 = require("../cell");
const affect_1 = require("../affect/affect");
const piece_builder_1 = require("../piece/piece-builder");
const rules_engine_1 = require("../rules-engine");
/**
* Board keeps data about current game position and pieces on the array of cells
* It provides methods for manipulation by affects, but not dirrect access to pieces
* Always should be filled in by metadata
*/
class Board {
size = 8;
squares;
rulesEngine = new rules_engine_1.RulesEngine();
/**
* Metastorage is needed for saving initial data about pieces
* It can be used for transformation of pieces
*/
meta;
constructor() {
this.squares = this.buildCells();
}
buildCells() {
return Array.from({ length: this.size }, () => Array.from({ length: this.size }, () => new cell_1.Cell()));
}
isIndexValid = (index) => index >= 0 && index < this.size;
getMeta() {
if (!this.meta) {
throw new Error("Board meta is not defined yet");
}
return this.meta;
}
fillBoardByMeta(meta) {
this.meta = meta;
const { cellsMeta: cells, postMovementRules, movementRules } = meta;
this.rulesEngine.addMovementRules(movementRules);
this.rulesEngine.addPostMovementRules(postMovementRules);
for (let row = 0; row < this.size; row++) {
for (let col = 0; col < this.size; col++) {
const pieceMetaId = cells[row][col];
if (pieceMetaId) {
const cell = this.getCell(col, row);
const pieceMeta = meta.pieceMeta.find(({ id }) => id === pieceMetaId);
if (!pieceMeta) {
throw new Error("Piece meta not found");
}
cell.putPiece((0, piece_builder_1.buildPieceByMeta)(pieceMeta));
}
}
}
}
getPiece = (x, y) => {
return this.squares[y][x].getPiece();
};
getPieceByCoordinate = (xy) => {
return this.squares[xy[1]][xy[0]].getPiece();
};
getCell(x, y) {
return this.squares[y][x];
}
forEachPiece(color, callback) {
this.squares.forEach((row, y) => {
row.forEach((cell, x) => {
const piece = cell.getPiece();
if (piece && piece.color === color) {
callback(piece, x, y);
}
});
});
}
// now [x, y, affects]
// to action: affects[]. Affects with user choice marked with field and will be used for tree building
//
getPieceAvailableMoves(x, y, turns) {
const availableMoves = [];
const piece = this.getPiece(x, y);
if (!piece) {
throw new Error("Can not get moves for invalid piece coordinates");
}
const { movementRules, postMovementRules } = piece;
movementRules.forEach((ruleId) => {
const ruleMoves = this.rulesEngine.getAvailableMoves(ruleId, x, y, this.getPiece, turns, this.size);
availableMoves.push(...ruleMoves);
});
let updatedMoves = availableMoves;
postMovementRules?.forEach((ruleId) => {
updatedMoves = this.rulesEngine.addPostMovementCorrections(ruleId, updatedMoves, piece.type);
});
return updatedMoves;
}
/**
* We keep all killed and removed from the board pieces here.
* Transformations are not included.
*/
killed = [];
updateCellsOnMove(affects) {
if (!this.meta) {
throw new Error("Board meta is not defined yet");
}
affects.forEach((affect) => {
(0, affect_1.handleKillAffect)(affect, this.squares, this.killed);
(0, affect_1.handleMoveAffect)(affect, this.squares);
(0, affect_1.handleTransformAffect)(affect, this.squares, this.meta);
(0, affect_1.handleSpawnAffect)(affect, this.squares, this.killed);
});
}
revertMove(affects) {
const reversedAffects = (0, affect_1.reverseAffects)(affects);
this.updateCellsOnMove(reversedAffects);
}
duplicatePosition(cells) {
this.squares.forEach((row, y) => {
row.forEach((cell, x) => {
const piece = cell.getPiece();
if (piece) {
cells[y][x].putPiece(piece);
}
else {
cells[y][x].popPiece();
}
});
});
return cells;
}
findUniqPiece(color, pieceType) {
for (let i = 0; i < this.squares.length; i++) {
for (let j = 0; j < this.squares[i].length; j++) {
const cell = this.squares[i][j];
const piece = cell.getPiece();
if (piece && piece.color === color && piece.type === pieceType) {
return [j, i];
}
}
}
throw new Error(`${pieceType} not found`);
}
}
exports.Board = Board;
//# sourceMappingURL=board.js.map