add German, English and Spanish pieces
authorLaurent Mazet <mazet@softndesign.org>
Sun, 3 May 2020 22:28:33 +0000 (00:28 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Sun, 3 May 2020 22:28:33 +0000 (00:28 +0200)
public/index.html
public/trivabble.js
server/de.js [new file with mode: 0644]
server/en.js [new file with mode: 0644]
server/es.js [new file with mode: 0644]
server/fr.js [new file with mode: 0644]
server/trivabble-server.js

index b71f1b02b9f28fde91b39a82759f02f550de2ebf..769a81c1dcc4a109007537c55d57faf087d93f19 100644 (file)
             <button data-l10n="text-content" id="join-game">Join adversaries</button>
             <p id="p-name"> <span data-l10n="text-content">You are:</span> <span id="name" data-l10n="text-content">(name to give)</span><br /><button class="minibutton" id="change-name" data-l10n="text-content">Change</button></p>
             <button id="clear-game" data-l10n="text-content">Put back all the tiles&#10;in the bag</button>
+            <p><span data-l10n="text-content">Board language: </span><span id="board-lang" data-l10n="text-content">(pending)</span></p>
+            <p>
+                <button data-l10n="text-content" id="change-de-board">German</button>
+                <button data-l10n="text-content" id="change-en-board">English</button>
+                <button data-l10n="text-content" id="change-fr-board">French</button>
+                <button data-l10n="text-content" id="change-es-board">Spanish</button>
+            </p>
             <p id="p-name"><span data-l10n="text-content">Number of your game:</span><br /><span id="number" data-l10n="text-content">(pending)</span></p>
             <div id="chat-messages"></div>
             <textarea id="chat-ta" placeholder="Write a message to your adversaries here" data-l10n="placeholder"></textarea>
index c1d71c621238ddaa04e5ce7194538ccc250912a3..36ff3448c7c00ef6ade37518923465a184153c62 100644 (file)
             case "gameNumber":
                 document.getElementById("number").textContent = localStorage.trivabbleGameNumber = value;
                 break;
+            case "boardLang":
+                document.getElementById("board-lang").textContent = localStorage.trivabbleBoardLang = value;
+                break;
         }
     }
 
             set("gameNumber", data.gameNumber);
         }
 
+        if (data.boardLang) {
+            set("boardLang", data.boardLang);
+        }
 
         if (data.letterValues) {
             scoreOf = data.letterValues;
         return {
             gameNumber: localStorage.trivabbleGameNumber || "",
             playerName: localStorage.trivabblePlayerName,
+            boardLang: localStorage.trivabbleBoardLang,
             version: VERSION,
             cmds: cmds
         };
         );
     }
 
+    function changeBoardLang(lang) {
+        myConfirm(
+            _("Are you sure you want to change board to '" + lang + "'? This will put all the tiles back in the bag an start another game."),
+            function () {
+                sendCmds([{cmd: "changeBoard", lang: lang}]);
+            }
+        );
+    }
+    function changeBoardDe() { changeBoardLang("de"); }
+    function changeBoardEn() { changeBoardLang("en"); }
+    function changeBoardEs() { changeBoardLang("es"); }
+    function changeBoardFr() { changeBoardLang("fr"); }
+
     function clearRack() {
         myConfirm(
             _("Are you sure you want to put all your tiles back in the bag?"),
         mouseDown(bag, bagClicked);
 
         document.getElementById("clear-game").onclick  = clearGame;
+        document.getElementById("change-de-board").onclick  = changeBoardDe;
+        document.getElementById("change-en-board").onclick  = changeBoardEn;
+        document.getElementById("change-es-board").onclick  = changeBoardEs;
+        document.getElementById("change-fr-board").onclick  = changeBoardFr;
         document.getElementById("change-name").onclick = changeName;
         document.getElementById("join-game").onclick   = joinGame;
         document.getElementById("clear-rack").onclick  = clearRack;
             document.getElementById("number").textContent = localStorage.trivabbleGameNumber;
         }
 
+        if (localStorage.trivabbleBoardLang) {
+            document.getElementById("board-lang").textContent = localStorage.trivabbleBoardLang;
+        }
+
         startGame(localStorage.trivabbleGameNumber);
     }
 
diff --git a/server/de.js b/server/de.js
new file mode 100644 (file)
index 0000000..2a0f454
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2020 Laurent Mazet <mazet@softndesign.org>
+ *
+ * @licstart
+ * This file is part of Trivabble.
+ *
+ * Trivabble is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License (GNU AGPL)
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Trivabble is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Trivabble.  If not, see <http://www.gnu.org/licenses/>.
+ * @licend
+ *
+ * @source: https://trivabble.1s.fr/
+ * @source: https://gitlab.com/raphj/trivabble/
+ */
+
+module.exports = {
+
+  /*
+     102 jetons:
+     - 0 point: Joker *2
+     - 1 point : E *15, N *9, S *7, I *6, R *6, T *6, U *6, A *5, D *4
+     - 2 points : H *4, G *3, L *3, O *3
+     - 3 points : M *4, B *2, W *1, Z *1
+     - 4 points : C *2, F *2, K *2, P *1
+     - 6 points : Ä *1, J *1, Ü *1, V *1
+     - 8 points : Ö *1, X *1
+     - 10 points : Q *1, Y *1
+   */
+
+  bag: [
+    " ", " ", // Joker
+    "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E",
+    "N", "N", "N", "N", "N", "N", "N", "N", "N",
+    "S", "S", "S", "S", "S", "S", "S",
+    "I", "I", "I", "I", "I", "I",
+    "R", "R", "R", "R", "R", "R",
+    "T", "T", "T", "T", "T", "T",
+    "U", "U", "U", "U", "U", "U",
+    "A", "A", "A", "A", "A",
+    "D", "D", "D", "D",
+    "H", "H", "H", "H",
+    "G", "G", "G",
+    "L", "L", "L",
+    "O", "O", "O",
+    "M", "M", "M", "M",
+    "B", "B",
+    "W",
+    "Z",
+    "C", "C",
+    "F", "F",
+    "K", "K",
+    "P",
+    "Ä",
+    "J",
+    "Ü",
+    "V",
+    "Ö",
+    "X",
+    "Q",
+    "Y"
+  ],
+
+  values: {
+    " ": 0,
+    "E": 1,
+    "N": 1,
+    "S": 1,
+    "I": 1,
+    "R": 1,
+    "T": 1,
+    "U": 1,
+    "A": 1,
+    "D": 1,
+    "H": 2,
+    "G": 2,
+    "L": 2,
+    "O": 2,
+    "M": 3,
+    "B": 3,
+    "W": 3,
+    "Z": 3,
+    "C": 4,
+    "F": 4,
+    "K": 4,
+    "P": 4,
+    "Ä": 6,
+    "J": 6,
+    "Ü": 6,
+    "V": 6,
+    "Ö": 8,
+    "X": 8,
+    "Q": 10,
+    "Y": 10
+  }
+};
diff --git a/server/en.js b/server/en.js
new file mode 100644 (file)
index 0000000..26f9894
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+ * Copyright (C) 2020 Laurent Mazet <mazet@softndesign.org>
+ *
+ * @licstart
+ * This file is part of Trivabble.
+ *
+ * Trivabble is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License (GNU AGPL)
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Trivabble is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Trivabble.  If not, see <http://www.gnu.org/licenses/>.
+ * @licend
+ *
+ * @source: https://trivabble.1s.fr/
+ * @source: https://gitlab.com/raphj/trivabble/
+ */
+
+module.exports = {
+  /*
+     100 jetons:
+     - 0 point: Blank *2
+     - 1 point : E *12, A *9, I *9, O *8, R *6, N *6, T *6, L *4, S *4, U *4
+     - 2 points : D *4, G *3
+     - 3 points : B *2, C *2, M *2, P *2
+     - 4 points : F *2, H *2, V *2, W *2, Y *2
+     - 5 points : K *1
+     - 8 points : J *1, X *1
+     - 10 points : Q *1, Z *1
+   */
+
+  bag: [
+    " ", " ", // Blanks
+    "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E",
+    "A", "A", "A", "A", "A", "A", "A", "A", "A",
+    "I", "I", "I", "I", "I", "I", "I", "I", "I",
+    "O", "O", "O", "O", "O", "O", "O", "O",
+    "R", "R", "R", "R", "R", "R",
+    "N", "N", "N", "N", "N", "N",
+    "T", "T", "T", "T", "T", "T",
+    "L", "L", "L", "L",
+    "S", "S", "S", "S",
+    "U", "U", "U", "U",
+    "D", "D", "D", "D",
+    "G", "G", "G",
+    "B", "B",
+    "C", "C",
+    "M", "M",
+    "P", "P",
+    "F", "F",
+    "H", "H",
+    "V", "V",
+    "W", "W",
+    "Y", "Y",
+    "K",
+    "J",
+    "X",
+    "Q",
+    "Z"
+  ],
+
+  values: {
+    " ": 0,
+    "E": 1,
+    "A": 1,
+    "I": 1,
+    "O": 1,
+    "R": 1,
+    "N": 1,
+    "T": 1,
+    "L": 1,
+    "S": 1,
+    "U": 1,
+    "D": 2,
+    "G": 2,
+    "B": 3,
+    "C": 3,
+    "M": 3,
+    "P": 3,
+    "F": 4,
+    "H": 4,
+    "V": 4,
+    "W": 4,
+    "Y": 4,
+    "K": 5,
+    "J": 8,
+    "X": 8,
+    "Q": 10,
+    "Z": 10
+  }
+};
diff --git a/server/es.js b/server/es.js
new file mode 100644 (file)
index 0000000..69b2ead
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * Copyright (C) 2020 Laurent Mazet <mazet@softndesign.org>
+ *
+ * @licstart
+ * This file is part of Trivabble.
+ *
+ * Trivabble is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License (GNU AGPL)
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Trivabble is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Trivabble.  If not, see <http://www.gnu.org/licenses/>.
+ * @licend
+ *
+ * @source: https://trivabble.1s.fr/
+ * @source: https://gitlab.com/raphj/trivabble/
+ */
+
+module.exports = {
+  /*
+     100 jetons:
+     - 0 point: Comodin *2
+     - 1 point : A *12, E *12, O *9, I *6, S *6, N *5, R *5, U *5, L *4, T *4
+     - 2 points : D *5, G *2
+     - 3 points : C *4, B *2, M *2, P *2
+     - 4 points : H *2, F *1, V *1, Y *1
+     - 5 points : CH *1, Q *1
+     - 8 points : J *1, LL *1, Ñ *1, RR *1, X *1
+     - 10 points : Z *1
+   */
+
+  bag: [
+    " ", " ", // Comodines
+    "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A",
+    "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E",
+    "O", "O", "O", "O", "O", "O", "O", "O", "O",
+    "I", "I", "I", "I", "I", "I",
+    "S", "S", "S", "S", "S", "S",
+    "N", "N", "N", "N", "N",
+    "R", "R", "R", "R", "R",
+    "U", "U", "U", "U", "U",
+    "L", "L", "L", "L",
+    "T", "T", "T", "T",
+    "D", "D", "D", "D", "D",
+    "G", "G",
+    "C", "C", "C", "C",
+    "B", "B",
+    "M", "M",
+    "P", "P",
+    "H", "H",
+    "F",
+    "V",
+    "Y",
+    "CH",
+    "Q",
+    "J",
+    "LL",
+    "Ñ",
+    "RR",
+    "X",
+    "Z"
+  ],
+
+  values: {
+    " ": 0,
+    "A": 1,
+    "E": 1,
+    "O": 1,
+    "I": 1,
+    "S": 1,
+    "N": 1,
+    "R": 1,
+    "U": 1,
+    "L": 1,
+    "T": 1,
+    "D": 2,
+    "G": 2,
+    "C": 3,
+    "B": 3,
+    "M": 3,
+    "P": 3,
+    "H": 4,
+    "F": 4,
+    "V": 4,
+    "Y": 4,
+    "CH": 5,
+    "Q": 5,
+    "J": 8,
+    "LL": 8,
+    "Ñ": 8,
+    "RR": 8,
+    "X": 8,
+    "Z": 10
+  }
+};
diff --git a/server/fr.js b/server/fr.js
new file mode 100644 (file)
index 0000000..744e1f9
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2020 Laurent Mazet <mazet@softndesign.org>
+ *
+ * @licstart
+ * This file is part of Trivabble.
+ *
+ * Trivabble is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License (GNU AGPL)
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Trivabble is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Trivabble.  If not, see <http://www.gnu.org/licenses/>.
+ * @licend
+ *
+ * @source: https://trivabble.1s.fr/
+ * @source: https://gitlab.com/raphj/trivabble/
+ */
+
+module.exports = {
+/*
+   102 jetons
+   - 0 point : Joker *2
+   - 1 point : E *15, A *9, I *8, N *6, O *6, R *6, S *6, T *6, U *6, L *5
+   - 2 points : D *3, M *3, G *2
+   - 3 points : B *2, C *2, P *2
+   - 4 points : F *2, H *2, V *2
+   - 8 points : J *1, Q *1
+   - 10 points : K *1, W *1, X *1, Y *1, Z *1
+ */
+
+  bag: [
+    " ", " ", // Jokers
+    "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E",
+    "A", "A", "A", "A", "A", "A", "A", "A", "A",
+    "I", "I", "I", "I", "I", "I", "I", "I",
+    "N", "N", "N", "N", "N", "N",
+    "O", "O", "O", "O", "O", "O",
+    "R", "R", "R", "R", "R", "R",
+    "S", "S", "S", "S", "S", "S",
+    "T", "T", "T", "T", "T", "T",
+    "U", "U", "U", "U", "U", "U",
+    "L", "L", "L", "L", "L",
+    "D", "D", "D",
+    "M", "M", "M",
+    "G", "G",
+    "B", "B",
+    "C", "C",
+    "P", "P",
+    "F", "F",
+    "H", "H",
+    "V", "V",
+    "J",
+    "Q",
+    "K",
+    "W",
+    "X",
+    "Y",
+    "Z"
+  ],
+
+  values: {
+    " ": 0,
+    "E": 1,
+    "A": 1,
+    "I": 1,
+    "N": 1,
+    "O": 1,
+    "R": 1,
+    "S": 1,
+    "T": 1,
+    "U": 1,
+    "L": 1,
+    "D": 2,
+    "M": 2,
+    "G": 2,
+    "B": 3,
+    "C": 3,
+    "P": 3,
+    "F": 4,
+    "H": 4,
+    "V": 4,
+    "J": 8,
+    "Q": 8,
+    "K": 10,
+    "W": 10,
+    "X": 10,
+    "Y": 10,
+    "Z": 10
+  }
+};
index 980e8388ec74c8766ecb05a6d9eb52552cd20da8..080659e837f6da959c135b5857c90590da36488a 100644 (file)
@@ -55,70 +55,22 @@ const REQUEST_TYPE_LONG_POLLING = 1;
 const REQUEST_TYPE_SSE          = 2;
 const REQUEST_TYPE_WEBSOCKET    = 3;
 
-const frBag = [
-    " ", " ", // Jokers
-    "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E",
-    "A", "A", "A", "A", "A", "A", "A", "A", "A",
-    "I", "I", "I", "I", "I", "I", "I", "I",
-    "N", "N", "N", "N", "N", "N",
-    "O", "O", "O", "O", "O", "O",
-    "R", "R", "R", "R", "R", "R",
-    "S", "S", "S", "S", "S", "S",
-    "T", "T", "T", "T", "T", "T",
-    "U", "U", "U", "U", "U", "U",
-    "L", "L", "L", "L", "L",
-    "D", "D", "D",
-    "M", "M", "M",
-    "G", "G",
-    "B", "B",
-    "C", "C",
-    "P", "P",
-    "F", "F",
-    "H", "H",
-    "V", "V",
-    "J",
-    "Q",
-    "K",
-    "W",
-    "X",
-    "Y",
-    "Z"
-];
-
 /* eslint-disable quote-props */
 
-const frValues = {
-    " ": 0,
-    "E": 1,
-    "A": 1,
-    "I": 1,
-    "N": 1,
-    "O": 1,
-    "R": 1,
-    "S": 1,
-    "T": 1,
-    "U": 1,
-    "L": 1,
-    "D": 2,
-    "M": 2,
-    "G": 2,
-    "B": 3,
-    "C": 3,
-    "P": 3,
-    "F": 4,
-    "H": 4,
-    "V": 4,
-    "J": 8,
-    "Q": 8,
-    "K": 10,
-    "W": 10,
-    "X": 10,
-    "Y": 10,
-    "Z": 10
+/* Manage multi language board */
+const boardPieces = {
+    "de": require ("./de.js"),
+    "en": require ("./en.js"),
+    "es": require ("./es.js"),
+    "fr": require ("./fr.js")
 };
+var boardLang = "fr";
 
 /* eslint-enable quote-props */
 
+var bag = boardPieces[boardLang].bag;
+var values = boardPieces[boardLang].values;
+
 const games = {};
 
 let saveTimeout = null;
@@ -153,7 +105,7 @@ function shuffleInPlace(a) {
 }
 
 function Game() {
-    this.letterValues = frValues;
+    this.letterValues = values;
     this.init();
     this.listeningPlayers = [];
     this.pendingEvents = [];
@@ -264,7 +216,7 @@ function newBoard() {
 
 Game.prototype.init = function () {
     this.board = newBoard();
-    this.bag = frBag.slice();
+    this.bag = bag.slice();
     this.racks = {};
     this.scores = {};
     this.lastUpdated = new Date();
@@ -287,7 +239,7 @@ Game.prototype.toJSON = function () {
 Game.fromJSON = function (obj) {
     const game = new Game();
     game.board            = obj.board  || newBoard();
-    game.bag              = obj.bag    || frBag.slice();
+    game.bag              = obj.bag    || bag.slice();
     game.racks            = obj.racks  || {};
     game.scores           = obj.scores || {};
     game.lastUpdated      = obj.lastUpdated ? new Date(obj.lastUpdated) : new Date();
@@ -521,11 +473,12 @@ function handleCommand(cmdNumber, message, response) {
                 error: 0,
                 gameNumber: gameNumber,
                 playerName: playerName,
+                boardLang: boardLang,
                 currentPlayer: game.currentPlayer,
                 rack: game.getPlayerRack(playerName),
                 board: game.board,
                 remainingLetters: game.bag.length,
-                letterValues: frValues,
+                letterValues: values,
                 version: VERSION
             });
             break;
@@ -710,6 +663,16 @@ function handleCommand(cmdNumber, message, response) {
             break;
         }
 
+        case "changeBoard": {
+            boardLang = cmd.lang;
+            bag = boardPieces[boardLang].bag;
+            values = boardPieces[boardLang].values;
+            game.reset();
+            reply(message, response, cmdNumber, {error: 0});
+            break;
+        }
+
+
         case "msg": {
             game.pendingEvents.push({
                 msg: {
@@ -741,6 +704,7 @@ function handleCommands(message, responseAndType) {
                 playerName:       message.playerName,
                 currentPlayer:    game.currentPlayer,
                 gameNumber:       gameNumber,
+                boardLang:        boardLang,
                 letterValues:     game.letterValues,
                 rack:             game.getPlayerRack(message.playerName),
                 board:            game.board,