From: Carl Worth Date: Sun, 8 Mar 2026 00:03:57 +0000 (-0500) Subject: Extract shared tile distribution and bag logic into tiles.js X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=5864a81920a302453ce0c1dc7019f5e7c7c06f0e;p=lmno-server Extract shared tile distribution and bag logic into tiles.js Letter Rip now imports from the shared module instead of defining its own tile distribution and make_bag(). This prepares for the Anagrams game which will reuse the same tile bag (without blanks). Co-Authored-By: Claude Opus 4.6 --- diff --git a/letterrip.js b/letterrip.js index e90a165..f717aa6 100644 --- a/letterrip.js +++ b/letterrip.js @@ -1,29 +1,7 @@ const express = require("express"); const Game = require("./game.js"); const TWL_WORDS = new Set(require("./twl-words.js")); - -/* Tile distribution (98 tiles + 2 blanks = 100). - * Letter counts: A9 B2 C2 D4 E12 F2 G3 H2 I9 J1 K1 L4 M2 - * N6 O8 P2 Q1 R6 S4 T6 U4 V2 W2 X1 Y2 Z1 - */ -const TILE_DISTRIBUTION = - "AAAAAAAAA" + - "BB" + "CC" + "DDDD" + - "EEEEEEEEEEEE" + - "FF" + "GGG" + "HH" + - "IIIIIIIII" + - "J" + "K" + - "LLLL" + "MM" + - "NNNNNN" + - "OOOOOOOO" + - "PP" + "Q" + - "RRRRRR" + - "SSSS" + - "TTTTTT" + - "UUUU" + - "VV" + "WW" + - "X" + "YY" + "Z" + - "__"; +const { make_bag } = require("./tiles.js"); const INITIAL_TILES = 7; @@ -31,7 +9,7 @@ class LetterRip extends Game { constructor(id) { super(id); this.state = { - bag: LetterRip.make_bag(), + bag: make_bag(), player_tiles: {}, player_boards: {}, results: null, @@ -40,16 +18,6 @@ class LetterRip extends Game { }; } - static make_bag() { - const tiles = TILE_DISTRIBUTION.split(""); - /* Fisher-Yates shuffle */ - for (let i = tiles.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [tiles[i], tiles[j]] = [tiles[j], tiles[i]]; - } - return tiles; - } - /* Deal count_per_player tiles to each active player. * Returns true on success, false if not enough tiles. */ deal(count_per_player) { diff --git a/templates/letterrip-game.html b/templates/letterrip-game.html index acd1cb5..21422b5 100644 --- a/templates/letterrip-game.html +++ b/templates/letterrip-game.html @@ -1,6 +1,7 @@ {% extends "base.html" %} {% block head %} + diff --git a/tiles.js b/tiles.js new file mode 100644 index 0000000..b820596 --- /dev/null +++ b/tiles.js @@ -0,0 +1,43 @@ +/* Shared tile distribution and bag logic for letter-based games. + * + * Standard distribution (98 tiles + 2 blanks = 100): + * A9 B2 C2 D4 E12 F2 G3 H2 I9 J1 K1 L4 M2 + * N6 O8 P2 Q1 R6 S4 T6 U4 V2 W2 X1 Y2 Z1 __ + */ + +const TILE_DISTRIBUTION = + "AAAAAAAAA" + + "BB" + "CC" + "DDDD" + + "EEEEEEEEEEEE" + + "FF" + "GGG" + "HH" + + "IIIIIIIII" + + "J" + "K" + + "LLLL" + "MM" + + "NNNNNN" + + "OOOOOOOO" + + "PP" + "Q" + + "RRRRRR" + + "SSSS" + + "TTTTTT" + + "UUUU" + + "VV" + "WW" + + "X" + "YY" + "Z" + + "__"; + +/* Letters only (no blanks). */ +const TILE_DISTRIBUTION_NO_BLANKS = TILE_DISTRIBUTION.replace(/_/g, ""); + +/* Create a shuffled bag of tiles. */ +function make_bag(distribution) { + const tiles = (distribution || TILE_DISTRIBUTION).split(""); + /* Fisher-Yates shuffle */ + for (let i = tiles.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [tiles[i], tiles[j]] = [tiles[j], tiles[i]]; + } + return tiles; +} + +exports.TILE_DISTRIBUTION = TILE_DISTRIBUTION; +exports.TILE_DISTRIBUTION_NO_BLANKS = TILE_DISTRIBUTION_NO_BLANKS; +exports.make_bag = make_bag;