build(ui): move the rule's played-word set into the lazy dict chunk
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m16s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m27s
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m16s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m27s
Building the set of words a game has already used belonged with the rest of the rule, behind the same lazy import as the evaluator that consumes it, rather than in the always-loaded game screen. What is left in the app entry — the per-game flag on the decoded GameView and the caption that names a rejected word — costs more than the budget had free, so raise it by the usual kilobyte with the reason recorded alongside the earlier raises.
This commit is contained in:
@@ -3,5 +3,6 @@
|
||||
// of the initial app bundle — it is a progressive enhancement over the network
|
||||
// preview, which remains the fallback.
|
||||
export { evaluateLocal } from './eval';
|
||||
export { playedWordsFromHistory } from './norepeat';
|
||||
export { getDawg, peekDawg, hasDawg, dictLoadingDisabled, noteDictMiss, clearDictInstances, bustDictHttpCache } from './loader';
|
||||
export { clearDictCache, listCachedDicts } from './store';
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// variant, so a game started before the rule existed plays on without it.
|
||||
|
||||
import type { Move } from './validate';
|
||||
import type { MoveRecord } from '../model';
|
||||
|
||||
/**
|
||||
* wordKey identifies a word for the rule. Words are alphabet-index letters, so the key ignores
|
||||
@@ -36,6 +37,20 @@ export function playedWordKeys(words: Iterable<readonly number[]>): Set<string>
|
||||
return played;
|
||||
}
|
||||
|
||||
/**
|
||||
* playedWordsFromHistory is the rule's lookup set for a game whose history the server decoded for
|
||||
* us: every word its plays have formed, main words and cross-words alike, in the same lower-case
|
||||
* form evaluateLocal decodes a candidate word into. It lives here, with the rest of the rule and
|
||||
* behind the same lazy import as the evaluator, rather than in the game screen.
|
||||
*/
|
||||
export function playedWordsFromHistory(moves: readonly MoveRecord[]): Set<string> {
|
||||
const played = new Set<string>();
|
||||
for (const m of moves) {
|
||||
if (m.action === 'play') for (const w of m.words) played.add(w);
|
||||
}
|
||||
return played;
|
||||
}
|
||||
|
||||
/**
|
||||
* noRepeatScore applies the rule to an already validated move against the set of words already
|
||||
* played. It returns null when the move's main word is one of them — the play is illegal — and
|
||||
|
||||
Reference in New Issue
Block a user