The pack
yahtzee
function yahtzee(): Pack<{ yahtzee: typeof rules }>
Install classic and triple Yahtzee scoring, matches and visible-information advice above dice-core.
Helpers
createYahtzee
function createYahtzee(options: YahtzeeOptions = {}): YahtzeeGame
Create a seeded solo, local or computer-opponent match.
YAHTZEE_CATEGORIES
const YAHTZEE_CATEGORIES: readonly ["ones", "twos", "threes", "fours", "fives", "sixes", "three-kind", "four-kind", "full-house", "small-straight", "large-straight", "yahtzee", "chance"]
The classic thirteen categories, in scorecard order.
yahtzeeHint
function yahtzeeHint(view: YahtzeeObservation, difficulty = view.difficulty): YahtzeeAdvice
Evaluate all 31 nontrivial hold masks with a bounded one-turn Monte Carlo heuristic on visible state only.
yahtzeeScore
function yahtzeeScore(category: YahtzeeCategory, dice: readonly number[]): number
Exact ordinary category scoring; a five-of-kind is not an ordinary full house.
yahtzeeScoringOptions
function yahtzeeScoringOptions(dice: readonly number[], card: YahtzeeScorecard): YahtzeeScoringOption[]
Exact legal scoring with classic Joker rules, including when Yahtzee was previously scored zero.
yahtzeeTotals
function yahtzeeTotals(card: YahtzeeScorecard): { upper: number; upperBonus: number; lower: number; yahtzeeBonus: number; total: number }
Exact scorecard totals, including the 63-point upper threshold and all 100-point bonuses.
Classes
YahtzeeGame
class YahtzeeGame
Yahtzee owns scoring and three-roll turns above one ordinary flexible dice pool. The match is a kernel history: its state is a function of the seed and the accepted commands, so a save is those commands and a restore replays them.
constructor(options: YahtzeeOptions = {})observation(): YahtzeeObservation— Public state for players and bots. No future random state is included.preview(action: YahtzeeAction): { ok: true } | { ok: false; reason: string }— Explain roll/hold/score legality without changing dice or state.apply(action: YahtzeeAction): YahtzeeResult— Apply a valid command, returning exact rendering events.hint(difficulty = this.options.difficulty): YahtzeeAdvice— Pure advice; inspection never consumes the match's randomness.autoStep(difficulty = this.options.difficulty): YahtzeeResult— Apply one advice step; rerolls set holds then roll through ordinary legal commands.snapshot(): YahtzeeSnapshot— Save a bounded deterministic command trace.restore(snapshot: YahtzeeSnapshot): void— Recompute every score, bonus, hold and roll from commands. Invalid traces leave the match intact.
Types
YahtzeeAction
type YahtzeeAction = { kind: 'roll' } | { kind: 'hold'; index: number; held: boolean } | { kind: 'score'; category: YahtzeeCategory; card?: number }
Public roll/hold/score commands.
YahtzeeAdvice
interface YahtzeeAdvice
Bounded advice for one turn, not an optimal full-match solver.
action: { kind: 'roll' } | { kind: 'reroll'; keep: number[] } | { kind: 'score'; category: YahtzeeCategory; card: number } | null— Suggested roll, reroll holding indices, or category choice.reason: string— Human-readable explanation.method: 'bounded-heuristic'— Honest analysis label.samples: number— Simulated terminal rolls evaluated.
YahtzeeCategory
type YahtzeeCategory = typeof YAHTZEE_CATEGORIES[number]
One scorecard row.
YahtzeeEvent
type YahtzeeEvent = { kind: 'roll'; dice: number[]; held: boolean[]; rolls: number } | { kind: 'hold'; index: number; held: boolean } | { kind: 'score'; player: number; card: number; category: YahtzeeCategory; points: number; bonus: number } | { kind: 'turn'; player: number; turn: number } | { kind: 'complete'; winners: number[] }
Ordered events for rendering and replay.
YahtzeeMatchScoringOption
interface YahtzeeMatchScoringOption extends YahtzeeScoringOption
A category preview for one of the current player's cards.
card: number— Zero-based scorecard within the current seat.
YahtzeeObservation
interface YahtzeeObservation
Visible match state; includes no seed, RNG state or future dice.
phase: 'playing' | 'complete'— Playing or finished.players: string[]— Seat names.bots: number[]— Computer seat indices.active: number— Current seat.turn: number— Current turn, starting at one.rolls: number— Rolls consumed this turn, zero to three.dice: (number | null)[]— Current faces; null before the first roll of each turn.held: boolean[]— Held dice.variant: 'classic' | 'triple'— Match variant.cardsPerPlayer: 1 | 3— Number of cards belonging to each seat.scorecards: YahtzeeScorecard[]— Public cards in player-major order: player * cardsPerPlayer + card.totals: number[]— Grand totals per seat, adding each card's total without multipliers.previews: YahtzeeMatchScoringOption[]— Exact category previews for every card of the current seat.winners: number[]— Winning seat indices; multiple indices represent a tie.difficulty: 'easy' | 'medium' | 'hard'— Bot/hint strength.
YahtzeeOptions
interface YahtzeeOptions
A classic or triple match, with one to four seats and optional computer seats.
seed?: number— Unsigned 32-bit seed.variant?: 'classic' | 'triple'— Classic has one card per seat; triple has three, with unweighted combined totals.players?: string[]— Unique, nonempty seat names; default solo.bots?: number[]— Seat indices controlled by computer play; default none.difficulty?: 'easy' | 'medium' | 'hard'— Changes advice/bot sampling only, never the dice.
YahtzeeResult
type YahtzeeResult = { ok: true; events: YahtzeeEvent[] } | { ok: false; reason: string }
An atomic action response.
YahtzeeScorecard
interface YahtzeeScorecard
Filled scores and extra-Yahtzee count. Missing rows remain playable; zero is a filled row.
scores: Partial<Record<YahtzeeCategory, number>>— At most one score per category.yahtzeeBonuses: number— Number of additional Yahtzees after a scored 50.
YahtzeeScoringOption
interface YahtzeeScoringOption
An exact preview, including forced Joker placement and bonus effects.
category: YahtzeeCategory— Scorecard row.legal: boolean— Legal to select this row.reason: string— Rejection reason, empty for legal rows.points: number— Points in this row, not including bonuses.bonus: number— Additional Yahtzee bonus, 0 or 100.joker: boolean— This roll is governed by the Joker placement rules.
YahtzeeSnapshot
interface YahtzeeSnapshot
Save/replay format; seed is privileged data and is never an input to a hint.
version: 1— Format version.options: Required<Omit<YahtzeeOptions, 'variant'>> & Pick<YahtzeeOptions, 'variant'>— Original match settings.actions: YahtzeeAction[]— Accepted player/bot commands.


