parent
ffaaf3bf15
commit
cd86f60456
Binary file not shown.
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "minesweeper",
|
"name": "minesweeper",
|
||||||
"version": "0.0.69",
|
"version": "0.0.70",
|
||||||
"description": "Just Minesweeper!",
|
"description": "Just Minesweeper!",
|
||||||
"author": "Felix W. Dekker",
|
"author": "Felix W. Dekker",
|
||||||
"browser": "dist/bundle.js",
|
"browser": "dist/bundle.js",
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fwdekker/template": "^0.0.20",
|
"@fwdekker/template": "^0.0.20",
|
||||||
"fast-random": "^2.0.4",
|
"alea": "^1.0.0",
|
||||||
"fork-awesome": "^1.1.7"
|
"fork-awesome": "^1.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as random from "fast-random";
|
import alea from "alea";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,10 +10,10 @@ import * as random from "fast-random";
|
||||||
* @returns the array that was given to this function to shuffle
|
* @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 | undefined = undefined): any[] {
|
||||||
const rng = random(seed);
|
const rng = alea("" + seed);
|
||||||
|
|
||||||
for (let i = array.length - 1; i > 0; i--) {
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
const j = rng.nextInt() % (i + 1);
|
const j = rng.uint32() % (i + 1);
|
||||||
[array[i], array[j]] = [array[j], array[i]];
|
[array[i], array[j]] = [array[j], array[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as random from "fast-random";
|
import alea from "alea";
|
||||||
import {ActionHistory, FlagAction, SwapMineAction, UnAction, UncoverAction} from "./Action";
|
import {ActionHistory, FlagAction, SwapMineAction, UnAction, UncoverAction} from "./Action";
|
||||||
import {chunkifyArray, shuffleArrayInPlace} from "./Common";
|
import {chunkifyArray, shuffleArrayInPlace} from "./Common";
|
||||||
import {Solver} from "./Solver";
|
import {Solver} from "./Solver";
|
||||||
|
@ -10,7 +10,7 @@ import {Timer} from "./Timer";
|
||||||
* A playing field for a game of Minesweeper.
|
* A playing field for a game of Minesweeper.
|
||||||
*/
|
*/
|
||||||
export class Field {
|
export class Field {
|
||||||
// Do not call `undo` directly on the history
|
// Do not call `undo` directly on the history, thanks
|
||||||
readonly history = new ActionHistory();
|
readonly history = new ActionHistory();
|
||||||
|
|
||||||
readonly width: number;
|
readonly width: number;
|
||||||
|
@ -20,7 +20,7 @@ export class Field {
|
||||||
readonly squares: Square[][] = [];
|
readonly squares: Square[][] = [];
|
||||||
readonly solvable: boolean;
|
readonly solvable: boolean;
|
||||||
|
|
||||||
private rng: any;
|
private readonly rng: any;
|
||||||
timer = new Timer();
|
timer = new Timer();
|
||||||
coveredRemaining: number;
|
coveredRemaining: number;
|
||||||
started: boolean = false;
|
started: boolean = false;
|
||||||
|
@ -45,14 +45,14 @@ export class Field {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.mineCount = mineCount;
|
this.mineCount = mineCount;
|
||||||
this.rng = random(seed);
|
this.rng = alea("" + seed);
|
||||||
this.solvable = solvable;
|
this.solvable = solvable;
|
||||||
|
|
||||||
this.squareList = Array(this.size).fill(0)
|
this.squareList = Array(this.size).fill(0)
|
||||||
.map((_, i) => new Square(this, i % this.width, Math.floor(i / this.width), true));
|
.map((_, i) => new Square(this, i % this.width, Math.floor(i / this.width), true));
|
||||||
this.squares = chunkifyArray(this.squareList, this.width);
|
this.squares = chunkifyArray(this.squareList, this.width);
|
||||||
this.coveredRemaining = this.size - this.mineCount;
|
this.coveredRemaining = this.size - this.mineCount;
|
||||||
this.shuffle(this.rng.nextInt());
|
this.shuffle(this.rng.uint32());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,7 +135,7 @@ export class Field {
|
||||||
if (this.solvable) {
|
if (this.solvable) {
|
||||||
let copy: Field;
|
let copy: Field;
|
||||||
do {
|
do {
|
||||||
this.shuffle(this.rng.nextInt());
|
this.shuffle(this.rng.uint32());
|
||||||
|
|
||||||
copy = this.copy();
|
copy = this.copy();
|
||||||
|
|
||||||
|
@ -191,10 +191,16 @@ export class Field {
|
||||||
return this.squares[y]?.[x] ?? orElse;
|
return this.squares[y]?.[x] ?? orElse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of flags the player has placed in this field.
|
||||||
|
*/
|
||||||
get flagCount(): number {
|
get flagCount(): number {
|
||||||
return this.squareList.filter(it => it.hasFlag).length;
|
return this.squareList.filter(it => it.hasFlag).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of squares in this field.
|
||||||
|
*/
|
||||||
get size(): number {
|
get size(): number {
|
||||||
return this.width * this.height;
|
return this.width * this.height;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import {$} from "@fwdekker/template";
|
import {$} from "@fwdekker/template";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as random from "fast-random";
|
import alea from "alea";
|
||||||
import {stringToHash} from "./Common";
|
import {stringToHash} from "./Common";
|
||||||
import {customDifficulty, defaultDifficulty, difficulties} from "./Difficulty";
|
import {customDifficulty, defaultDifficulty, difficulties} from "./Difficulty";
|
||||||
import {Display} from "./Display";
|
import {Display} from "./Display";
|
||||||
|
@ -49,8 +49,8 @@ export class Game {
|
||||||
this.display.startDrawLoop();
|
this.display.startDrawLoop();
|
||||||
this.canvas.style.visibility = "unset";
|
this.canvas.style.visibility = "unset";
|
||||||
|
|
||||||
this.rng = random(Date.now());
|
this.rng = alea("" + Date.now());
|
||||||
this.seed = "" + this.rng.nextInt();
|
this.seed = "" + this.rng.uint32();
|
||||||
this.leftDown = false;
|
this.leftDown = false;
|
||||||
this.rightDown = false;
|
this.rightDown = false;
|
||||||
this.holdsAfterChord = false;
|
this.holdsAfterChord = false;
|
||||||
|
@ -300,7 +300,7 @@ export class Game {
|
||||||
solvable: boolean = defaultDifficulty.solvable,
|
solvable: boolean = defaultDifficulty.solvable,
|
||||||
seed: string | null = null
|
seed: string | null = null
|
||||||
) {
|
) {
|
||||||
this.seed = seed ?? "" + this.rng.nextInt();
|
this.seed = seed ?? "" + this.rng.uint32();
|
||||||
this.field = new Field(
|
this.field = new Field(
|
||||||
width, height, mineCount, solvable,
|
width, height, mineCount, solvable,
|
||||||
isNaN(+this.seed) ? stringToHash(this.seed) : +this.seed
|
isNaN(+this.seed) ? stringToHash(this.seed) : +this.seed
|
||||||
|
|
Loading…
Reference in New Issue