npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bacc-ts

v1.0.0

Published

A fast and memory efficient Baccarat engine for calculating results, scoreboards, and related statistics.

Readme

bacc-ts

A fast and memory-efficient Baccarat engine for calculating results, scoreboards, and related statistics. TypeScript port of bacc-rs.

Features

  • Cactus Kev 32-bit card integer encoding for compact, fast card representation
  • Multi-deck shoe with configurable penetration, shuffle passes, and burn ritual
  • Full baccarat third-card rules (natural, player draw, banker draw table)
  • Round encoding: outcome, pair flags, third-card flags, and hand values packed into a single integer
  • Five standard scoreboards: bead plate, big road, Big Eye Boy, Small Road, Cockroach Pig
  • All scoreboards returned as bigint (big-endian byte stream) for compact serialization
  • BaccaratShoe implements the Iterable protocol -- use a for...of loop or call next() manually
  • Deterministic shoe construction via fromCards() for testing and simulation

Installation

npm install bacc-ts

Usage

Run a full shoe

import { BaccaratShoe, BaccaratScoreboard } from 'bacc-ts'

const shoe = BaccaratShoe.new(
    8,      // number of decks
    5,      // shuffle passes
    0.965,  // penetration (fraction of shoe dealt before cut card)
)

const scoreboard = new BaccaratScoreboard()

for (const round of shoe) {
    scoreboard.update(round)
}

console.log(scoreboard.beadPlate().toString(16))
console.log(scoreboard.bigRoad().toString(16))

const [bigEyeBoy, smallRoad, cockroachPig] = scoreboard.derivedRoads()

Inspect individual rounds

const shoe = BaccaratShoe.new(6, 3, 0.8)

let round = shoe.next()
while (round !== null) {
    const encoded = round.encode()
    const outcome = encoded & 0x3           // 1=player, 2=banker, 3=tie
    const playerPair = (encoded >>> 2) & 1
    const bankerPair = (encoded >>> 3) & 1
    const playerValue = (encoded >>> 8) & 0xf
    const bankerValue = (encoded >>> 12) & 0xf

    console.log({ outcome, playerPair, bankerPair, playerValue, bankerValue })
    console.log('player cards:', round.playerCards())
    console.log('banker cards:', round.bankerCards())

    // null if cut card not seen this round; index 0-5 if seen
    if (round.cutCardIndex() !== null) {
        console.log('cut card encountered at position', round.cutCardIndex())
    }

    round = shoe.next()
}

Deterministic shoe from a card list

Useful for unit tests or exact simulations. The array is dealt from the end (last element first). Exactly one null marks the cut card position.

import { BaccaratShoe, CardAs, CardKs, CardQs, CardJs, Card9s, Card8s } from 'bacc-ts'

// Layout: [stub..., null, ...cards dealt last->first]
// Dealt order: Card8s, Card9s, CardJs, CardQs, CardKs, CardAs
const shoe = BaccaratShoe.fromCards([
    null,
    Card8s, Card9s, CardJs, CardQs, CardKs, CardAs,
    Card8s, Card9s, CardJs, CardQs, CardKs, CardAs,
])

Low-level shoe access

import { Shoe, DECK, CardAs } from 'bacc-ts'

const shoe = Shoe.new(6)
shoe.shuffle(5)
shoe.cut(0.8)

console.log('stub size:', shoe.stubSize())

let card = shoe.deal()
while (card !== undefined) {
    if (card === null) console.log('cut card reached')
    else console.log('dealt:', card)
    card = shoe.deal()
}

Round encoding

BaccaratRound.encode() packs the round result into a single 32-bit integer:

| Bits | Field | Values | |-------|---------------------|-------------------------------| | 1-0 | Outcome | 1=player, 2=banker, 3=tie | | 2 | Player pair | 1=yes, 0=no | | 3 | Banker pair | 1=yes, 0=no | | 4 | Player drew third | 1=yes, 0=no | | 5 | Banker drew third | 1=yes, 0=no | | 11-8 | Player hand value | 0-9 | | 15-12 | Banker hand value | 0-9 |

Scoreboard encoding

All scoreboards are returned as bigint values where the oldest entry sits at the most significant byte. Pass them directly to a WASM layer or serialize with .toString(16).

  • Bead plate -- 2 bytes per round in chronological order.
  • Big road -- variable-width columns; each column is 2*rowCount+1 bytes.
  • Derived roads (Big Eye Boy, Small Road, Cockroach Pig) -- run-length encoded; each byte is (runLength << 1) | icon where icon 1=red, 0=blue.

License

LGPL-3.0-only