Simplify some calls
This commit is contained in:
parent
7dd4af8787
commit
08b707d017
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "minesweeper",
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.5",
|
||||
"description": "Just Minesweeper!",
|
||||
"author": "Felix W. Dekker",
|
||||
"browser": "dist/bundle.js",
|
||||
|
|
|
@ -2,7 +2,7 @@ import {$, doAfterLoad, footer, header, nav} from "@fwdekker/template";
|
|||
import {MersenneTwister19937, Random} from "random-js";
|
||||
|
||||
|
||||
const logArea = document.getElementById("logArea");
|
||||
const logArea = $("#logArea");
|
||||
const log = (message) => {
|
||||
logArea.value += `${message}\n`;
|
||||
logArea.scrollTop = logArea.scrollHeight;
|
||||
|
@ -17,12 +17,12 @@ class Game {
|
|||
* Constructs and starts a new game of Minesweeper.
|
||||
*/
|
||||
constructor() {
|
||||
this.canvas = document.getElementById("canvas");
|
||||
this.settingsForm = document.getElementById("settingsForm");
|
||||
this.widthInput = document.getElementById("settingsWidth");
|
||||
this.heightInput = document.getElementById("settingsHeight");
|
||||
this.minesInput = document.getElementById("settingsMines");
|
||||
this.seedInput = document.getElementById("settingsSeed");
|
||||
this.canvas = $("#canvas");
|
||||
this.settingsForm = $("#settingsForm");
|
||||
this.widthInput = $("#settingsWidth");
|
||||
this.heightInput = $("#settingsHeight");
|
||||
this.minesInput = $("#settingsMines");
|
||||
this.seedInput = $("#settingsSeed");
|
||||
|
||||
this.reset();
|
||||
this.display = new Display(this.canvas, this.field);
|
||||
|
@ -116,7 +116,7 @@ class Display {
|
|||
constructor(canvas, field) {
|
||||
// TODO Remove this \/
|
||||
this.frameNumber = 0;
|
||||
this.counter = document.getElementById("counter");
|
||||
this.counter = $("#counter");
|
||||
window.setInterval(() => {
|
||||
this.counter.innerText = "" + (this.frameNumber * 4);
|
||||
this.frameNumber = 0;
|
||||
|
@ -198,7 +198,7 @@ class Display {
|
|||
ctx.textBaseline = "middle";
|
||||
ctx.textAlign = "center";
|
||||
this.field.cellList.forEach(cell => {
|
||||
const neighborMineCount = cell.getNeighborMineCount();
|
||||
const neighborMineCount = cell.getNeighborCount(it => it.hasMine);
|
||||
let contents;
|
||||
if (cell.isCovered) {
|
||||
if (cell.hasFlag)
|
||||
|
@ -260,6 +260,7 @@ class Field {
|
|||
constructor(width, height, mineCount, seed = undefined) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.mineCount = mineCount;
|
||||
|
||||
const mines = Array(width * height).fill(true, 0, mineCount).fill(false, mineCount);
|
||||
shuffleArrayInPlace(mines, seed);
|
||||
|
@ -268,6 +269,18 @@ class Field {
|
|||
this.cells = chunkifyArray(this.cellList, this.width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a deep copy of this field.
|
||||
*
|
||||
* @return {Field} a deep copy of this field
|
||||
*/
|
||||
copy() {
|
||||
const copy = new Field(this.width, this.height, this.mineCount, undefined);
|
||||
copy.cellList = this.cellList.map(it => it.copy());
|
||||
copy.cellList.forEach(it => it.field = copy);
|
||||
copy.cells = chunkifyArray(copy.cellList, copy.width);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the cell at the given coordinates, or throws an error if there is no cell there.
|
||||
|
@ -296,16 +309,23 @@ class Field {
|
|||
return row === undefined ? orElse : row[y];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns `true` if and only if all mineless cells have been uncovered.
|
||||
*
|
||||
* @return `true` if and only if all mineless cells have been uncovered
|
||||
*/
|
||||
isCleared() {
|
||||
return this.cellList.reduce(
|
||||
(isCleared, cell) => isCleared && (!cell.isCovered || cell.hasMine),
|
||||
true
|
||||
);
|
||||
return this.cellList.find(it => !it.hasMine && it.isCovered) !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if and only if a mine has been uncovered.
|
||||
*
|
||||
* @returns {boolean} if and only if a mine has been uncovered
|
||||
*/
|
||||
isFailed() {
|
||||
return this.cellList.find(it => it.hasMine && !it.isCovered) !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,6 +351,18 @@ class Cell {
|
|||
this.hasFlag = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a deep copy of this cell, without a reference to any field.
|
||||
*
|
||||
* @returns {Cell} a deep copy of this cell, without a reference to any field
|
||||
*/
|
||||
copy() {
|
||||
const copy = new Cell(undefined, this.x, this.y, this.hasMine);
|
||||
copy.isCovered = this.isCovered;
|
||||
copy.hasFlag = this.hasFlag
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the `Cell`s that are adjacent to this cell.
|
||||
|
@ -351,21 +383,13 @@ class Cell {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the number of neighbors that have a flag.
|
||||
* Returns the number of neighbors that satisfy the given property.
|
||||
*
|
||||
* @returns {number} the number of neighbors that have a flag
|
||||
* @param property {function} the property to check on each neighbor
|
||||
* @returns {number} the number of neighbors that satisfy the given property
|
||||
*/
|
||||
getNeighborFlagCount() {
|
||||
return this.getNeighbors().filter(it => it.hasFlag).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of neighbors that have a mine.
|
||||
*
|
||||
* @returns {number} the number of neighbors that have a mine
|
||||
*/
|
||||
getNeighborMineCount() {
|
||||
return this.getNeighbors().filter(it => it.hasMine).length;
|
||||
getNeighborCount(property) {
|
||||
return this.getNeighbors().filter(property).length;
|
||||
}
|
||||
|
||||
|
||||
|
@ -375,7 +399,7 @@ class Cell {
|
|||
*/
|
||||
chord() {
|
||||
if (this.isCovered) return;
|
||||
if (this.getNeighborMineCount() !== this.getNeighborFlagCount()) return;
|
||||
if (this.getNeighborCount(it => it.hasFlag) !== this.getNeighborCount(it => it.hasMine)) return;
|
||||
|
||||
this.getNeighbors()
|
||||
.filter(it => it.isCovered && !it.hasFlag)
|
||||
|
@ -397,7 +421,7 @@ class Cell {
|
|||
}
|
||||
|
||||
this.getNeighbors()
|
||||
.filter(it => it.getNeighborMineCount() === 0 && !it.hasMine && !it.hasFlag)
|
||||
.filter(it => it.getNeighborCount(it => it.hasMine) === 0 && !it.hasMine && !it.hasFlag)
|
||||
.forEach(it => it.uncover());
|
||||
}
|
||||
|
||||
|
@ -418,7 +442,7 @@ class Cell {
|
|||
|
||||
this.isCovered = false;
|
||||
this.hasFlag = false;
|
||||
if (!this.hasMine && this.getNeighborMineCount() === 0)
|
||||
if (!this.hasMine && this.getNeighborCount(it => it.hasMine) === 0)
|
||||
this.chord();
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +501,7 @@ doAfterLoad(() => {
|
|||
|
||||
// Initialize game
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
document.getElementById("settingsSeed").value =
|
||||
$("#settingsSeed").value =
|
||||
urlParams.get("seed") === null
|
||||
? "" + Math.floor(Math.random() * 1000000000000)
|
||||
: urlParams.get("seed");
|
||||
|
|
Loading…
Reference in New Issue