103 lines
2.9 KiB
TypeScript
103 lines
2.9 KiB
TypeScript
const {LocalStorage} = (window as any).fwdekker.storage;
|
|
|
|
import {formatTime} from "./Common";
|
|
import {difficulties, Difficulty} from "./Difficulty";
|
|
|
|
|
|
/**
|
|
* A score obtained by clearing a field.
|
|
*/
|
|
export type Score = {time: number, deaths: number};
|
|
|
|
|
|
/**
|
|
* The highest scores.
|
|
*/
|
|
export class HighScores {
|
|
private static readonly scoresToStore: number = 10;
|
|
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);
|
|
scores.sort((a: Score, b: Score) => {
|
|
return Math.floor(a.time / 1000) !== Math.floor(b.time / 1000)
|
|
? a.time - b.time
|
|
: a.deaths - b.deaths;
|
|
});
|
|
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 += "" +
|
|
`<table>
|
|
<tr>
|
|
<th></th>
|
|
<th>Time</th>
|
|
<th>Deaths</th>
|
|
</tr>`;
|
|
for (let j = 0; j < highScores.length; j++) {
|
|
const score = highScores[j];
|
|
report += "" +
|
|
`<tr>
|
|
<th>#${j + 1}</th>
|
|
<td>${formatTime(Math.floor(score.time / 1000), true, false)}</td>
|
|
<td>${score.deaths}</td>
|
|
</tr>`;
|
|
}
|
|
report += "</table>";
|
|
}
|
|
return report;
|
|
}
|
|
}
|