The pack
blackjack
function blackjack(): Pack<{ blackjack: typeof rules }>
Install headless Blackjack rules; compose cards for deck operations and presentation.
Helpers
blackjackHint
function blackjackHint(view: BlackjackObservation): { action: BlackjackAction | null; reason: string; method: 'visible-heuristic' }
Basic-strategy-style advice using only the player hand and dealer upcard. Named rules vary; this is a heuristic.
blackjackTotal
function blackjackTotal(cards: readonly Pick<Card, 'rank'>[], split = false): BlackjackTotal
Compute ace-adjusted Blackjack totals without reading any private game state.
createBlackjack
function createBlackjack(options: BlackjackOptions = {}): BlackjackGame
Create a quick seeded Blackjack session.
Classes
BlackjackGame
class BlackjackGame
A single player against a deterministic dealer, with explicit house rules and atomic commands. The session 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: BlackjackOptions = {})observation(): BlackjackObservation— Read-only player view; use this for hints and computer play.legalActions(): BlackjackAction['kind'][]— Available verbs. Use preview for a specific bet amount.preview(action: BlackjackAction): { ok: true } | { ok: false; reason: string }— Explain legality without mutating state or consuming randomness.apply(action: BlackjackAction): BlackjackResult— Apply one command atomically. The dealer completes its rule-defined turn automatically.snapshot(): BlackjackSnapshot— Serializable, bounded command replay; never expose this privileged seed to advice code.restore(snapshot: BlackjackSnapshot): void— Reconstruct every accepted action instead of trusting edited balances, cards or phase fields.hint(): ReturnType<typeof blackjackHint>— Visible-information heuristic; no claim of perfect play or guaranteed wins.
Types
BlackjackAction
type BlackjackAction = { kind: 'bet'; amount: number } | { kind: 'hit' | 'stand' | 'double' | 'split' | 'surrender' | 'insure' | 'decline-insurance' }
Named round actions. Bets use even integer chips so 3:2 and half-bets stay exact.
BlackjackEvent
type BlackjackEvent = { kind: 'deal'; owner: 'dealer' | 'player'; hand: number; card: Card | null } | { kind: 'reveal'; card: Card } | { kind: 'action'; action: BlackjackAction['kind']; hand: number } | { kind: 'settled'; bankroll: number }
Public event stream, with no unrevealed card values.
BlackjackHand
interface BlackjackHand
A publicly visible player hand.
cards: Card[]— Cards owned by this hand.bet: number— Wager already debited from the bankroll.split: boolean— Split-origin hands never receive natural payouts.splitAces: boolean— Whether split aces are locked to one extra card.status: 'playing' | 'stood' | 'bust' | 'surrendered'— Action state.outcome: '' | 'win' | 'loss' | 'push' | 'blackjack' | 'surrender'— Final outcome, empty until settlement.paid: number— Total chips returned at settlement, including the wager.
BlackjackObservation
interface BlackjackObservation
The complete player/bot view: hidden hole cards are null, and shoe order/seed are absent.
phase: 'betting' | 'insurance' | 'player' | 'settled'— Current round phase.bankroll: number— Available chips.dealer: (Card | null)[]— Dealer cards with an unrevealed hole represented by null.hands: BlackjackHand[]— Player hands.active: number— Current hand index.round: number— Number of started rounds.shoeRemaining: number— Undealt cards; no identities or order.discardCount: number— Previously discarded cards, for conservation diagnostics.insuranceBet: number— Insurance wager already debited.insurancePaid: number— Insurance chips returned.rules: Omit<Required<BlackjackOptions>, 'seed'>— Applied house rules, excluding hidden seed.legal: BlackjackAction['kind'][]— Non-bet actions currently legal.
BlackjackOptions
interface BlackjackOptions
Supported US hole-card/peek rules. All chips are play money.
seed?: number— Unsigned 32-bit seed.decks?: number— One to eight standard decks; default six.bankroll?: number— Starting chips; default 200.hitSoft17?: boolean— Hit soft 17 rather than stand; default false.doubleAfterSplit?: boolean— Permit doubling a split hand; default true.maxHands?: number— Two to four simultaneous hands; default four.insurance?: boolean— Offer half-bet insurance against an ace; default true.surrender?: boolean— Permit late surrender on the original two-card hand; default false.
BlackjackResult
type BlackjackResult = { ok: true; events: BlackjackEvent[] } | { ok: false; reason: string }
Transactional action result.
BlackjackSnapshot
interface BlackjackSnapshot
Replay/save format; privileged because its seed can reconstruct the shoe.
version: 1— Format version.options: Required<BlackjackOptions>— Original session settings.actions: BlackjackAction[]— Accepted commands from session start.
BlackjackTotal
interface BlackjackTotal
Ace-aware totals. A natural requires an original, unsplit two-card hand.
total: number— Highest legal total, or the minimum bust total.soft: boolean— An ace still counts as eleven.bust: boolean— Total exceeds 21.natural: boolean— Two-card 21, optionally suppressed for split hands.


