From: Laurent Mazet Date: Fri, 7 Mar 2025 10:07:52 +0000 (+0100) Subject: New option to check if first word cover central star (#13) X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=01adf6ac0e6fefb1c93ae68592036a379ca68b1b;p=trivabble.git New option to check if first word cover central star (#13) Reviewed-on: https://git.jakse.fr/trivabble/trivabble/pulls/13 Co-authored-by: Laurent Mazet Co-committed-by: Laurent Mazet --- diff --git a/bin/check-l10n-file.sh b/bin/check-l10n-file.sh new file mode 100755 index 0000000..8b91565 --- /dev/null +++ b/bin/check-l10n-file.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +PODIR="l10n/po/fr" + +PUBDIR="public" + +[ "$1" ] && PODIR=$1 +[ "$2" ] && PUBDIRF=$2 + +IFS=$'\n' + +function extract_from_html() { + awk -F '>' \ + '/l10n/ { + for (i=1; iSound of the tiles
Sound of messages
Enable first word verification
diff --git a/public/trivabble.js b/public/trivabble.js index 2cdd6ad..ac455f9 100644 --- a/public/trivabble.js +++ b/public/trivabble.js @@ -161,6 +161,7 @@ BoardLabel: "string", Lang: "string", PlayerName: "string", + CheckFirstWord: "number", SpellCheckerEnabledOnce: "boolean", TimerGameDate: "number", TimerTurnDate: "number" @@ -791,6 +792,9 @@ .map(function (x) {return parseInt(x);}); initBoard(); break; + case "checkFirstWord": + setSetting("CheckFirstWord", value); + break; } } @@ -999,6 +1003,14 @@ row.lastChild.lastChild.onclick = ( function (row) { return function () { + if (getSetting("CheckFirstWord") === 1) { + const centerCell = document.getElementById("center-cell"); + if (!centerCell.getElementsByClassName("tile")[0]) { + myAlert(_("First word must cover center box.")); + return; + } + } + if (!pollingReady) { showConnectionLost(); return; @@ -1031,6 +1043,14 @@ row.lastChild.lastChild.onclick = ( function (row) { return function () { + if (getSetting("CheckFirstWord") === 1) { + const centerCell = document.getElementById("center-cell"); + if (!centerCell.getElementsByClassName("tile")[0]) { + myAlert(_("First word must cover center box.")); + return; + } + } + if (!pollingReady) { showConnectionLost(); return; @@ -1215,6 +1235,11 @@ setCurrentPlayer(data.currentPlayer); } + if (data.checkFirstWord) { + set("checkFirstWord", data.checkFirstWord); + document.getElementById("check-first-word").checked = (getSetting("CheckFirstWord") === 1); + } + if (data.players) { setPlayers(data.players); } @@ -1536,6 +1561,7 @@ boardLang: getSetting("BoardLang"), boardLabel: getSetting("BoardLabel"), bagFactor: (typeof getSetting("BoardLabel") === "undefined") ? 1 : BoardList[getSetting("BoardLabel")].factor, + checkFirstWord: getSetting("CheckFirstWord"), version: VERSION, cmds: cmds }; @@ -1968,6 +1994,14 @@ function scoreWords() { let totalScore = 0; + if (getSetting("CheckFirstWord") === 1) { + const centerCell = document.getElementById("center-cell"); + if (!centerCell.getElementsByClassName("tile")[0]) { + myAlert(_("First word must cover center box.")); + return; + } + } + const newWords = searchNewWords(); for (const k of Object.keys(newWords)) { let wordFactor = 1; @@ -2215,6 +2249,15 @@ } } + function initCheckFirstWord() { + document.getElementById("check-first-word").checked = (getSetting("CheckFirstWord") === 1); + document.getElementById("check-first-word").onclick = function () { + const checkFirstWord = (document.getElementById("check-first-word").checked) ? 1 : -1; + set("checkFirstCheck", checkFirstWord); + sendCmds([{cmd: "checkFirstWord", checkFirstWord: checkFirstWord}]); + }; + } + function toggleSpellChecker(e) { const disabled = document.getElementById("disable-spell-checker").checked; checkDictionaryExistance(); @@ -2660,6 +2703,7 @@ initChat(); initGame(); initSound(); + initCheckFirstWord(); initSpellChecker(); initFlashLight(); nextHelpMessage(); diff --git a/server/trivabble-server.js b/server/trivabble-server.js index 0f90f91..c745e16 100644 --- a/server/trivabble-server.js +++ b/server/trivabble-server.js @@ -36,6 +36,7 @@ const GAMES_BACKUP = process.env.TRIVABBLE_GAMES_BACKUP || "games.backup.json"; const DEFAULT_BOARD_LANG = process.env.TRIVABBLE_DEFAULT_BOARD_LANG || "fr"; const DEFAULT_BOARD_LABEL = process.env.TRIVABBLE_DEFAULT_BOARD_LABEL || "15x15-7"; const DEFAULT_BAG_FACTOR = 1; +const CHECK_FIRST_WORD = 1; // 1: check, 0: not set, -1: no check const VERSION = 202005070100; @@ -240,7 +241,7 @@ function newBoard(label) { return res; } -Game.prototype.init = function (lang, label, factor) { +Game.prototype.init = function (lang, label, factor, checkFirstWord) { this.label = label || DEFAULT_BOARD_LABEL; this.factor = factor || DEFAULT_BAG_FACTOR; this.board = newBoard(this.label); @@ -249,6 +250,7 @@ Game.prototype.init = function (lang, label, factor) { this.letterValues = boardTilesPerLang[this.lang].letterValues; this.racks = {}; this.scores = {}; + this.checkFirstWord = checkFirstWord || CHECK_FIRST_WORD; this.lastUpdated = new Date(); this.currentPlayer = ""; @@ -265,6 +267,7 @@ Game.prototype.toJSON = function () { letterValues: this.letterValues, racks: this.racks, scores: this.scores, + checkFirstWord: this.checkFirstWord, lastUpdated: this.lastUpdated.toISOString(), currentPlayer: this.currentPlayer }; @@ -280,6 +283,7 @@ Game.fromJSON = function (obj) { game.letterValues = boardTilesPerLang[game.lang].letterValues; game.racks = obj.racks || {}; game.scores = obj.scores || {}; + game.checkFirstWord = obj.checkFirstWord || CHECK_FIRST_WORD; game.lastUpdated = obj.lastUpdated ? new Date(obj.lastUpdated) : new Date(); game.currentPlayer = obj.currentPlayer || ""; return game; @@ -317,6 +321,11 @@ Game.prototype.setCurrentPlayer = function (player) { this.pendingEvents.push({currentPlayer: player}); }; +Game.prototype.setCheckFirstWord = function (onOff) { + this.checkFirstWord = onOff; + this.pendingEvents.push({checkFirstWord: onOff}); +}; + Game.prototype.playerJoined = function (playerName) { if (playerName) { this.getPlayerRack(playerName); // Create the player's rack @@ -451,7 +460,7 @@ Game.prototype.bagPushLetter = function (letter, player) { }; Game.prototype.reset = function (player) { - this.init(this.lang, this.label, this.factor); + this.init(this.lang, this.label, this.factor, this.checkFirstWord); this.pendingEvents.push({ player: player, action: "reset", @@ -550,6 +559,7 @@ function handleCommand(cmdNumber, message, response) { availableBoardLangs: availableBoardLangs, currentPlayer: game.currentPlayer, rack: game.getPlayerRack(playerName), + checkFirstWord: game.checkFirstWord, board: game.board, remainingLetters: game.bag.length, letterletterValues: game.letterValues, @@ -570,6 +580,12 @@ function handleCommand(cmdNumber, message, response) { break; } + case "checkFirstWord": { + game.setCheckFirstWord(cmd.checkFirstWord); + reply(message, response, cmdNumber, {error: 0}); + break; + } + case "currentPlayer": { game.setCurrentPlayer(cmd.player); reply(message, response, cmdNumber, {error: 0}); @@ -747,6 +763,7 @@ function handleCommand(cmdNumber, message, response) { game.lang = cmd.lang || DEFAULT_BOARD_LANG; game.label = cmd.label || DEFAULT_BOARD_LABEL; game.factor = cmd.factor || DEFAULT_BAG_FACTOR; + game.checkFirstWord = cmd.checkFirstWord || CHECK_FIRST_WORD; game.reset(); reply(message, response, cmdNumber, { @@ -754,6 +771,7 @@ function handleCommand(cmdNumber, message, response) { boardLang: game.lang, boardLabel: game.label, bagFactor: game.factor, + checkFirstWord: game.checkFirstWord, letterValues: game.letterValues }); @@ -813,6 +831,7 @@ function handleCommands(message, responseAndType) { rack: game.getPlayerRack(message.playerName), board: game.board, remainingLetters: game.bag.length, + checkFirstWord: game.checkFirstWord, version: VERSION }) );