Went looking at dealer procedure again and ended up checking the rule home games argue about longest. The tool had it wrong. Blinds 1/2. Seat 4 raises to 10 — a full raise of 8. Seat 1 calls. Seat 2 is all-in for 13: three more, where a full raise would need eight. Under TDA rule 44 that does not reopen the betting to anyone who has already acted; they owe the extra three or they fold. Seat 1 and seat 4 were both being handed another go. Two things were wrong in raiseTo. Any increase at all reset hasActed for every live player, so a short shove gave the whole table another chance to raise. And lastRaiseSize was overwritten with the short amount, so the next legal raise was computed off 3 instead of 8 and came out too small — a second, quieter error that only shows up when somebody then tries to raise. Both now key off whether the increase was actually a full raise. A player who had not yet acted keeps full rights, which falls out naturally because their hasActed is already false — that distinction is the part of the rule people get wrong in the other direction. Everyone still owes the difference: isStreetComplete already asks anyone with chips left to call, so the short all-in is answered without being re-raiseable. The rulings sheet now covers what the tool does for you It had three entries. A dealer challenged on a payout couldn't look up why the tool did what it did, even for the rules it enforces automatically. Added the short all-in rule above, uncalled chips coming back rather than being announced as a side pot, and the odd chip in a chopped pot going to the first player left of the button — all three are things this tool already decides silently, and all three are worth being able to point at when somebody objects. 10 tests (137 total): already-acted players aren't reopened but still owe the difference, a player yet to act keeps full rights, the minimum raise isn't shrunk, calling it ends the street, no chips are created, and — the other half of the rule — a full-sized all-in, an ordinary raise, a raise exactly matching the last one, and a full-sized opening bet all still reopen everyone. Validated through the real action bar: after the short shove, lastRaiseSize stays 8 and the player who had already called stays settled, while the two who hadn't acted keep their turn. The longer rulings sheet still fits a phone, scrolls, traps focus and closes on Escape. Sources: TDA rules via thelodgepokerclub.com/tda-rules/, pokernews.com/strategy/deal-with-it-tips-for-mistake-free-dealing-in-home-games-30231.htm Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
Hold'em dealer tests
Unit tests for the money logic behind /Casino/TexasHoldem — the betting engine, the
side-pot calculator, the split calculator and the table state.
node --test tests/holdem/*.test.js
No install step, no package.json, no dependencies. The browser modules are plain
script-tag files that each end with a module.exports guard, so Node can require them
as-is; load.js puts them on globalThis under the same names they use to find each
other in the page, in the load order from TexasHoldem.cshtml.
What's covered
| File | Covers |
|---|---|
potCalculator.test.js |
Main and side pots, dead money, uncalled bets, odd-cent distribution |
betting.test.js |
Blinds, street completion, raises reopening the action, all-in run-outs |
state.test.js |
Button rotation, which seats post blinds, session standings |
splitCalculator.test.js |
Chopped pots, odd chips, unmakeable denominations |
invariants.test.js |
1000 randomised hands per property (see below) |
Why the randomised suite exists
Every correctness bug found in this tool so far has been shape-dependent: blinds posted to empty chairs, the button skipping past players, heads-up acting out of order, an overbet announced as a side pot. None of them show up on a full six-handed table with equal stacks, which is the table anyone writes a fixed example for.
invariants.test.js deals a thousand hands across random seat counts, random empty
chairs, random stack depths and random dealer input, and checks the things a dealer
would notice being wrong:
- chips are never created or destroyed during play
- the pot breakdown plus the uncalled returns always equal the money that went in
- paying the pot out settles it to the cent
- once uncalled chips are handed back, nobody is still betting above the whole table
- the button and both blinds always land on players who are actually in the hand
The generator is seeded, so a failure reproduces from the seed printed in the message rather than being a flake to re-run.