Simplify some calls

This commit is contained in:
Florine W. Dekker 2020-07-25 22:00:33 +02:00
parent 7dd4af8787
commit 08b707d017
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
2 changed files with 55 additions and 31 deletions

View File

@ -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",

View File

@ -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");