152 lines
3.4 KiB
JavaScript
152 lines
3.4 KiB
JavaScript
export class ScoreEntry {
|
|
constructor(score, total, foul, wasOverflow, wasWin) {
|
|
this.score = score;
|
|
this.total = total;
|
|
this.fouls = foul;
|
|
this.wasOverflow = wasOverflow;
|
|
this.wasWin = wasWin;
|
|
}
|
|
};
|
|
|
|
export class Scorecard {
|
|
|
|
constructor(rules) {
|
|
this.rules = rules;
|
|
this.reset();
|
|
}
|
|
|
|
reset() {
|
|
this._player1Scores = [];
|
|
this._player2Scores = [];
|
|
}
|
|
|
|
addPlayer1Score(newScore) {
|
|
this._addScore(this._player1Scores, newScore);
|
|
}
|
|
|
|
removeLastPlayer1Score() {
|
|
this._player1Scores.pop();
|
|
}
|
|
|
|
addPlayer2Score(newScore) {
|
|
this._addScore(this._player2Scores, newScore);
|
|
}
|
|
|
|
removeLastPlayer2Score() {
|
|
this._player2Scores.pop();
|
|
}
|
|
|
|
_addScore(playerScores, newScore) {
|
|
let lastEntry;
|
|
if (playerScores.length === 0) {
|
|
lastEntry = new ScoreEntry(0, 0, 0, false, false);
|
|
} else {
|
|
lastEntry = playerScores[playerScores.length - 1];
|
|
}
|
|
|
|
let newEntry = this._newEntryFromPrevious(newScore, lastEntry);
|
|
|
|
playerScores.push(newEntry);
|
|
}
|
|
|
|
length() {
|
|
return Math.max(this._player1Scores.length, this._player2Scores.length);
|
|
}
|
|
|
|
pairs() {
|
|
let pairs = [];
|
|
|
|
for (let i = 0; i < this.length(); i++) {
|
|
pairs.push({
|
|
p1: (i < this._player1Scores.length ? this._player1Scores[i] : null),
|
|
p2: (i < this._player2Scores.length ? this._player2Scores[i] : null),
|
|
})
|
|
}
|
|
|
|
return pairs;
|
|
}
|
|
|
|
_newEntryFromPrevious(score, previousScoreEntry) {
|
|
if (previousScoreEntry === null) {
|
|
return new ScoreEntry(score, score, (score === 0 ? 1 : 0));
|
|
}
|
|
|
|
let wasOverflow = false, wasWin = false;
|
|
let newTotal = previousScoreEntry.total + score;
|
|
|
|
if (newTotal === this.rules.maxScore) {
|
|
wasWin = true;
|
|
} else if (newTotal > this.rules.maxScore) {
|
|
newTotal = this.rules.overflowScoreTo;
|
|
wasOverflow = true;
|
|
}
|
|
|
|
let newFouls = previousScoreEntry.foul;
|
|
if (score === 0) {
|
|
newFouls++;
|
|
}
|
|
|
|
return new ScoreEntry(score, newTotal, newFouls, wasOverflow, wasWin);
|
|
}
|
|
|
|
toJson() {
|
|
return {
|
|
"version": 1,
|
|
"rules": this.rules,
|
|
"p1": { "scores": this._player1Scores.map(p => p.score) },
|
|
"p2": { "scores": this._player2Scores.map(p => p.score) },
|
|
};
|
|
}
|
|
|
|
static fromJson(o) {
|
|
let scorecard = new Scorecard(o.rules);
|
|
o["p1"]["scores"].forEach(x => scorecard.addPlayer1Score(x));
|
|
o["p2"]["scores"].forEach(x => scorecard.addPlayer2Score(x));
|
|
return scorecard;
|
|
}
|
|
}
|
|
|
|
class StoreDAO {
|
|
|
|
constructor(localStorage) {
|
|
this._localStorage = localStorage;
|
|
}
|
|
|
|
save(scoreCard) {
|
|
this._localStorage.setItem('score_card', JSON.stringify(scoreCard.toJson()));
|
|
}
|
|
|
|
loadOrCreate(rules) {
|
|
try {
|
|
console.log("Loading scorecard");
|
|
let scoreCardJson = this._localStorage.getItem('score_card');
|
|
if (scoreCardJson !== null) {
|
|
return Scorecard.fromJson(JSON.parse(scoreCardJson));
|
|
}
|
|
} catch (e) {
|
|
console.log(`Could not restore game: ${e}`);
|
|
}
|
|
|
|
return new Scorecard(rules);
|
|
}
|
|
|
|
clear() {
|
|
this._localStorage.clear();
|
|
}
|
|
}
|
|
|
|
class DummyStoreDAO {
|
|
save(scoreCard) { }
|
|
loadOrCreate(rules) {
|
|
return new Scorecard(rules);
|
|
}
|
|
clear() { }
|
|
}
|
|
|
|
export function getStoreDAO() {
|
|
if (!!window.localStorage) {
|
|
return new StoreDAO(window.localStorage);
|
|
} else {
|
|
return new DummyStoreDAO();
|
|
}
|
|
} |