The pack
anagramRounds
function anagramRounds(): Pack<{ anagramRounds: AnagramRoundsApi }>
The anagram-rounds pack: timed anagram rounds over the english-words lists. Pure logic, so it runs headless.
Helpers
anagramScore
function anagramScore(word: string, full: boolean, scoring?: AnagramScoring): number
Points for word under scoring. Throws a RangeError for a table or function that gives a negative or non-finite number.
createAnagramRounds
function createAnagramRounds(options: AnagramRoundsOptions): AnagramRounds
Start a game. Throws a RangeError for options out of range: a letter count or length range no word in the list has, a time that is not above 0, a qualify rule or mode it does not know.
Types
AnagramEvent
type AnagramEvent = | { readonly kind: 'found'; readonly word: string; readonly points: number; readonly full: boolean } | { readonly kind: 'cleared'; readonly bonus: number } | { readonly kind: 'round-over'; readonly passed: boolean } | { readonly kind: 'skipped'; readonly word: string; readonly timedOut: boolean } | { readonly kind: 'next'; readonly round: number }
Something that happened, for a game to show.
AnagramMode
type AnagramMode = 'twist' | 'unscramble'
'twist': find every word a rack's letters spell, round after round. 'unscramble': unscramble one word after another.
AnagramMove
type AnagramMove = | { readonly kind: 'word'; readonly word: string } | { readonly kind: 'shuffle' } | { readonly kind: 'skip' } | { readonly kind: 'next' } | { readonly kind: 'advance'; readonly seconds: number }
A move.
AnagramRounds
interface AnagramRounds
A game of timed anagram rounds. Make one with createAnagramRounds.
observation(): AnagramView— The game as it stands.check(word: string): { readonly ok: true; readonly points: number; readonly full: boolean } | Refusal— Would this word count now?{ ok: true, points, full }or the refusal with a reason a player could be shown. Changes nothing.submit(word: string): { readonly ok: true; readonly result: FoundAnagram } | Refusal— Submit a word made from the rack's letters.shuffle(): void— Put the rack's letters in a new order.skip(): { readonly ok: true; readonly word: string } | Refusal— Unscramble: give up on the word, revealing it, for its cost. Refused in twist mode.next(): { readonly ok: true } | Refusal— Twist: start the next round after a passed one. Refused while playing or once the game is over.advance(seconds: number): void— Letsecondsof game time pass; consecutive advances are saved as one. A round or run ends when its clock does.undo(): boolean— Take back the last word, skip, shuffle or round start; time is never given back.hint(): { readonly first: string; readonly length: number } | null— The first letter and length of a word still to find (the shortest), or null.answers(): ReadonlyArray<string>— Twist: every target of the round. Unscramble: the word to unscramble. For a solver, a reveal or a test.snapshot(): HistorySave<AnagramMove>— The game as a save: the seed and the moves. Restore it into a game made with the same options.restore(save: HistorySave<AnagramMove> | string): void— Replace this game with a save. Throws, changing nothing, when it does not replay.
AnagramRoundsApi
type AnagramRoundsApi = typeof rules
game.anagramRounds: every function and type this pack carries, as one namespace.
AnagramRoundsOptions
interface AnagramRoundsOptions
How a game is set up. Only seed is required.
seed: number— Picks the words and every scramble, as an unsigned 32-bit integer.mode?: AnagramMode—'twist'(the default) or'unscramble'.words?: WordList— The words that count. Default the English lexicon.exclude?: ReadonlyArray<string>— Words never used, as a rack's word, a target or a word to unscramble (any case).minLength?: number— Twist: shortest word that counts, in letters. Default 3.letters?: number— Twist: letters on the rack in the first round. Default 6.growEvery?: number— Twist: one more letter every this many rounds; 0 never. Default 0.maxLetters?: number— Twist: most letters on the rack. Default 9.minWords?: number— Twist: fewest words a round's letters must spell for its word to be chosen. Default 6.attempts?: number— Twist: base words tried forminWords, the richest kept. Default 60.time?: number— Seconds on the clock: a twist round's, an unscramble run's, or withperWordeach unscrambled word's; Infinity for no limit. Default 120 for a twist round, 90 for a run, 30 a word.qualify?: QualifyRule— Twist: what passes a round. Default'full'.qualifyCount?: number— Twist: words needed withqualify: 'count'. Default 5.bonus?: number— Twist: points for finding every word of a round, which also ends it. Default 500.lengths?: readonly [number, number]— Unscramble: the shortest and longest word to unscramble. Default[5, 7].count?: number— Unscramble: words in a run. Default 10.perWord?: boolean— Unscramble: each word has a clock of its own,timeseconds; running out counts as a skip. Default false.skip?: 'points' | 'life'— Unscramble: what a skip (or a word's clock running out) costs:'points'(the default) or'life'.skipPenalty?: number— Unscramble: points a skip costs withskip: 'points'. Default 50. Never takes the score below 0.lives?: number— Unscramble: lives withskip: 'life'; the run ends at 0. Default 3.timeBonus?: number— Unscramble: points for each whole second left on the clock when a word is unscrambled. Default 1.scoring?: AnagramScoring— Points for each word. Default ten a letter, doubled for a word using every letter.
AnagramScoring
type AnagramScoring = ReadonlyArray<number> | ((word: string, full: boolean) => number)
Points for a word: a table of points by length (the last entry for anything longer), or your own function, told whether the word used every letter on the rack. Default: ten points a letter, doubled for a word using every letter.
AnagramTarget
interface AnagramTarget
One target of a twist round, as a player sees it.
readonly word: string | null— The word, once found or once the round is over; null before.readonly found: boolean— Found by the player (not just shown at the end).
AnagramView
interface AnagramView
The game as it stands. Never gives away an unfound word.
readonly mode: AnagramMode— The mode.readonly phase: 'playing' | 'round-over' | 'game-over'—'playing','round-over'(twist: passed, waiting fornext) or'game-over'.readonly round: number— The round (twist) or the word (unscramble), counting from 1.readonly letters: number— Letters on the rack.readonly rack: ReadonlyArray<string>— The rack's letters in their current order, lower case.readonly targets: ReadonlyArray<{ readonly length: number; readonly words: ReadonlyArray<AnagramTarget> }>— Twist: the round's words, by length, shortest first, alphabetical within a length. Empty in unscramble.readonly total: number— Twist: how many targets there are.readonly found: ReadonlyArray<FoundAnagram>— Words found this round (twist) or this run (unscramble), in order.readonly score: number— Points in the game so far.readonly timeLeft: number— Seconds on the clock now; Infinity for no limit.readonly time: number— The clock's full time, seconds.readonly passed: boolean— Twist: has the qualify rule been met this round? Unscramble: always true.readonly lives: number— Unscramble: lives left (Infinity unlessskip: 'life').readonly solved: number— Unscramble: words unscrambled.readonly skipped: ReadonlyArray<string>— Unscramble: words skipped or timed out, revealed.readonly last: AnagramEvent | null— What the last word, skip or round end did, or null.
FoundAnagram
interface FoundAnagram
A word found, and its points.
readonly word: string— The word, lower case.readonly points: number— Points it scored.readonly full: boolean— Did it use every letter on the rack?
QualifyRule
type QualifyRule = 'full' | 'count' | 'none'
What passes a twist round: a word using every letter ('full'), qualifyCount words ('count'), or nothing ('none').


