msgid "Rack"
msgstr "Douger-pezhioù"
-msgid "Score"
-msgstr "Poentoù"
+msgid "Score:"
+msgstr "Poentoù:"
msgid "Waiting for other participants…"
msgstr "O c'hortoz c'hoarien all..."
msgid "Triple\nWord"
msgstr "Mot\nTriple"
-msgid "Join adversaries"
+msgid "Join adversaries"
msgstr "Rejoindre des adversaires"
msgid "You are:"
msgstr "Écrivez un message à vos adversaires ici"
msgid "Send message"
-msgstr "Envoyer le message"
+msgstr "Envoyer le message"
msgid "Sound of the tiles"
msgstr "Bruit des pièces"
msgid "Rack"
msgstr "Chevalet"
-msgid "Score"
-msgstr "Score"
+msgid "Score:"
+msgstr "Score :"
msgid "Waiting for other participants…"
msgstr "En attente des autres participants…"
msgid "Interface:"
msgstr "Interface :"
-msgid "Sorry to disturb you, but we need to reload the game so you can continue playing. You will not lose anything except the messages in the chat. Are you ready?"
+msgid "Sorry to disturb you, but we need to reload the game so you can continue playing. You will not lose anything except the messages in the chat. Are you ready?"
msgstr "Désolé pour le dérangement, mais nous avons besoin de recharger le jeu pour que vous poussiez continuer à jouer. Vous ne perdrez rien sauf les messages dans le chat. Êtes-vous prêt·e ?"
-msgid "To continue playing, click here"
+msgid "To continue playing, click here"
msgstr "Pour continuer à jouer, cliquez ici"
-msgid "{0}: "
+msgid "{0}: "
msgstr "{0} : "
-msgid "Whoops, there is a problem. We are trying to fix it as soon as possible. Please wait a few seconds. If it persists, please contact the person who is able to fix the problem."
+msgid "Whoops, there is a problem. We are trying to fix it as soon as possible. Please wait a few seconds. If it persists, please contact the person who is able to fix the problem."
msgstr "Oups, il y a un problème. Nous essayons de corriger cela le plus vite possible. Merci de bien vouloir patienter quelques secondes. Si cela persiste, n’hésitez pas à contacter la personne qui peut s’occuper de ce problème"
-msgid "The problem is solved, sorry for the inconvenience!"
+msgid "The problem is solved, sorry for the inconvenience!"
msgstr "Le problème est résolu. Désolé pour la gêne occasionnée !"
-msgid "It seems your browser went offline. Please reconnect to continue playing."
+msgid "It seems your browser went offline. Please reconnect to continue playing."
msgstr "On dirait que votre navigateur est hors ligne. Merci de bien vouloir vous reconnecter pour continuer à jouer."
msgid "Turn"
msgstr "{0} montre son jeu :"
msgid "You cannot take another tile: the bag is empty."
-msgstr "Vous ne pouvez pas tirer de pièce : le sac est vide."
+msgstr "Vous ne pouvez pas tirer de pièce : le sac est vide."
msgid "Are you sure you want to change board to '{0}'? This will put all the tiles back in the bag and start another game."
msgstr "Êtes-vous sûr·e de vouloir de changer la langue du plateau à '{0}' ? Cela remettra toutes les lettres du jeu dans le sac et commencera une nouvelle partie."
msgid "{0} points will be added to:"
msgstr "{0} points vont être ajoutés à:"
-msgid "There are no points to add."
+msgid "There are no points to add."
msgstr "Il n’y a pas de point à ajouter."
msgid "Settings"
msgstr "Couleur du flash laser"
msgid "Tip!"
-msgstr "Astuce !"
+msgstr "Astuce !"
-msgid "Next tip"
+msgid "Next tip"
msgstr "Astuce suivante"
-msgid "Disable the spell checker"
+msgid "Disable the spell checker"
msgstr "Désactiver la vérification orthographique"
-msgid "Spell checking is not available for this language."
+msgid "Spell checking is not available for this language."
msgstr "La vérification orthographique n'est pas disponible dans cette langue."
-msgid "Score new words"
+msgid "Score new words"
msgstr "Compter les points"
msgid "Turn:"
msgid "First word must cover center box."
msgstr "Le premier mot doit couvrir la case centrale."
+
+msgid "Freeze tiles after playing"
+msgstr "Bloquer les pièces à la fin du tour"
msgid "Rack"
msgstr "Suport"
-msgid "Score"
-msgstr "Scor"
+msgid "Score:"
+msgstr "Scor:"
msgid "Waiting for other participants…"
msgstr "În așteptarea altor participanți…"
msgid "Enter the score to add to {0}:"
msgstr ""
-msgid "To join a game, please give the number which is displayed on your adversary(ies)' screen.\nIf you do not know it, ask them.\n\nWarning: your adversary must not take your number, (s)he must keep his/her own. If you whish to recover your current game, please not the following number: {0}."
+msgid "To join a game, please give the number which is displayed on your adversary(ies)' screen.\nIf you do not know it, ask them.\n\nWarning: your adversary must not take your number, (s)he must keep his/her own."
msgstr ""
msgid "It seems your did not give a correct number, or you clicked on “Cancel”. As a result, the current game continues, if any. To join a game, click on “Join a game” again."
msgid "Triple\nWord"
msgstr ""
-msgid "Join adversaries"
+msgid "Join adversaries"
msgstr ""
msgid "You are:"
msgid "Rack"
msgstr ""
-msgid "Score"
+msgid "Score:"
msgstr ""
msgid "Waiting for other participants…"
msgid "Interface:"
msgstr ""
-msgid "Sorry to disturb you, but we need to reload the game so you can continue playing. You will not lose anything except the messages in the chat. Are you ready?"
+msgid "Sorry to disturb you, but we need to reload the game so you can continue playing. You will not lose anything except the messages in the chat. Are you ready?"
msgstr ""
-msgid "To continue playing, click here"
+msgid "To continue playing, click here"
msgstr ""
-msgid "{0}: "
+msgid "{0}: "
msgstr ""
-msgid "Whoops, there is a problem. We are trying to fix it as soon as possible. Please wait a few seconds. If it persists, please contact the person who is able to fix the problem."
+msgid "Whoops, there is a problem. We are trying to fix it as soon as possible. Please wait a few seconds. If it persists, please contact the person who is able to fix the problem."
msgstr ""
-msgid "The problem is solved, sorry for the inconvenience!"
+msgid "The problem is solved, sorry for the inconvenience!"
msgstr ""
msgid "It seems your browser went offline. Please reconnect to continue playing."
msgid "{0} points will be added to:"
msgstr ""
-msgid "There are no points to add."
-msgstr: ""
+msgid "There are no points to add."
+msgstr ""
msgid "Settings"
msgstr ""
msgid "Configuration window"
+msgstr ""
msgid "Look at:"
msgstr ""
msgid "Tip!"
msgstr ""
-msgid "Next tip"
+msgid "Next tip"
msgstr ""
-msgid "Disable the spell checker"
+msgid "Disable the spell checker"
msgstr ""
-msgid "Spell checking is not available for this language."
+msgid "Spell checking is not available for this language."
msgstr ""
-msgid "Score new words"
+msgid "Score new words"
msgstr ""
msgid "Turn:"
msgid "First word must cover center box."
msgstr ""
+
+msgid "Freeze tiles after playing"
+msgstr ""
<div>
<p><label><input type="checkbox" id="check-first-word" /> <span data-l10n="text-content">Enable first word verification</span></label></p>
</div>
+ <div>
+ <p><label><input type="checkbox" id="freeze-played-tiles" /> <span data-l10n="text-content">Freeze tiles after playing</span></label></p>
+ </div>
<div>
<p id="disable-spell-checker-p" hidden="true">
<label>
Lang: "string",
PlayerName: "string",
CheckFirstWord: "number",
+ FreezePlayedTiles: "number",
SpellCheckerEnabledOnce: "boolean",
TimerGameDate: "number",
TimerTurnDate: "number"
let blockMove = 0;
let remainingLetters = 0;
let needsRestart = false;
- let currentTilePlayed = {};
+ let currentTileOwner = {};
let eventSource = null;
let webSocket = null;
movingTile.style.width = "";
movingTile.style.height = "";
- /* Keep track of letter */
- if (moveCMD.from === "rack") {
- if (moveCMD.to === "board") {
- currentTilePlayed[moveCMD.indexTo] = "-";
- }
- } else {/* moveCMD.from === "board" */
- if (moveCMD.to === "board") {
- currentTilePlayed[moveCMD.indexTo] = currentTilePlayed[moveCMD.indexFrom];
- }
- delete currentTilePlayed[moveCMD.indexFrom];
- }
-
if (tileDest === bag) {
moveCMD.to = "bag";
moveCMD.indexTo = -1;
} else {
sendCmds([moveCMD]);
}
+
+ /* Keep track of letter move */
+ if (moveCMD.from === "board") {
+ delete currentTileOwner[moveCMD.indexFrom];
+ }
+ if (moveCMD.to === "board") {
+ currentTileOwner[moveCMD.indexTo] = true;
+ }
}
cleanupDragTile();
p = p.parentNode;
}
+ if ((getSetting("FreezePlayedTiles") > 0) && (from === "board") && (!currentTileOwner[index])) {
+ return;
+ }
+
if (!from) {
fatalError(new Error("Error: did not find the parent of the moving tile"));
return;
}
+ //XXXX
+
moveCMD = {
cmd: "moveLetter",
from: from,
}
}
- function setCell(index, letter, highlight) {
- if (lastPlayer) {
- if (letter) {
- currentTilePlayed[index] = letter;
- } else {
- delete currentTilePlayed[index];
- }
+ function setCell(index, letter, player, highlight) {
+ if (letter && (player === getSetting("PlayerName"))) {
+ currentTileOwner[index] = true;
+ } else {
+ delete currentTileOwner[index];
}
-
setTileParent(boardCells[index].getElementsByClassName("tile-placeholder")[0], letter, highlight);
}
case "checkFirstWord":
setSetting("CheckFirstWord", value);
break;
+ case "freezePlayedTiles":
+ setSetting("FreezePlayedTiles", value);
+ break;
}
}
player: row.firstChild.textContent,
score: res
}]);
+ currentTileOwner = {};
}
},
row.lastChild.firstChild.textContent,
player: row.firstChild.textContent,
score: parseInt(row.childNodes[2].childNodes[0].textContent) + res
}]);
+ currentTileOwner = {};
}
},
row.lastChild.firstChild.textContent,
if (Object.prototype.hasOwnProperty.call(player, "score")) {
const scoreCell = getScoreCell(playerName);
- if (parseInt(scoreCell.textContent) !== player.score) {
- currentTilePlayed = {};
- }
scoreCell.textContent = player.score;
blink(scoreCell);
}
function handleLastPlayer(data) {
if (data.player) {
- if (lastPlayer !== data.player) {
- currentTilePlayed = {};
- }
lastPlayer = data.player;
}
}
sendCmds([{cmd: "hello"}]);
lastPlayer = null;
- currentTilePlayed = {};
+ currentTileOwner = {};
break;
case "moveLetter":
if (data.to === "board") {
setCell(
- data.indexTo,
- data.letter,
+ data.indexTo, data.letter, data.player,
data.player && data.player !== getSetting("PlayerName")
);
} else if (data.to === "rack") {
handleLastPlayer(data);
setCell(
- data.indexTo,
- data.letter,
+ data.indexTo, data.letter, data.player,
data.player && data.player !== getSetting("PlayerName")
);
- if ((data.letter !== "") && (currentTilePlayed[data.indexTo] === "-")) {
- currentTilePlayed[data.indexTo] = data.letter;
- }
-
break;
case "setRackCell":
document.getElementById("check-first-word").checked = (getSetting("CheckFirstWord") === 1);
}
+ if (data.freezePlayedTiles) {
+ set("freezePlayedTiles", data.freezePlayedTiles);
+ document.getElementById("freeze-played-tiles").checked = (getSetting("FreezePlayedTiles") === 1);
+ }
+
if (data.players) {
setPlayers(data.players);
}
setBoard(data.board);
}
+ if (data.tileOwner) {
+ const player = getSetting("PlayerName");
+ for (const i of Object.keys(data.tileOwner)) {
+ if (data.tileOwner[i] === player) {
+ currentTileOwner[i] = true;
+ }
+ }
+ }
+
if (typeof data.remainingLetters === "number") {
remainingLetters = data.remainingLetters;
tileCount.textContent = data.remainingLetters;
boardLabel: getSetting("BoardLabel"),
bagFactor: (typeof getSetting("BoardLabel") === "undefined") ? 1 : BoardList[getSetting("BoardLabel")].factor,
checkFirstWord: getSetting("CheckFirstWord"),
+ freezePlayedTiles: getSetting("FreezePlayedTiles"),
version: VERSION,
cmds: cmds
};
function searchNewWords() {
const words = [];
- for (const i of Object.keys(currentTilePlayed)) {
+ for (const i of Object.keys(currentTileOwner)) {
/* Get board position */
const row = Math.floor(i / boardDef.nbColumns);
let letterFactor = 1;
/* Is a freshly played letter? */
- if (currentTilePlayed[index] === word.letters[l]) {
+ if (getLetterFromBoard(word.row, word.col) === word.letters[l]) {
/* Letter factor */
if (boardCells[index].classList.contains("special-cell-doubleLetter")) {
}
/* Check for trivabble (the premium score) */
- if (Object.keys(currentTilePlayed).length === boardDef.rackLength) {
+ if (Object.keys(currentTileOwner).length === boardDef.rackLength) {
if (Object.prototype.hasOwnProperty.call(BoardList[getSetting("BoardLabel")], "premium")) {
totalScore += BoardList[getSetting("BoardLabel")].premium;
} else {
return;
}
- currentTilePlayed = {};
-
sendCmds([{
cmd: "score",
player: name,
score: parseInt(getScoreCell(name).textContent) + totalScore
}]);
+ currentTileOwner = {};
},
playerName || lastPlayer || currentPlayer || getSetting("PlayerName")
);
};
}
+ function initFreezePlayedTiles() {
+ document.getElementById("freeze-played-tiles").checked = (getSetting("FreezePlayedTiles") === 1);
+ document.getElementById("freeze-played-tiles").onclick = function () {
+ const freezePlayedTiles = (document.getElementById("freeze-played-tiles").checked) ? 1 : -1;
+ set("freezePlayedTiles", freezePlayedTiles);
+ sendCmds([{cmd: "freezePlayedTiles", freezePlayedTiles: freezePlayedTiles}]);
+ };
+ }
+
function toggleSpellChecker(e) {
const disabled = document.getElementById("disable-spell-checker").checked;
checkDictionaryExistance();
initGame();
initSound();
initCheckFirstWord();
+ initFreezePlayedTiles();
initSpellChecker();
initFlashLight();
nextHelpMessage();
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 FREEZE_PLAYED_TILES = -1; // 1: freeze, 0: not set, -1: no freeze
const VERSION = 202005070100;
return res;
}
-Game.prototype.init = function (lang, label, factor, checkFirstWord) {
+// eslint-disable-next-line max-params
+Game.prototype.init = function (lang, label, factor, checkFirstWord, freezePlayedTiles) {
this.label = label || DEFAULT_BOARD_LABEL;
this.factor = factor || DEFAULT_BAG_FACTOR;
this.board = newBoard(this.label);
this.letterValues = boardTilesPerLang[this.lang].letterValues;
this.racks = {};
this.scores = {};
+ this.tileOwner = {};
this.checkFirstWord = checkFirstWord || CHECK_FIRST_WORD;
+ this.freezePlayedTiles = freezePlayedTiles || FREEZE_PLAYED_TILES;
this.lastUpdated = new Date();
this.currentPlayer = "";
letterValues: this.letterValues,
racks: this.racks,
scores: this.scores,
+ tileOwner: this.tileOwner,
checkFirstWord: this.checkFirstWord,
+ freezePlayedTiles: this.freezePlayedTiles,
lastUpdated: this.lastUpdated.toISOString(),
currentPlayer: this.currentPlayer
};
game.letterValues = boardTilesPerLang[game.lang].letterValues;
game.racks = obj.racks || {};
game.scores = obj.scores || {};
+ game.tileOwner = obj.tileOwner || {};
game.checkFirstWord = obj.checkFirstWord || CHECK_FIRST_WORD;
+ game.freezePlayedTiles = obj.freezePlayedTiles || FREEZE_PLAYED_TILES;
game.lastUpdated = obj.lastUpdated ? new Date(obj.lastUpdated) : new Date();
game.currentPlayer = obj.currentPlayer || "";
return game;
this.scores[playerID] = score;
+ for (const index of Object.keys(this.tileOwner)) {
+ if (this.tileOwner[index] === player) {
+ delete (this.tileOwner[index]);
+ }
+ }
+
this.pendingEvents.push({
players: [{
player: player,
this.pendingEvents.push({checkFirstWord: onOff});
};
+Game.prototype.setFreezePlayedTiles = function (onOff) {
+ this.freezePlayedTiles = onOff;
+ this.pendingEvents.push({freezePlayedTiles: onOff});
+};
+
Game.prototype.playerJoined = function (playerName) {
if (playerName) {
this.getPlayerRack(playerName); // Create the player's rack
return this.board[index];
};
-Game.prototype.setCell = function (index, letter, player) {
+Game.prototype.setCellAndTileOwner = function (index, letter, player) {
this.board[index] = letter;
+ if ((letter === "") || (player === "")) {
+ delete (this.tileOwner[index]);
+ } else {
+ this.tileOwner[index] = player;
+ }
this.pendingEvents.push({
player: player,
action: "setCell",
});
};
+Game.prototype.getTileOwner = function (index) {
+ return Object.prototype.hasOwnProperty.call(this.tileOwner, index) ? this.tileOwner[index] : "";
+};
+
Game.prototype.bagPushLetter = function (letter, player) {
if (letter) {
this.bag.push(letter);
};
Game.prototype.reset = function (player) {
- this.init(this.lang, this.label, this.factor, this.checkFirstWord);
+ this.init(this.lang, this.label, this.factor, this.checkFirstWord, this.freezePlayedTiles);
this.pendingEvents.push({
player: player,
action: "reset",
currentPlayer: game.currentPlayer,
rack: game.getPlayerRack(playerName),
checkFirstWord: game.checkFirstWord,
+ freezePlayedTiles: game.freezePlayedTiles,
board: game.board,
+ tileOwner: game.tileOwner,
remainingLetters: game.bag.length,
letterValues: game.letterValues,
version: VERSION
break;
}
+ case "freezePlayedTiles": {
+ game.setFreezePlayedTiles(cmd.freezePlayedTiles);
+ reply(message, response, cmdNumber, {error: 0});
+ break;
+ }
+
case "currentPlayer": {
game.setCurrentPlayer(cmd.player);
+ //for (const cell of game.board) {
+ // if ((cell.player != "") && (cell.player != cmd.player)) {
+ // cell.player = "";
+ // }
+ //}
reply(message, response, cmdNumber, {error: 0});
break;
}
}
letter = game.getCell(cmd.indexFrom);
- operations.push(game.setCell.bind(game, cmd.indexFrom, "", playerName));
+ //const cell = game.getCell(cmd.indexFrom);
+ //if (cell.player != playerName) {
+ // reply(message, response, cmdNumber, {error: 1, reason: "Move forbidden"});
+ // return false;
+ //}
+ //letter = cell.letter;
+ operations.push(game.setCellAndTileOwner.bind(game, cmd.indexFrom, "", playerName));
break;
case "bag":
return false;
}
- operations.push(game.setCell.bind(game, cmd.indexTo, letter, playerName));
+ operations.push(game.setCellAndTileOwner.bind(game, cmd.indexTo, letter, playerName));
break;
case "bag":
game.label = cmd.label || DEFAULT_BOARD_LABEL;
game.factor = cmd.factor || DEFAULT_BAG_FACTOR;
game.checkFirstWord = cmd.checkFirstWord || CHECK_FIRST_WORD;
+ game.freezePlayedTiles = cmd.freezePlayedTiles || FREEZE_PLAYED_TILES;
game.reset();
reply(message, response, cmdNumber, {
boardLabel: game.label,
bagFactor: game.factor,
checkFirstWord: game.checkFirstWord,
+ freezePlayedTiles: game.freezePlayedTiles,
letterValues: game.letterValues
});
letterValues: game.letterValues,
rack: game.getPlayerRack(message.playerName),
board: game.board,
+ tileOwner: game.tileOwner,
remainingLetters: game.bag.length,
checkFirstWord: game.checkFirstWord,
+ freezePlayedTiles: game.freezePlayedTiles,
version: VERSION
})
);