Add more preferences for automatic hints
This commit is contained in:
parent
b60c7609cf
commit
85d71faa3f
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "minesweeper",
|
||||
"version": "0.84.0",
|
||||
"version": "0.85.0",
|
||||
"description": "Just Minesweeper!",
|
||||
"author": "Florine W. Dekker",
|
||||
"browser": "dist/bundle.js",
|
||||
|
|
|
@ -138,11 +138,12 @@
|
|||
<header>
|
||||
<hgroup>
|
||||
<h1>Preferences</h1>
|
||||
<h2>
|
||||
Configure the gameplay to your liking.
|
||||
</h2>
|
||||
<h2>Configure the gameplay to your liking.</h2>
|
||||
</hgroup>
|
||||
</header>
|
||||
<article>
|
||||
Options marked with * make the game considerably easier, and are not recommended except for learning.
|
||||
</article>
|
||||
<form id="preferences-form">
|
||||
<input role="switch" type="checkbox" id="preferences-enable-marks" autofocus />
|
||||
<label for="preferences-enable-marks">Right-clicking a square twice places a question mark.</label>
|
||||
|
@ -150,12 +151,21 @@
|
|||
|
||||
<input role="switch" type="checkbox" id="preferences-show-too-many-flags-hints" />
|
||||
<label for="preferences-show-too-many-flags-hints">
|
||||
Highlight squares with too many flags around them in red.
|
||||
Highlight squares in red if there are too many adjacent flags.
|
||||
</label>
|
||||
<br /><br />
|
||||
|
||||
<input role="switch" type="checkbox" id="preferences-show-chordable-hints" />
|
||||
<label for="preferences-show-chordable-hints">Highlight squares that can be chorded in blue.</label>
|
||||
<label for="preferences-show-chordable-hints">
|
||||
*Highlight squares in green if they can be
|
||||
<a href="https://www.minesweeper.info/wiki/Chord">chorded</a>.
|
||||
</label>
|
||||
<br /><br />
|
||||
|
||||
<input role="switch" type="checkbox" id="preferences-show-all-neighbors-are-mines-hints" />
|
||||
<label for="preferences-show-all-neighbors-are-mines-hints">
|
||||
*Highlight squares in green if all neighbors have mines.
|
||||
</label>
|
||||
</form>
|
||||
<footer>
|
||||
<a role="button" href="#" id="preferences-cancel" class="secondary">Cancel</a>
|
||||
|
|
|
@ -9,6 +9,10 @@ import {Preferences} from "./Preferences";
|
|||
* Displays a Minesweeper field.
|
||||
*/
|
||||
export class Display {
|
||||
private readonly errorColor: string = "rgba(255, 0, 0, 0.3)";
|
||||
private readonly hintColor: string = "rgba(0, 0, 255, 0.3)";
|
||||
private readonly safeColor: string = "rgba(0, 255, 0, 0.5)";
|
||||
|
||||
private readonly scale: number = 30;
|
||||
private readonly minSquareWidth: number = 6;
|
||||
|
||||
|
@ -301,19 +305,35 @@ export class Display {
|
|||
private drawHints(ctx: CanvasRenderingContext2D): void {
|
||||
if (this.field == null) return;
|
||||
|
||||
if (this.preferences.showTooManyFlagsHints) {
|
||||
let madeMistakes = false;
|
||||
let showsHint = false;
|
||||
|
||||
if (this.hintSquare != null) {
|
||||
ctx.save();
|
||||
ctx.fillStyle = "rgba(255, 0, 0, 0.3)";
|
||||
this.field.squareList
|
||||
ctx.fillStyle = this.hintColor;
|
||||
ctx.fillRect(this.hintSquare.x * this.scale, this.hintSquare.y * this.scale, this.scale, this.scale);
|
||||
ctx.restore();
|
||||
|
||||
showsHint = true;
|
||||
}
|
||||
|
||||
if (!showsHint && this.preferences.showTooManyFlagsHints) {
|
||||
ctx.save();
|
||||
ctx.fillStyle = this.errorColor;
|
||||
madeMistakes = madeMistakes || this.field.squareList
|
||||
.filter(it => !it.isCovered)
|
||||
.filter(it => it.getNeighborCount(it => it.hasMine) < it.getNeighborCount(it => it.hasFlag))
|
||||
.forEach(square => ctx.fillRect(square.x * this.scale, square.y * this.scale, this.scale, this.scale));
|
||||
.map(square => ctx.fillRect(square.x * this.scale, square.y * this.scale, this.scale, this.scale))
|
||||
.length > 0;
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
if (this.preferences.showChordableHints) {
|
||||
if (
|
||||
!showsHint && !madeMistakes &&
|
||||
(this.preferences.showChordableHints || this.preferences.showAllNeighborsAreMinesHints)
|
||||
) {
|
||||
ctx.save();
|
||||
ctx.fillStyle = "rgba(0, 0, 255, 0.3)";
|
||||
ctx.fillStyle = this.safeColor;
|
||||
this.field.squareList
|
||||
.filter(it => !it.isCovered)
|
||||
.filter(it => {
|
||||
|
@ -321,18 +341,14 @@ export class Display {
|
|||
const flags = it.getNeighborCount(it => it.hasFlag);
|
||||
const covered = it.getNeighborCount(it => it.isCovered);
|
||||
|
||||
return mines === flags && covered !== flags;
|
||||
return (
|
||||
(this.preferences.showChordableHints && mines === flags && covered !== flags) ||
|
||||
(this.preferences.showAllNeighborsAreMinesHints && mines === covered && mines !== flags)
|
||||
);
|
||||
})
|
||||
.forEach(square => ctx.fillRect(square.x * this.scale, square.y * this.scale, this.scale, this.scale));
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
if (this.hintSquare != null) {
|
||||
ctx.save();
|
||||
ctx.fillStyle = "rgba(0, 255, 0, 0.3)";
|
||||
ctx.fillRect(this.hintSquare.x * this.scale, this.hintSquare.y * this.scale, this.scale, this.scale);
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -181,24 +181,27 @@ export class Game {
|
|||
);
|
||||
|
||||
// Preferences
|
||||
const enableMarksInput = $("#preferences-enable-marks");
|
||||
const showTooManyFlagsHintsInput = $("#preferences-show-too-many-flags-hints");
|
||||
const enableMarks = $("#preferences-enable-marks");
|
||||
const showTooManyFlagsHints = $("#preferences-show-too-many-flags-hints");
|
||||
const showAllNeighborsAreMinesHints = $("#preferences-show-all-neighbors-are-mines-hints");
|
||||
const showChordableHints = $("#preferences-show-chordable-hints");
|
||||
const preferencesDialog = new ModalDialog({
|
||||
dialog: $("#preferences-dialog"),
|
||||
openButton: $("#preferences-open"),
|
||||
onOpen: () => {
|
||||
enableMarksInput.checked = preferences.marksEnabled;
|
||||
showTooManyFlagsHintsInput.checked = preferences.showTooManyFlagsHints;
|
||||
enableMarks.checked = preferences.marksEnabled;
|
||||
showTooManyFlagsHints.checked = preferences.showTooManyFlagsHints;
|
||||
showChordableHints.checked = preferences.showChordableHints;
|
||||
showAllNeighborsAreMinesHints.checked = preferences.showAllNeighborsAreMinesHints;
|
||||
},
|
||||
form: $("#preferences-form"),
|
||||
closeButton: $("#preferences-cancel"),
|
||||
submitButton: $("#preferences-submit"),
|
||||
onSubmit: () => {
|
||||
preferences.marksEnabled = enableMarksInput.checked;
|
||||
preferences.showTooManyFlagsHints = showTooManyFlagsHintsInput.checked;
|
||||
preferences.marksEnabled = enableMarks.checked;
|
||||
preferences.showTooManyFlagsHints = showTooManyFlagsHints.checked;
|
||||
preferences.showChordableHints = showChordableHints.checked;
|
||||
preferences.showAllNeighborsAreMinesHints = showAllNeighborsAreMinesHints.checked;
|
||||
|
||||
preferencesDialog.close();
|
||||
}
|
||||
|
|
|
@ -43,6 +43,14 @@ export class Preferences {
|
|||
this.storage.setBoolean("showChordableHints", value);
|
||||
}
|
||||
|
||||
get showAllNeighborsAreMinesHints(): boolean {
|
||||
return this.storage.getBoolean("showAllNeighborsAreMinesHints", false);
|
||||
}
|
||||
|
||||
set showAllNeighborsAreMinesHints(value: boolean) {
|
||||
this.storage.setBoolean("showAllNeighborsAreMinesHints", value);
|
||||
}
|
||||
|
||||
get showTooManyFlagsHints(): boolean {
|
||||
return this.storage.getBoolean("showTooManyFlagsHints", true);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue