UNPKG

minesweeper-for-web

Version:
240 lines 10.6 kB
var _MinesweeperBoard_positions, _MinesweeperBoard_flags, _MinesweeperBoard_flagCounter, _MinesweeperBoard_questionMarks, _MinesweeperBoard_revealedFields; import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; import { FieldKey } from '../types/index.js'; export class MinesweeperBoard { constructor(gameModeConfiguration) { _MinesweeperBoard_positions.set(this, void 0); _MinesweeperBoard_flags.set(this, void 0); _MinesweeperBoard_flagCounter.set(this, 0); _MinesweeperBoard_questionMarks.set(this, void 0); _MinesweeperBoard_revealedFields.set(this, void 0); this.gameModeConfiguration = gameModeConfiguration; // First: Generate 2d field __classPrivateFieldSet(this, _MinesweeperBoard_positions, this.generate2dFields(0), "f"); __classPrivateFieldSet(this, _MinesweeperBoard_flags, this.generate2dFields(false), "f"); __classPrivateFieldSet(this, _MinesweeperBoard_questionMarks, this.generate2dFields(false), "f"); __classPrivateFieldSet(this, _MinesweeperBoard_revealedFields, this.generate2dFields(false), "f"); // Second: Place the bombs on the field this.placeBombs(); // Third: Calculate the fields number, based on neighbor bombs this.applyFieldNumbers(); } get rows() { return this.gameModeConfiguration.rows; } get columns() { return this.gameModeConfiguration.columns; } get bombs() { return this.gameModeConfiguration.bombs; } get positions() { return __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f"); } get flags() { return __classPrivateFieldGet(this, _MinesweeperBoard_flags, "f"); } get flagCounter() { return __classPrivateFieldGet(this, _MinesweeperBoard_flagCounter, "f"); } get questionMarks() { return __classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f"); } get revealedFields() { return __classPrivateFieldGet(this, _MinesweeperBoard_revealedFields, "f"); } generate2dFields(value) { return Array.from({ length: this.rows }) .fill([value]) .map(() => Array.from({ length: this.columns }).fill(value)); } placeBombs() { const bombIndices = this.calculateRandomBombIndices(); let fieldIndex = 0; for (let row = 0; row < this.rows; row += 1) { for (let column = 0; column < this.columns; column += 1) { if (bombIndices.includes(fieldIndex)) { __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column] = FieldKey.BOMB; } fieldIndex += 1; } } } /** * Calculates a random set of indices where bombs are located on the field * @returns List of indices of bomb #positions */ calculateRandomBombIndices() { const result = []; const size = this.rows * this.columns; const desiredBombAmount = Math.min(this.bombs, size); while (result.length !== desiredBombAmount) { const newBombPosition = Math.floor(Math.random() * size); if (!result.includes(newBombPosition)) { result.push(newBombPosition); } } return result; } /** * Calculates for every field, except the fields with bombs, how many neighbor bombs are present. */ applyFieldNumbers() { for (let row = 0; row < this.rows; row += 1) { for (let column = 0; column < this.columns; column += 1) { if (__classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column] !== FieldKey.BOMB) { const bombCounter = this.getNeighbors(row, column).filter((neighbor) => __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[neighbor[0]][neighbor[1]] === FieldKey.BOMB).length; __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column] = bombCounter; } } } } revealField(row, column) { if (__classPrivateFieldGet(this, _MinesweeperBoard_flags, "f")[row][column]) { return FieldKey.FLAG; } if (__classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[row][column]) { __classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[row][column] = false; } const field = __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column]; if (field === FieldKey.BOMB) { // position contains bomb __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column] = FieldKey.BOMB_EXPLODE; } else if (field === 0) { // position contains no bomb and has no neighbor-bombs this.expand(row, column); } else { // position contains no bomb but neighbor-bombs __classPrivateFieldGet(this, _MinesweeperBoard_revealedFields, "f")[row][column] = true; } return field; } expand(row, column) { const field = __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column]; if (field === FieldKey.BOMB || __classPrivateFieldGet(this, _MinesweeperBoard_revealedFields, "f")[row][column]) { return; } __classPrivateFieldGet(this, _MinesweeperBoard_revealedFields, "f")[row][column] = true; if (__classPrivateFieldGet(this, _MinesweeperBoard_flags, "f")[row][column]) { this.removeFlag(row, column); } if (__classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[row][column]) { this.removeQuestionMark(row, column); } if (field === 0) { const neighbors = this.getNeighbors(row, column); for (const neighbor of neighbors) { this.expand(neighbor[0], neighbor[1]); } } } /** * @returns List of Neighbors, every entry contains a row and a column index */ getNeighbors(currentRow, currentColumn) { const neighbors = []; /** xoo * oxo * ooo */ if (currentRow > 0 && currentColumn > 0) { neighbors.push([currentRow - 1, currentColumn - 1]); } /** oxo * oxo * ooo */ if (currentRow > 0) { neighbors.push([currentRow - 1, currentColumn]); } /** oox * oxo * ooo */ if (currentRow > 0 && currentColumn < this.columns - 1) { neighbors.push([currentRow - 1, currentColumn + 1]); } /** ooo * oxx * ooo */ if (currentColumn < this.columns - 1) { neighbors.push([currentRow, currentColumn + 1]); } /** ooo * oxo * oox */ if (currentRow < this.rows - 1 && currentColumn < this.columns - 1) { neighbors.push([currentRow + 1, currentColumn + 1]); } /** ooo * oxo * oxo */ if (currentRow < this.rows - 1) { neighbors.push([currentRow + 1, currentColumn]); } /** ooo * oxo * xoo */ if (currentRow < this.rows - 1 && currentColumn > 0) { neighbors.push([currentRow + 1, currentColumn - 1]); } /** ooo * xxo * ooo */ if (currentColumn > 0) { neighbors.push([currentRow, currentColumn - 1]); } return neighbors; } addFlag(selectedRow, selectedColumn) { if (!__classPrivateFieldGet(this, _MinesweeperBoard_flags, "f")[selectedRow][selectedColumn]) { __classPrivateFieldGet(this, _MinesweeperBoard_flags, "f")[selectedRow][selectedColumn] = true; __classPrivateFieldSet(this, _MinesweeperBoard_flagCounter, __classPrivateFieldGet(this, _MinesweeperBoard_flagCounter, "f") + 1, "f"); this.removeQuestionMark(selectedRow, selectedColumn); } } removeFlag(selectedRow, selectedColumn) { if (__classPrivateFieldGet(this, _MinesweeperBoard_flags, "f")[selectedRow][selectedColumn]) { __classPrivateFieldGet(this, _MinesweeperBoard_flags, "f")[selectedRow][selectedColumn] = false; __classPrivateFieldSet(this, _MinesweeperBoard_flagCounter, __classPrivateFieldGet(this, _MinesweeperBoard_flagCounter, "f") - 1, "f"); } } addQuestionMark(selectedRow, selectedColumn) { if (!__classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[selectedRow][selectedColumn]) { __classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[selectedRow][selectedColumn] = true; this.removeFlag(selectedRow, selectedColumn); } } removeQuestionMark(selectedRow, selectedColumn) { if (__classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[selectedRow][selectedColumn]) { __classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[selectedRow][selectedColumn] = false; } } revealBombs(bombsAsFlags = false) { for (let row = 0; row < this.rows; row += 1) { for (let column = 0; column < this.columns; column += 1) { if (__classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column] === FieldKey.BOMB) { __classPrivateFieldGet(this, _MinesweeperBoard_revealedFields, "f")[row][column] = true; if (bombsAsFlags) { this.addFlag(row, column); } else if (__classPrivateFieldGet(this, _MinesweeperBoard_questionMarks, "f")[row][column]) { this.removeQuestionMark(row, column); } } if (__classPrivateFieldGet(this, _MinesweeperBoard_flags, "f")[row][column] || __classPrivateFieldGet(this, _MinesweeperBoard_positions, "f")[row][column] === FieldKey.BOMB_EXPLODE) { __classPrivateFieldGet(this, _MinesweeperBoard_revealedFields, "f")[row][column] = true; } } } } } _MinesweeperBoard_positions = new WeakMap(), _MinesweeperBoard_flags = new WeakMap(), _MinesweeperBoard_flagCounter = new WeakMap(), _MinesweeperBoard_questionMarks = new WeakMap(), _MinesweeperBoard_revealedFields = new WeakMap(); //# sourceMappingURL=MinesweeperBoard.js.map