Switch to different RNG

Fixes #56.
This commit is contained in:
Florine W. Dekker 2020-08-03 17:25:03 +02:00
parent ffaaf3bf15
commit cd86f60456
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
5 changed files with 21 additions and 15 deletions

BIN
package-lock.json generated

Binary file not shown.

View File

@ -1,6 +1,6 @@
{
"name": "minesweeper",
"version": "0.0.69",
"version": "0.0.70",
"description": "Just Minesweeper!",
"author": "Felix W. Dekker",
"browser": "dist/bundle.js",
@ -17,7 +17,7 @@
},
"dependencies": {
"@fwdekker/template": "^0.0.20",
"fast-random": "^2.0.4",
"alea": "^1.0.0",
"fork-awesome": "^1.1.7"
},
"devDependencies": {

View File

@ -1,5 +1,5 @@
// @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
*/
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--) {
const j = rng.nextInt() % (i + 1);
const j = rng.uint32() % (i + 1);
[array[i], array[j]] = [array[j], array[i]];
}

View File

@ -1,5 +1,5 @@
// @ts-ignore
import * as random from "fast-random";
import alea from "alea";
import {ActionHistory, FlagAction, SwapMineAction, UnAction, UncoverAction} from "./Action";
import {chunkifyArray, shuffleArrayInPlace} from "./Common";
import {Solver} from "./Solver";
@ -10,7 +10,7 @@ import {Timer} from "./Timer";
* A playing field for a game of Minesweeper.
*/
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 width: number;
@ -20,7 +20,7 @@ export class Field {
readonly squares: Square[][] = [];
readonly solvable: boolean;
private rng: any;
private readonly rng: any;
timer = new Timer();
coveredRemaining: number;
started: boolean = false;
@ -45,14 +45,14 @@ export class Field {
this.width = width;
this.height = height;
this.mineCount = mineCount;
this.rng = random(seed);
this.rng = alea("" + seed);
this.solvable = solvable;
this.squareList = Array(this.size).fill(0)
.map((_, i) => new Square(this, i % this.width, Math.floor(i / this.width), true));
this.squares = chunkifyArray(this.squareList, this.width);
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) {
let copy: Field;
do {
this.shuffle(this.rng.nextInt());
this.shuffle(this.rng.uint32());
copy = this.copy();
@ -191,10 +191,16 @@ export class Field {
return this.squares[y]?.[x] ?? orElse;
}
/**
* The number of flags the player has placed in this field.
*/
get flagCount(): number {
return this.squareList.filter(it => it.hasFlag).length;
}
/**
* The number of squares in this field.
*/
get size(): number {
return this.width * this.height;
}

View File

@ -1,7 +1,7 @@
// @ts-ignore
import {$} from "@fwdekker/template";
// @ts-ignore
import * as random from "fast-random";
import alea from "alea";
import {stringToHash} from "./Common";
import {customDifficulty, defaultDifficulty, difficulties} from "./Difficulty";
import {Display} from "./Display";
@ -49,8 +49,8 @@ export class Game {
this.display.startDrawLoop();
this.canvas.style.visibility = "unset";
this.rng = random(Date.now());
this.seed = "" + this.rng.nextInt();
this.rng = alea("" + Date.now());
this.seed = "" + this.rng.uint32();
this.leftDown = false;
this.rightDown = false;
this.holdsAfterChord = false;
@ -300,7 +300,7 @@ export class Game {
solvable: boolean = defaultDifficulty.solvable,
seed: string | null = null
) {
this.seed = seed ?? "" + this.rng.nextInt();
this.seed = seed ?? "" + this.rng.uint32();
this.field = new Field(
width, height, mineCount, solvable,
isNaN(+this.seed) ? stringToHash(this.seed) : +this.seed