parent
f94ee57811
commit
71d61a8916
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "minesweeper",
|
||||
"version": "0.81.4",
|
||||
"version": "0.81.5",
|
||||
"description": "Just Minesweeper!",
|
||||
"author": "Felix W. Dekker",
|
||||
"browser": "dist/bundle.js",
|
||||
|
|
|
@ -9,7 +9,7 @@ import alea from "alea";
|
|||
* @param seed the seed for the random number generator
|
||||
* @returns the array that was given to this function to shuffle
|
||||
*/
|
||||
export function shuffleArrayInPlace(array: any[], seed: number | undefined = undefined): any[] {
|
||||
export function shuffleArrayInPlace(array: any[], seed: number): any[] {
|
||||
const rng = alea("" + seed);
|
||||
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
|
@ -56,10 +56,10 @@ export function range(length: number, beginAt: number = 0): number[] {
|
|||
*
|
||||
* @param onSuccess the function to invoke once the font has loaded
|
||||
* @param onFailure the function to invoke if the font cannot be loaded
|
||||
* @param timeout the maximum time in milliseconds to wait for the font to load
|
||||
* @param timeout the maximum time in milliseconds to wait for the font to load, or `null` if there is no limit
|
||||
*/
|
||||
export function waitForForkAwesome(onSuccess: () => void, onFailure: () => void,
|
||||
timeout: number | undefined = undefined): void {
|
||||
timeout: number | null = null): void {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d")!;
|
||||
const fontSize = 36;
|
||||
|
@ -73,7 +73,7 @@ export function waitForForkAwesome(onSuccess: () => void, onFailure: () => void,
|
|||
ctx.textBaseline = "middle";
|
||||
|
||||
const startTime = performance.now();
|
||||
const failTime = timeout === undefined ? undefined : startTime + timeout;
|
||||
const failTime = timeout === null ? null : startTime + timeout;
|
||||
requestAnimationFrame(fontOnload);
|
||||
|
||||
/**
|
||||
|
@ -83,7 +83,7 @@ export function waitForForkAwesome(onSuccess: () => void, onFailure: () => void,
|
|||
*/
|
||||
function fontOnload(time: number): void {
|
||||
const currentCount = getPixelCount();
|
||||
if (failTime !== undefined && time > failTime) onFailure();
|
||||
if (failTime !== null && time > failTime) onFailure();
|
||||
else if (currentCount < targetPixelCount) requestAnimationFrame(fontOnload);
|
||||
else onSuccess();
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ export class Field {
|
|||
* @param orElse the value to return if there is no square at the given coordinates
|
||||
* @returns the square at the given coordinates, or `orElse` if there is no square there
|
||||
*/
|
||||
getSquareOrElse(coords: { x: number, y: number }, orElse: any = undefined): Square | any {
|
||||
getSquareOrElse(coords: { x: number, y: number }, orElse: any = null): Square | any {
|
||||
return this.squares[coords.y]?.[coords.x] ?? orElse;
|
||||
}
|
||||
|
||||
|
@ -514,7 +514,7 @@ export class Square {
|
|||
this.field.getSquareOrElse({x: this.x - 1, y: this.y + 1}),
|
||||
this.field.getSquareOrElse({x: this.x, y: this.y + 1}),
|
||||
this.field.getSquareOrElse({x: this.x + 1, y: this.y + 1}),
|
||||
].filter(it => it !== undefined);
|
||||
].filter(it => it !== null);
|
||||
}
|
||||
|
||||
return this._neighbors!;
|
||||
|
|
|
@ -17,7 +17,7 @@ import {Overlay} from "./UI";
|
|||
*/
|
||||
export class Game {
|
||||
private readonly statistics = new LocalStatistics();
|
||||
private statisticsTimer: number | undefined = undefined;
|
||||
private statisticsTimer: number | undefined;
|
||||
|
||||
private readonly canvas: HTMLCanvasElement;
|
||||
private readonly difficultySelect: HTMLSelectElement;
|
||||
|
@ -264,7 +264,7 @@ export class Game {
|
|||
);
|
||||
this.statisticsOverlay = new Overlay(
|
||||
$("#statisticsOverlay"),
|
||||
undefined,
|
||||
null,
|
||||
$("#statisticsCloseForm")
|
||||
);
|
||||
this.statisticsResetForm = $("#statisticsResetForm");
|
||||
|
@ -319,7 +319,7 @@ export class Game {
|
|||
case 2:
|
||||
if (!this.leftDown) {
|
||||
const square = this.field.getSquareOrElse(coords);
|
||||
if (square !== undefined) {
|
||||
if (square !== null) {
|
||||
if (square.hasFlag) {
|
||||
this.field.toggleFlag(coords);
|
||||
if (preferences.marksEnabled)
|
||||
|
|
|
@ -191,9 +191,10 @@ export class Solver {
|
|||
* @param knowns the uncovered squares that the solver should consider
|
||||
* @param adjacentSquaresOnly `true` if the solver should only look at the squares adjacent to `known` and not at
|
||||
* all squares in the field. Enabling this option increases complexity, but may uncover some edge cases
|
||||
* @returns the solution that has been found
|
||||
* @private
|
||||
*/
|
||||
private matrixSolve(field: Field, knowns: Square[], adjacentSquaresOnly: boolean): ([number, Square] | undefined)[] {
|
||||
private matrixSolve(field: Field, knowns: Square[], adjacentSquaresOnly: boolean): Solution {
|
||||
if (knowns.length === 0) return [];
|
||||
|
||||
let unknowns: Square[];
|
||||
|
@ -241,11 +242,10 @@ export class Solver {
|
|||
* Applies the given solution to the field.
|
||||
*
|
||||
* @param field the field to apply the solution to
|
||||
* @param solution an array in which each `undefined` element is ignored, and each pair contains a square and the
|
||||
* number `1` if the square contains a mine or the number `0` if the square does not contain a mine
|
||||
* @param solution the solution to apply
|
||||
* @private
|
||||
*/
|
||||
private applySolution(field: Field, solution: ([number, Square] | undefined)[]): void {
|
||||
private applySolution(field: Field, solution: Solution): void {
|
||||
solution.forEach(target => {
|
||||
if (target === undefined) return;
|
||||
|
||||
|
@ -450,3 +450,14 @@ export class Matrix {
|
|||
this.cells[rowA].map((it, i) => this.cells[rowA][i] + this.cells[rowB][i] * factor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A partial solution to a field.
|
||||
*
|
||||
* Each element of the array describes an instruction to apply to the field. If the instruction is `undefined`, then
|
||||
* nothing should be done. Otherwise, the tuple describes the instruction: If the number is 0, the associated square
|
||||
* should be uncovered because it definitely does not contain a mine. Otherwise, the number is 1 and the associated
|
||||
* square should be flagged because it definitely contains a mine.
|
||||
*/
|
||||
type Solution = ([number, Square] | undefined)[]
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
*/
|
||||
export class Overlay {
|
||||
private readonly overlay: HTMLDivElement;
|
||||
private readonly submitForm: HTMLFormElement | undefined;
|
||||
private readonly cancelForm: HTMLFormElement | undefined;
|
||||
private readonly submitForm: HTMLFormElement | null;
|
||||
private readonly cancelForm: HTMLFormElement | null;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -17,9 +17,9 @@ export class Overlay {
|
|||
*/
|
||||
constructor(
|
||||
overlay: HTMLDivElement,
|
||||
submitForm: HTMLFormElement | undefined,
|
||||
cancelForm: HTMLFormElement | undefined,
|
||||
onSubmit: (() => void) | undefined = undefined
|
||||
submitForm: HTMLFormElement | null,
|
||||
cancelForm: HTMLFormElement | null,
|
||||
onSubmit: (() => void) | null = null
|
||||
) {
|
||||
this.overlay = overlay;
|
||||
overlay.addEventListener(
|
||||
|
|
Loading…
Reference in New Issue