import fs from 'node:fs'; import { buildWordSet, loadComboWords, getCommonnessScore } from './lexicon-sources.mjs'; // Build a clean, high-frequency recognized vocabulary for client-side unlimited/custom puzzles // (includes regional spellings and the proper-word allowlist) const vocabulary = buildWordSet(); // Accept-only words (scripts/combo-words.txt): valid in play, never shown in solution lists const comboWords = [...new Set(loadComboWords())].filter(w => !vocabulary.has(w)).sort(); console.log('Total vocabulary words:', vocabulary.size); console.log('Accept-only combo words:', comboWords.length); // Pack into space-separated string or array const sortedWords = [...vocabulary].sort(); // One digit (0-4) per word, parallel to RAW_LEXICON. Compresses to almost nothing. const commonnessDigits = sortedWords.map(w => getCommonnessScore(w)).join(''); const lexiconContent = `// Client-side recognized English words for solver & custom puzzles // Loaded as a Set for O(1) instantaneous lookup const RAW_LEXICON = ${JSON.stringify(sortedWords)}; export const DICTIONARY_SET = new Set(RAW_LEXICON); // Commonness tier per word (4 = most common, 0 = rare), parallel to RAW_LEXICON const RAW_COMMONNESS = ${JSON.stringify(commonnessDigits)}; const COMMONNESS_MAP = new Map(); for (let i = 0; i < RAW_LEXICON.length; i++) { const c = RAW_COMMONNESS.charCodeAt(i) - 48; if (c > 0) COMMONNESS_MAP.set(RAW_LEXICON[i], c); } export function getCommonnessScore(word) { return COMMONNESS_MAP.get(word) || 0; } // Accept-only words buildable from pool tiles (generated by // scripts/find-missing-combo-words.mjs). Space-packed to keep the bundle small. const RAW_COMBO_WORDS = ${JSON.stringify(comboWords.join(' '))}; export const COMBO_WORD_SET = new Set(RAW_COMBO_WORDS ? RAW_COMBO_WORDS.split(' ') : []); // Prefix set for lightning fast tree-pruning search (1 to 6 chars) export const PREFIX_SET = new Set(); for (const word of RAW_LEXICON) { for (let len = 1; len <= Math.min(word.length, 6); len++) { PREFIX_SET.add(word.slice(0, len)); } } export function isWordValid(word) { return DICTIONARY_SET.has(word.toLowerCase()); } // Any word a player may submit: main dictionary + accept-only combo words export function isAcceptedWord(word) { const w = word.toLowerCase(); return DICTIONARY_SET.has(w) || COMBO_WORD_SET.has(w); } `; fs.writeFileSync('src/data/lexicon.js', lexiconContent, 'utf8'); console.log('Saved src/data/lexicon.js successfully!');