Skip to content
abel0xPublic

About

Free, play-money blackjack that runs in your browser, even offline. Las Vegas, Atlantic City and European rules, a basic-strategy coach, and an installable PWA in English and Turkish. Vanilla JavaScript, no dependencies.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Table 21 🂡

Important

Disclaimer: Table 21 is a blackjack simulation made for entertainment and as a portfolio project. It uses play money only: there are no payments, deposits, withdrawals or prizes, and the chips have no cash value. It is not a gambling service, does not promote gambling and is not intended for any unlawful or harmful use. It is provided as is, without warranty, and the author accepts no liability for its use. Please read the full disclaimer.

A polished, fully static & offline blackjack simulation that uses play money only. No build step, no runtime dependencies, no network. Open and play.

Play Table 21 in your browser · Version 1.0.0 · GNU AGPL v3 · Tests

A hand in play on the Emerald table

Play

  • Online: open https://abel0x.github.io/table21/ and play. Install it from the browser menu (or Add to Home Screen on iOS) to keep a copy that works offline.
  • Locally: clone the repository and double‑click index.html. It works straight from file://, completely offline:
    git clone https://github.com/abel0x/table21.git
  • Local server, for PWA install and service‑worker offline caching:
    cd table21
    python3 -m http.server 8000   # or: npm run serve
    # open http://localhost:8000

Features

  • Three real table profiles: Las Vegas (6 decks, H17), Atlantic City (8 decks, S17 and late surrender), and European (6 decks, S17 and no hole card). Each preset changes dealing, peek, double, surrender, and split limits as one coherent ruleset; advanced deck/H17 edits are still available as a custom table.
  • Full action set: Hit, Stand, Double Down, Split, Surrender where permitted, Insurance, Even Money, and Rebet. Blackjack pays 3:2.
  • Truly random cards: a multi‑deck shoe shuffled with Fisher–Yates using crypto.getRandomValues (unbiased), reshuffled at 75% penetration or before the reserve becomes too small for a full round. Configurable 1/2/6/8 decks.
  • Three saved table themes: Emerald, Midnight, and Bordeaux each pair their own woven felt with a matching card back. The walnut/brass rail, authentic A–10 pip layouts, distinct mirrored Jack/Queen/King artwork, dealing shoe, discard tray, and anti-aliased vector clay chips are all rendered locally with HTML/CSS/SVG.
  • Physical table flow: cards leave the shoe, the hole card is exposed when the selected rules use one, and settled cards move into the discard tray. Every split hand owns an independent physical wager; doubled stakes visibly grow in place, losing stacks are collected separately, and each hand's winnings arrive as denomination-correct chips. The balance display changes when the chips move, not before.
  • Visible table conditions: a quiet plaque shows the table limits, number of decks, active S17/H17 dealer rule, and selected table profile. Short landscape layouts simplify or hide it to keep the cards and controls clear; the full rules remain available in settings.
  • Living table: restrained dealer status lines react to each hand, progressively growing high-limit chip piles remain readable at large values, and Fast, Normal, or Cinematic animation pacing is available.
  • Insurance, done right: the offer takes over the controls, not a checkbox and not a pop-up over the cards, so both hands stay readable while you decide.
  • Strategy coach: optional basic-strategy coaching for the active rules (1, 2 or 4+ decks, S17/H17, double after split, late surrender, no-hole-card European play). Feedback names the better play after a different one, Hints also marks it on the buttons, and the statistics track your strategy accuracy either way. Insurance and even money are always declined.
  • Table-true reading: live soft hands show both counts (7/17, a dealer Ace shows 1/11), the double-down card lies sideways (across the hand when three or four hands crowd the felt), and each round ends with one clear verdict badge carrying the net amount. Split hands keep compact tags with their own net result, and the rules plaque steps aside while they share the felt.
  • Sincere, rotating moments: bust out and the house re-stakes you with a different friendly line each time.
  • Professional local sound: eight bundled samples cover card slides, the hole-card flip, chips, payouts, and shuffling. Each ships as Ogg Vorbis and as an AAC (.m4a) twin for Safari versions that cannot play Ogg; the browser's canPlayType picks one. A restrained Web Audio fallback remains available. Master, card, chip, and table-effect levels can be adjusted independently and saved locally.
  • Bundled typography: the interface uses a locally packaged OFL-licensed WOFF2 family, with no font service or network dependency.
  • Internationalisation: English (primary) and Turkish, including felt rules, dialogs, card names for assistive technology, and number formatting. The chosen language is saved in the browser (localStorage) and restored on every visit.
  • Persistent bankroll, statistics (hands, wins, losses, pushes, blackjacks, win rate) and settings. Auto re‑stake when you bust out. Supporting browsers coordinate shared balances across tabs using Web Locks; without that API, each tab uses a separate session balance and displays a notice.
  • Unfinished hands survive: a reload, a crash or a closed tab resumes the same hand with the same cards and the stake still on the table (another tab picks it up on its next deal). Refreshing can neither refund a bad hand nor replay its cards; a snapshot that cannot be trusted voids the round and returns its stake.
  • Safe updates and amounts: PWA updates wait for an idle, unstaked table and do not force another open tab to reload. Amounts use whole dollars; fractional returns round down, as explained in settings. Wager limits reserve enough safe-integer headroom for settlement without reducing an existing valid balance.
  • Accessible & responsive: keyboard focus is contained in dialogs, zoom remains available, reduced-motion is respected, and narrow mobile layouts show only the controls relevant to the current phase.
  • Keyboard shortcuts: D deal/double · H hit · S stand · P split · X surrender · R rebet · C clear · Y/N insurance · Esc decline/close.

Privacy

Table 21 has no accounts, analytics, cookies or trackers, and it talks to no server beyond loading its own files. Settings, statistics, the play-money balance and any unfinished hand are kept in your browser's localStorage and never leave your device; clearing the site's data resets them. The online version is hosted on GitHub Pages, which may log visits as described in GitHub's privacy statement.

Verify

The core test suite uses only Node's built-in test runner (Node.js 22.12 or newer); there is nothing to install:

npm test                 # node --test "tests/*.test.js" "tests/*.test.cjs"

The suite currently executes 553 deterministic cases. It covers exhaustive hand and payout matrices, every basic-strategy chart cell and rule variation, split naturals, insurance, even money, surrender, table-profile rules, scalable chip layouts, active-sound behavior, translation parity, persistence boundaries, accessibility contracts, local asset references, DOM integrity, responsive safeguards, the complete service-worker app shell, the disclaimer and license notices, and earlier behavior regressions. GitHub Actions runs it on Node 22, 24 and 26 for every push and pull request.

The optional real-browser suite adds 163 Chromium tests, including file:// play, hands resumed after reloads and closed tabs, split-hand layouts from 320 px phones to desktop, offline PWA reloads, live updates, multiple tabs, keyboard use, language changes, and all 52 cards in both languages. Puppeteer is declared as a development-only dependency in package.json; the game itself never loads it:

npm install              # also downloads the Chrome build Puppeteer drives
npm run test:browser

Development

There is no build step: edit a file and reload the page. Whenever a change touches a file the game ships, bump CACHE_VERSION in sw.js so that installed copies pick up the new version; the update waits until the table is idle. tools/generate-audio.sh rebuilds the sound samples with ffmpeg.

Files

index.html                 markup + layout
css/styles.css             the complete Table 21 look
js/i18n.js                 translations (EN/TR) + persistence
js/sound.js                local sample playback + Web Audio fallback
js/engine.js               pure, dependency-free rules and payout engine
js/rules.js                table profiles and profile-specific action rules
js/chip-stack.js           scalable high-limit bet-pile model
js/strategy.js             pure basic-strategy charts for the coach
js/round.js                pure snapshot capture/validation for unfinished rounds
js/game.js                 game state, betting, rendering, and interactions
js/pwa.js                  optional service-worker registration and safe updates
manifest.json              installable PWA metadata
sw.js                      offline cache (only used when served over http)
icon.svg                   app icon (apple-touch-icon.png: iOS home-screen PNG)
assets/audio/              local card, chip, payout, and shuffle sounds (Ogg + AAC)
assets/fonts/              local WOFF2 interface font + OFL license
assets/icons/              PNG install icons (192, 512 and a maskable 512)
assets/social-preview.jpg  1200×630 link-preview image
tools/                     reproducible local audio generator
tests/                     dependency-free rules, strategy, behavior and offline integrity tests
tests/browser/             optional real-browser suite (Puppeteer, development only)
.github/workflows/         continuous integration for the core suite
package.json               test scripts + dev-only Puppeteer (not needed to play)
CHANGELOG.md               release notes
LICENSE                    GNU Affero General Public License v3

Disclaimer

Table 21 is a free blackjack simulation built for entertainment, for practising basic strategy and as a portfolio project.

  • Play money only. Chips and balances have no cash value. They cannot be bought, sold or exchanged for money or prizes, and Add play money only adds free chips.
  • Not gambling. Table 21 is not a gambling service, offers no real-money play, does not promote gambling and is not intended for any unlawful or harmful use.
  • No real-money advice. The strategy coach teaches textbook basic strategy for learning purposes. Neither the coach nor results in the game are a guide to real-money play.
  • Intended for adults. Like other simulated casino games, Table 21 is not aimed at minors.
  • No affiliation. Table 21 is not affiliated with any casino. The Las Vegas, Atlantic City and European profiles only describe common rule sets.
  • No warranty, no liability. The software is provided as is, without warranty of any kind, and the author accepts no liability for its use; see sections 15 and 16 of the license. You are responsible for complying with the laws that apply where you live.

If gambling is causing problems for you or someone close to you, please seek help.

License

Copyright (C) 2026 abel0x

Table 21 is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The bundled interface font is licensed separately under the SIL Open Font License 1.1 (assets/fonts/OFL.txt).

About

Free, play-money blackjack that runs in your browser, even offline. Las Vegas, Atlantic City and European rules, a basic-strategy coach, and an installable PWA in English and Turkish. Vanilla JavaScript, no dependencies.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages