import { HwCell, HwCoin, HwEffect } from './HwTypes.js'; export type HwPhase = 'idle' | 'active' | 'spinning'; /** * The pure Hold & Win state machine - the single source of truth for board * state, with **zero** PixiJS. It owns the locked-coin ledger, the respin * counter, the round number and the feature {@link HwPhase}; every derived * value (`freeCells`, `isFull`) is computed from the one ledger, never stored * in parallel, so nothing can drift out of sync. * * It is a *reducer, not a cache*: {@link HoldAndWinBoard} drives the reels and * reports each landing here; the methods mutate the ledger and **return the * ordered list of {@link HwEffect}s to emit**, which the driver replays onto its * event emitter (and uses to fire visual side effects like `playWin()`). Locks * happen progressively as cells land in stagger order, so this is an * *incremental* reducer ({@link beginWave} → N×{@link land} → {@link endWave}), * not a one-shot `reduce(state, hits)`. * * Being PixiJS-free, it is fully unit-testable: assert the returned effect * sequence for hit / miss / full / release / reset / error paths. */ export declare class HoldAndWinState { private readonly _locked; private readonly _cellSet; private readonly _allCells; private readonly _defaultRespins; private _respinsLeft; private _round; private _phase; private _waveLanded; constructor(allCells: HwCell[], defaultRespins: number); get phase(): HwPhase; get respinsLeft(): number; get round(): number; get capacity(): number; get isFull(): boolean; lockedCoins(): HwCoin[]; freeCells(): HwCell[]; isLocked(cell: HwCell): boolean; coinAt(cell: HwCell): HwCoin | undefined; /** Seed the trigger coins and arm the counter. Idle → active. */ enter(seed: HwCoin[]): HwEffect[]; /** * Open a wave: validate the hits, mark every free cell as spinning, bump the * round. Returns the data the driver needs to emit `respin:start` and to land * each cell. Active → spinning. */ beginWave(hits: HwCoin[]): { round: number; spinning: HwCell[]; hitByKey: Map>; }; /** Record one cell's landing. `coin` is null on a miss. */ land(cell: HwCell, coin: HwCoin | null): HwEffect[]; /** Close the wave: resolve the counter, detect full / feature end. */ endWave(): { effects: HwEffect[]; landed: HwCoin[]; }; /** * Abandon an in-flight wave after a driver error: restore the phase from * `spinning` back to `active` so a thrown spin doesn't strand the board (every * later `beginWave` would otherwise throw "wave in flight"). Cells that already * landed stay locked; the caller decides whether to retry or `reset`. */ abortWave(): void; /** Remove locked coins - the collect moment. */ release(cells: HwCell[]): { effects: HwEffect[]; released: HwCoin[]; }; /** * Rewrite a **locked** cell's coin identity in place (coin → jackpot, mini → * major). Throws on a free cell - placing a brand-new tracked coin out of a * spin is `enter`/`respin`'s job; for purely decorative art on a free cell use * the cell's reel directly. */ swap(cell: HwCell, id: string, data: TData | undefined): void; /** Hard clear back to idle. Fires `feature:reset`, never `coin:released`. */ reset(): HwEffect[]; private _setRespins; /** * Store a coin with a board-owned, frozen `cell` so the ledger key can never * be corrupted by a game mutating the coin it was handed. `data` is left * mutable by reference - that is the supported way to carry live value. */ private _freeze; private _assertInGrid; } //# sourceMappingURL=HoldAndWinState.d.ts.map