The pack
hangman
function hangman(): Pack<{ hangman: HangmanApi }>
The hangman pack: letter-guessing rules over the english-words lists. Pure logic, so it runs headless.
Helpers
createHangman
function createHangman(options: HangmanOptions): Hangman
Start a game. Throws a RangeError for options out of range: a seed that is not an unsigned 32-bit integer, a lives
count that is not a whole number of 1 or more (or Infinity), a negative or fractional penalty or hint cost, a set
answer with no letters, or a word source with nothing between min and max letters.
hangmanCandidates
function hangmanCandidates(pool: Iterable<string>, pattern: ReadonlyArray<string | null>, misses: Iterable<string> = [], opts: { hits?: Iterable<string>; hidden?: Iterable<string>; exclude?: Iterable<string> } = {}): string[]
The answers in pool still possible for pattern, in pool order, once each. pattern has one entry a character:
a letter that shows, null for a hidden letter, or a character that is not a letter (a space), which must match.
A candidate holds no letter of misses anywhere, shows the right letter at every shown place, and at a hidden place
holds none of hits (letters guessed and in the answer: they would show), none of misses and none of hidden
(letters that cannot hide, such as given vowels). hits defaults to every letter the pattern shows; exclude
leaves out answers already guessed whole. Entries are compared in lower case with accents taken off.
Types
Hangman
interface Hangman
A game of hangman. Make one with createHangman.
observation(): HangmanView— The game as it stands.check(move: HangmanMove): { readonly ok: true } | Refusal— Wouldmovebe accepted now?{ ok: true }, or the refusal with a reason a player could be shown. Changes nothing.letter(letter: string): { readonly ok: true; readonly result: HangmanResult } | Refusal— Guess a letter.word(word: string): { readonly ok: true; readonly result: HangmanResult } | Refusal— Guess the whole answer; spaces and punctuation do not matter.hint(): { readonly ok: true; readonly result: HangmanResult } | Refusal— Show one hidden letter, forhintCostlives: the one that uncovers the most positions (alphabetical on a tie).undo(): boolean— Take back the last move. False when there is none.candidates(): string[]— Every answer in the word source still possible: the same shape, agreeing with every letter shown and missed.suggest(): string | null— The best next letter: the one most ofcandidates()hold in a hidden place (alphabetical on a tie); null when over.autoStep(): { readonly ok: true; readonly result: HangmanResult } | Refusal— Play the advice: the whole answer when one candidate is left (and whole guesses are on), elsesuggest()'s letter.answer(): string— The answer, for a game's own reveal or a test.snapshot(): HistorySave<HangmanMove>— The game as a save: the seed and the moves. Restore it into a game made with the same options.restore(save: HistorySave<HangmanMove> | string): void— Replace this game with a save. Throws, changing nothing, when the save does not replay under these options.
HangmanApi
type HangmanApi = typeof rules
game.hangman: every function and type this pack carries, as one namespace.
HangmanMove
type HangmanMove = | { readonly kind: 'letter'; readonly letter: string } | { readonly kind: 'word'; readonly word: string } | { readonly kind: 'hint' }
A move: a letter, a whole answer, or a hint.
HangmanOptions
interface HangmanOptions
How a game is set up. Only seed is required; the defaults are a 5 to 9 letter English word and six lives.
seed: number— Picks the answer whenanswerdoes not give it, as an unsigned 32-bit integer.words?: WordList | ReadonlyArray<string>— Where answers come from: a word list, or an array whose entries may be phrases ("polar bear","jack-in-the-box"): spaces, hyphens and other characters that are not letters are shown from the start and never guessed. Accents are taken off. Default the English lexicon.min?: number— Fewest letters in a picked answer. Default 5 for a word list, 1 for an array.max?: number— Most letters in a picked answer. Default 9 for a word list, no limit for an array.answer?: string— The answer, a word or phrase, instead of a seeded pick.lives?: number— Lives before the game is lost: a whole number of 1 or more, or Infinity. Default 6.reveal?: HangmanReveal— Letters shown from the start. Default'none'.wordGuess?: boolean— May the player guess the whole answer? Default true.wordPenalty?: number— Lives a wrong whole-answer guess costs, a whole number. Default 1.hintCost?: number— Lives a hint costs, a whole number; 0 for free hints. Default 1.
HangmanResult
interface HangmanResult
What a move did.
readonly kind: 'hit' | 'miss' | 'solved' | 'wrong' | 'hint'—'hit','miss','solved'(a right whole answer),'wrong'(a wrong one) or'hint'.readonly guess: string— The letter guessed or hinted, or the whole answer guessed.readonly uncovered: ReadonlyArray<number>— The positions inslotsit uncovered, in order.readonly cost: number— Lives it cost.readonly phase: HangmanView['phase']— The phase after it.
HangmanReveal
type HangmanReveal = 'none' | 'first' | 'first-last' | 'vowels'
Which letters show from the start: none, the first, the first and last, or every vowel.
HangmanSlot
interface HangmanSlot
One character of the answer as a player sees it.
readonly char: string | null— The character: a revealed letter (lower case), a character that is not a letter (shown from the start), or null for a hidden letter.readonly letter: boolean— Is it a letter, to be guessed? A space or a hyphen is not.readonly revealed: boolean— Showing? Always true for a character that is not a letter.
HangmanView
interface HangmanView
Everything a game draws, at one moment. Never holds the answer before the game is over.
readonly phase: 'playing' | 'won' | 'lost'—'playing','won'or'lost'.readonly slots: ReadonlyArray<HangmanSlot>— Every character of the answer, in order.readonly letters: number— How many of the slots are letters.readonly hits: ReadonlyArray<string>— Letters guessed that are in the answer, in the order guessed.readonly misses: ReadonlyArray<string>— Letters guessed that are not, in the order guessed.readonly wrongWords: ReadonlyArray<string>— Whole-answer guesses that were wrong, in order.readonly hinted: ReadonlyArray<string>— Letters shown by hints, in order.readonly lives: number— Lives at the start; Infinity for no limit.readonly lost: number— Lives lost so far: one a miss,wordPenaltya wrong whole-answer guess,hintCosta hint.readonly livesLeft: number— Lives left; Infinity for no limit.readonly answer: string | null— The answer, once the game is over; null before.readonly keyboard: Readonly<Record<string, 'hit' | 'miss' | 'unused'>>— Each letter a to z:'hit'(in the answer, guessed or hinted),'miss', or'unused'.readonly wordGuess: boolean— May the whole answer be guessed?readonly hintCost: number— Lives a hint costs.readonly given: ReadonlyArray<string>— Letters the reveal shows and that cannot be guessed: the vowels withreveal: 'vowels', else none.


