// Static per-variant ruleset data for the offline engine — tile point values, bag tile counts // and blank count, indexed by alphabet letter index. Mirrored from scrabble-solver/rules/rules.go // (English / RussianScrabble / Erudit) so a local game is fully self-contained: online scoring // reads the server-sent alphabet (lib/alphabet.ts), but offline there is no server, so the values // live here. Board geometry, the centre and RACK_SIZE/BINGO already live in lib/premiums.ts; this // table adds the values (offline copy), the bag distribution and the blank count. Pinned to the Go // rulesets by ruleset.parity.test.ts. import type { Variant } from '../model'; /** VariantRuleset is the offline scoring + bag data for one variant. */ export interface VariantRuleset { /** Number of letters in the alphabet (bag distribution and values are indexed 0..size-1). */ size: number; /** Tiles drawn to a full rack (7 for every variant). */ rackSize: number; /** All-tiles (bingo) bonus. */ bingo: number; /** Number of blank tiles in the bag. */ blanks: number; /** Tile point value per letter index; a blank scores 0 (handled by the caller). */ values: readonly number[]; /** Bag tile count per letter index (how many of each letter the bag holds). */ counts: readonly number[]; /** Display glyph per letter index, upper-cased (matching lib/alphabet.ts). Offline needs these * to translate the engine's index space to/from the glyphs the game UI shows, with no server. */ letters: readonly string[]; } /** RULESETS is the static ruleset table, one entry per variant, mirrored from rules.go. */ export const RULESETS: Record = { scrabble_en: { size: 26, rackSize: 7, bingo: 50, blanks: 2, // a b c d e f g h i j k l m n o p q r s t u v w x y z values: [1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10], counts: [9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1], letters: [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'], }, scrabble_ru: { size: 33, rackSize: 7, bingo: 50, blanks: 2, // а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я values: [1, 3, 1, 3, 2, 1, 3, 5, 5, 1, 4, 2, 2, 2, 1, 1, 2, 1, 1, 1, 2, 10, 5, 5, 5, 8, 10, 10, 4, 3, 8, 8, 3], counts: [8, 2, 4, 2, 4, 8, 1, 1, 2, 5, 1, 4, 4, 3, 5, 10, 4, 5, 5, 5, 4, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2], letters: [...'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'], }, erudit_ru: { size: 33, rackSize: 7, bingo: 15, blanks: 3, // а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я values: [1, 3, 2, 3, 2, 1, 0, 5, 5, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 3, 10, 5, 10, 5, 10, 10, 10, 5, 5, 10, 10, 3], counts: [10, 3, 5, 3, 5, 9, 0, 2, 2, 8, 4, 6, 4, 5, 8, 10, 6, 6, 6, 5, 3, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 3], letters: [...'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'], }, };