UNPKG

@real_one_chess_king/game-logic

Version:
141 lines 5.18 kB
"use strict"; 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