minesweeper-for-web
Version:
Minesweeper as a WebComponent.
240 lines • 10.6 kB
JavaScript
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