Finalise high score implementation

Fixes #87.
This commit is contained in:
Florine W. Dekker 2020-09-02 20:32:28 +02:00
parent 53dd327786
commit e64d20f3bd
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
5 changed files with 47 additions and 11 deletions

View File

@ -62,6 +62,7 @@ form button.cancel {
.overlay {
padding: 6rem;
min-width: 33%;
max-height: 80%;
overflow: auto;

View File

@ -3,6 +3,7 @@
*/
export class Difficulty {
readonly name: string;
readonly description: string | null;
readonly width: number;
readonly height: number;
readonly mineCount: number;
@ -13,13 +14,16 @@ export class Difficulty {
* Constructs a new difficulty.
*
* @param name the name of the difficulty
* @param description the properties of the difficulty
* @param width the width of the field in this difficulty
* @param height the height of the field in this difficulty
* @param mineCount the number of mines in this difficulty
* @param solvable whether the field is guaranteed to be solvable in this difficulty
*/
constructor(name: string, width: number, height: number, mineCount: number, solvable: boolean) {
constructor(name: string, description: string | null, width: number, height: number, mineCount: number,
solvable: boolean) {
this.name = name;
this.description = description;
this.width = width;
this.height = height;
this.mineCount = mineCount;
@ -31,10 +35,10 @@ export class Difficulty {
* The default difficulty levels.
*/
export const difficulties: Difficulty[] = [
new Difficulty("Beginner (9x9, 10 mines)", 9, 9, 10, true),
new Difficulty("Intermediate (16x16, 40 mines)", 16, 16, 40, true),
new Difficulty("Expert (30x16, 99 mines)", 30, 16, 99, true),
new Difficulty("Custom", 0, 0, 0, false)
new Difficulty("Beginner", "9x9, 10 mines", 9, 9, 10, true),
new Difficulty("Intermediate", "16x16, 40 mines", 16, 16, 40, true),
new Difficulty("Expert", "30x16, 99 mines", 30, 16, 99, true),
new Difficulty("Custom", null, 0, 0, 0, false)
];
/**
@ -64,4 +68,4 @@ export const findDifficulty = function(width: number, height: number, mineCount:
}
return customDifficulty;
}
};

View File

@ -87,7 +87,7 @@ export class Game {
difficulties.forEach(it => {
const option = document.createElement("option");
option.value = it.name;
option.innerHTML = it.name;
option.innerHTML = `${it.name}${it.description !== null ? ` (${it.description})` : ""}`;
this.difficultySelect.add(option);
});
this.difficultySelect.addEventListener(

View File

@ -1,3 +1,4 @@
import {formatTime} from "./Common";
import {difficulties, Difficulty} from "./Difficulty";
import {LocalStorage, Storage} from "./Storage";
@ -16,15 +17,29 @@ export class HighScores {
private readonly storage: Storage;
/**
* Constructs a new container for high scores.
*
* @param storage the underlying object to store high scores in
*/
constructor(storage: Storage = new LocalStorage("/tools/minesweeper//high-scores")) {
this.storage = storage;
}
/**
* Clears all high scores.
*/
clear(): void {
this.storage.clear();
}
/**
* Adds a new high score.
*
* @param difficulty the difficulty to associate the score to
* @param score the score to store
*/
addScore(difficulty: Difficulty, score: Score): void {
const scores = this.storage.getArray(difficulty.name, []);
scores.push(score);
@ -32,19 +47,35 @@ export class HighScores {
this.storage.setArray(difficulty.name, scores.slice(0, HighScores.scoresToStore));
}
/**
* Returns all high scores associated with the given difficulty.
*
* @param difficulty the difficulty to return the high scores for
* @returns all high scores associated with the given difficulty
*/
getScores(difficulty: Difficulty): Score[] {
return this.storage.getArray(difficulty.name, []);
}
/**
* Generates an HTML report of all high scores.
*
* @returns an HTML report of all high scores
*/
generateHtmlReport(): string {
let report = "";
for (let i = 0; i < difficulties.length; i++) {
const difficulty = difficulties[i];
report += `<h3>${difficulty.name}</h3>`;
const highScores = this.getScores(difficulty);
if (highScores.length === 0) {
report += "<i>You have no high scores for this difficulty yet.</i><br /><br />";
continue;
}
report += "" +
`<h3>${difficulty.name}</h3>
<table>
`<table>
<tr>
<th>Time (seconds)</th>
<th>Deaths</th>
@ -53,7 +84,7 @@ export class HighScores {
const score = highScores[j];
report += "" +
`<tr>
<td>${score.time / 1000}</td>
<td>${formatTime(Math.floor(score.time / 1000), true, false)}</td>
<td>${score.deaths}</td>
</tr>`;
}

View File

@ -178,7 +178,7 @@ export class Statistics implements Statistics {
${this.lossesRedone > 0 ? `<tr><th>Losses redone</th><td>${this.lossesRedone}</td></tr>` : ``}
<tr>
<th>Time spent</th>
<td>${formatTime(Math.floor(+this.timeSpent / 1000), true, true)}</td>
<td>${formatTime(Math.floor(this.timeSpent / 1000), true, true)}</td>
</tr>
</table>