diff --git a/site/index.html b/site/index.html
index d36f391..683ba05 100644
--- a/site/index.html
+++ b/site/index.html
@@ -24,8 +24,7 @@
Gradient Bands
Two-letter Country Codes
Timestamp Converter
- Generic Scorecard - 2 Players
- Generic Scorecard - 4 Players
+ Generic Scorecard
Mahjong Scorecard
Finska Scorecard
diff --git a/site/scorecard-2p/main.js b/site/scorecard-2p/main.js
deleted file mode 100644
index e69de29..0000000
diff --git a/site/scorecard-4p/index.html b/site/scorecard-4p/index.html
deleted file mode 100644
index d495e38..0000000
--- a/site/scorecard-4p/index.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
- Score Card - Tools
-
-
-
-
-
-
-
- Scorecard
- 4 Players
-
-
-
-
-
-
-
-
- | Player A |
- Player B |
- Player C |
- Player D |
-
-
-
-
-
-
- |
-
- |
- |
-
-
- |
- |
-
-
- |
- |
-
-
- |
- |
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/site/scorecard-4p/scripts/controllers.js b/site/scorecard-4p/scripts/controllers.js
deleted file mode 100644
index 5159f4f..0000000
--- a/site/scorecard-4p/scripts/controllers.js
+++ /dev/null
@@ -1,158 +0,0 @@
-import { Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js";
-import { Scorecard, getStoreDAO } from "./models.js";
-
-const storeDao = getStoreDAO();
-
-export class FinskaScorecardController extends Controller {
- static targets = ["score1Input", "score2Input", "score3Input", "score4Input", "scoreTable"];
-
- connect() {
- this._undoStack = [];
- this._scorecard = storeDao.loadOrCreate();
- this.updateTable();
- }
-
- updateTable() {
- let tableBody = this.scoreTableTarget;
- let tableRows = tableBody.querySelectorAll("tr");
- let pairs = this._scorecard.pairs();
-
- for (let pairIndex = 0; pairIndex < pairs.length; pairIndex++) {
- let tableRow;
- if (pairIndex >= tableRows.length) {
- tableRow = this._appendRow();
- } else {
- tableRow = tableRows[pairIndex];
- }
-
- this._updateRow(tableRow, pairs[pairIndex])
- }
-
- // Remove any extra rows
- for (let i = pairs.length; i < tableRows.length; i++) {
- tableBody.removeChild(tableRows[i]);
- }
-
- console.log(JSON.stringify(this._scorecard.toJson()));
- }
-
- _updateRow(tableRow, pair) {
- let tds = tableRow.querySelectorAll("td");
-
- this._updateCell(pair.p1, tds[0], tds[1]);
- this._updateCell(pair.p2, tds[2], tds[3]);
- this._updateCell(pair.p3, tds[4], tds[5]);
- this._updateCell(pair.p4, tds[6], tds[7]);
- }
-
- _updateCell(score, scoreCell, totalCell) {
- scoreCell.classList.value = "";
- totalCell.classList.value = "";
-
- if (score != null) {
- scoreCell.textContent = score.score;
- totalCell.textContent = score.total;
- } else {
- scoreCell.textContent = "";
- totalCell.textContent = "";
- }
- }
-
- _appendRow() {
- let newRow = document.createElement("tr");
- newRow.classList.add("score-entry");
-
- for (let i = 0; i < 8; i++) {
- newRow.appendChild(document.createElement("td"));
- }
-
- this.scoreTableTarget.appendChild(newRow);
- return newRow;
- }
-
- addScore1() {
- this._addScore(this.score1InputTarget, this.score2InputTarget,
- this._scorecard.addPlayer1Score.bind(this._scorecard),
- this._scorecard.removeLastPlayer1Score.bind(this._scorecard));
- }
-
- addScore2() {
- this._addScore(this.score2InputTarget, this.score3InputTarget,
- this._scorecard.addPlayer2Score.bind(this._scorecard),
- this._scorecard.removeLastPlayer2Score.bind(this._scorecard));
- }
-
- addScore3() {
- this._addScore(this.score3InputTarget, this.score4InputTarget,
- this._scorecard.addPlayer3Score.bind(this._scorecard),
- this._scorecard.removeLastPlayer3Score.bind(this._scorecard));
- }
-
- addScore4() {
- this._addScore(this.score4InputTarget, this.score1InputTarget,
- this._scorecard.addPlayer4Score.bind(this._scorecard),
- this._scorecard.removeLastPlayer4Score.bind(this._scorecard));
- }
-
- _addScore(inputElem, focusToInputElem, addScoreFn, queueUndoFn) {
- let score = parseInt(inputElem.value);
- if (isNaN(score)) {
- score = 0;
- }
-
- addScoreFn(score);
- this._undoStack.push(queueUndoFn);
-
- inputElem.value = "";
-
- storeDao.save(this._scorecard);
- this.updateTable();
-
- focusToInputElem.focus();
- }
-
- score1KeyDown(e) {
- this._handleKeyDown(e, this.addScore1.bind(this));
- }
-
- score2KeyDown(e) {
- this._handleKeyDown(e, this.addScore2.bind(this));
- }
-
- score3KeyDown(e) {
- this._handleKeyDown(e, this.addScore3.bind(this));
- }
-
- score4KeyDown(e) {
- this._handleKeyDown(e, this.addScore4.bind(this));
- }
-
- _handleKeyDown(e, addScoreFn) {
- if (e.key === "Enter") {
- e.preventDefault();
- addScoreFn();
- }
- }
-
- undoLast() {
- if (this._undoStack.length === 0) {
- return;
- }
-
- (this._undoStack.pop())();
-
- storeDao.save(this._scorecard);
- this.updateTable();
- }
-
- resetAll() {
- if (!confirm("Really reset?")) {
- return;
- }
-
- this._scorecard.reset();
- storeDao.clear();
- this._undoStack = [];
- this.updateTable();
- }
-}
diff --git a/site/scorecard-4p/scripts/main.js b/site/scorecard-4p/scripts/main.js
deleted file mode 100644
index 34ece68..0000000
--- a/site/scorecard-4p/scripts/main.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Application } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js";
-import { FinskaScorecardController } from "./controllers.js"
-
-window.Stimulus = Application.start();
-
-window.Stimulus.register('finska-scorecard', FinskaScorecardController);
-
diff --git a/site/scorecard-4p/scripts/models.js b/site/scorecard-4p/scripts/models.js
deleted file mode 100644
index 2472177..0000000
--- a/site/scorecard-4p/scripts/models.js
+++ /dev/null
@@ -1,158 +0,0 @@
-export class ScoreEntry {
- constructor(score, total) {
- this.score = score;
- this.total = total;
- }
-};
-
-export class Scorecard {
-
- constructor() {
- this.reset();
- }
-
- reset() {
- this._player1Scores = [];
- this._player2Scores = [];
- this._player3Scores = [];
- this._player4Scores = [];
- }
-
- addPlayer1Score(newScore) {
- this._addScore(this._player1Scores, newScore);
- }
-
- removeLastPlayer1Score() {
- this._player1Scores.pop();
- }
-
- addPlayer2Score(newScore) {
- this._addScore(this._player2Scores, newScore);
- }
-
- removeLastPlayer2Score() {
- this._player2Scores.pop();
- }
-
- addPlayer3Score(newScore) {
- this._addScore(this._player3Scores, newScore);
- }
-
- removeLastPlayer3Score() {
- this._player3Scores.pop();
- }
-
- addPlayer4Score(newScore) {
- this._addScore(this._player4Scores, newScore);
- }
-
- removeLastPlayer4Score() {
- this._player4Scores.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,
- this._player3Scores.length, this._player4Scores.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),
- p3: (i < this._player3Scores.length ? this._player3Scores[i] : null),
- p4: (i < this._player4Scores.length ? this._player4Scores[i] : null),
- })
- }
-
- return pairs;
- }
-
- _newEntryFromPrevious(score, previousScoreEntry) {
- if (previousScoreEntry === null) {
- return new ScoreEntry(score, score, (score === 0 ? 1 : 0));
- }
-
- let newTotal = previousScoreEntry.total + score;
- return new ScoreEntry(score, newTotal);
- }
-
- toJson() {
- return {
- "version": 1,
- "p1": { "scores": this._player1Scores.map(p => p.score) },
- "p2": { "scores": this._player2Scores.map(p => p.score) },
- "p3": { "scores": this._player3Scores.map(p => p.score) },
- "p4": { "scores": this._player4Scores.map(p => p.score) },
- };
- }
-
- static fromJson(o) {
- let scorecard = new Scorecard();
- o["p1"]["scores"].forEach(x => scorecard.addPlayer1Score(x));
- o["p2"]["scores"].forEach(x => scorecard.addPlayer2Score(x));
- if (o["p3"]) o["p3"]["scores"].forEach(x => scorecard.addPlayer3Score(x));
- if (o["p4"]) o["p4"]["scores"].forEach(x => scorecard.addPlayer4Score(x));
- return scorecard;
- }
-}
-
-class StoreDAO {
-
- constructor(localStorage) {
- this._localStorage = localStorage;
- }
-
- save(scoreCard) {
- this._localStorage.setItem('generic-scorecard-4p', JSON.stringify(scoreCard.toJson()));
- }
-
- loadOrCreate() {
- try {
- console.log("Loading scorecard");
- let scoreCardJson = this._localStorage.getItem('generic-scorecard-4p');
- if (scoreCardJson !== null) {
- return Scorecard.fromJson(JSON.parse(scoreCardJson));
- }
- } catch (e) {
- console.log(`Could not restore game: ${e}`);
- }
-
- return new Scorecard();
- }
-
- clear() {
- this._localStorage.removeItem('generic-scorecard-4p');
- }
-}
-
-class DummyStoreDAO {
- save(scoreCard) { }
- loadOrCreate() {
- return new Scorecard();
- }
- clear() { }
-}
-
-export function getStoreDAO() {
- if (!!window.localStorage) {
- return new StoreDAO(window.localStorage);
- } else {
- return new DummyStoreDAO();
- }
-}
\ No newline at end of file
diff --git a/site/scorecard-4p/style.css b/site/scorecard-4p/style.css
deleted file mode 100644
index e2cd398..0000000
--- a/site/scorecard-4p/style.css
+++ /dev/null
@@ -1,21 +0,0 @@
-tfoot input {
- border-width: 1px;
-}
-
-.score-foul {
- color: #861D13;
- background-color: #F8DCD6;
- font-weight: bold;
-}
-
-.score-overflow {
- color: #5B4200;
- background-color: #FCEFD9;
- font-weight: bold;
-}
-
-.score-win {
- color: #394D00;
- background-color: #DEFC85;
- font-weight: bold;
-}
\ No newline at end of file
diff --git a/site/scorecard-2p/index.html b/site/scorecard/index.html
similarity index 91%
rename from site/scorecard-2p/index.html
rename to site/scorecard/index.html
index 0bf3b74..0f0fe13 100644
--- a/site/scorecard-2p/index.html
+++ b/site/scorecard/index.html
@@ -12,13 +12,7 @@
-
-
- Scorecard
- 2 Players
-
-
-
+ Scorecard
diff --git a/site/scorecard-2p/scripts/controllers.js b/site/scorecard/scripts/controllers.js
similarity index 100%
rename from site/scorecard-2p/scripts/controllers.js
rename to site/scorecard/scripts/controllers.js
diff --git a/site/scorecard-2p/scripts/main.js b/site/scorecard/scripts/main.js
similarity index 100%
rename from site/scorecard-2p/scripts/main.js
rename to site/scorecard/scripts/main.js
diff --git a/site/scorecard-2p/scripts/models.js b/site/scorecard/scripts/models.js
similarity index 94%
rename from site/scorecard-2p/scripts/models.js
rename to site/scorecard/scripts/models.js
index 64cd910..fb97c05 100644
--- a/site/scorecard-2p/scripts/models.js
+++ b/site/scorecard/scripts/models.js
@@ -94,13 +94,13 @@ class StoreDAO {
}
save(scoreCard) {
- this._localStorage.setItem('generic-scorecard-2p', JSON.stringify(scoreCard.toJson()));
+ this._localStorage.setItem('generic-scorecard', JSON.stringify(scoreCard.toJson()));
}
loadOrCreate() {
try {
console.log("Loading scorecard");
- let scoreCardJson = this._localStorage.getItem('generic-scorecard-2p');
+ let scoreCardJson = this._localStorage.getItem('generic-scorecard');
if (scoreCardJson !== null) {
return Scorecard.fromJson(JSON.parse(scoreCardJson));
}
@@ -112,7 +112,7 @@ class StoreDAO {
}
clear() {
- this._localStorage.removeItem('generic-scorecard-2p');
+ this._localStorage.removeItem('generic-scorecard');
}
}
diff --git a/site/scorecard-2p/style.css b/site/scorecard/style.css
similarity index 100%
rename from site/scorecard-2p/style.css
rename to site/scorecard/style.css