Fix four rules and modelling defects found in review
TDA Rule 47 — cumulative incomplete raises: A boolean could not express "facing at least a full raise since acting", so several short all-ins that together reached a full raise failed to reopen betting. Seat now records lastActedAtBet (the currentBet when it last acted); mayRaise() reopens when currentBet - lastActedAtBet >= minRaiseSize. This subsumes the single-incomplete-raise case, so the hasActed reset in apply() is gone. TDA Rule 20 — odd chips: Split-pot remainders were awarded in seat-list order. They now go to the first winning seat clockwise from the button. The old test also never produced an odd pot (20 chips heads-up), so it only ever proved an even split; it now builds a genuinely odd 25-chip pot via a folded small blind and asserts which seat takes the extra chip. OpponentModel skipped events across hands: It inferred a new hand from a shrinking history, but history is cleared each hand: having consumed 3 events, first observing the next hand at 4 events left 4 < 3 false and silently dropped the first three. observe() now takes an explicit handNumber, exposed via DecisionContext and Table.handNumber. PreflopChart percentile semantics: The 169 classes were ranked equally, but they are not equally likely — a pair is 6 of 1326 combinations, suited 4, offsuit 12. "Top 12%" therefore meant 12% of classes, not of dealt hands, so looseness did not mean what it claimed. Percentiles are now weighted by combination count. Tests: 30 -> 37. Each new test was verified to fail with its fix reverted. Skill gradient still monotonic: 85.9 / 79.8 / 17.4 / -183.1 bb/100 over 50k hands, chips conserved on both tables. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -56,10 +56,24 @@ export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
|
||||
|
||||
- Evaluator: verified exhaustively against published frequencies for all
|
||||
2,598,960 five-card hands. ~24M evals/sec.
|
||||
- Engine: chip-conserving; side pots, odd-chip splits, uncalled-bet refunds, and
|
||||
incomplete (short all-in) raises all covered by tests.
|
||||
- Bots: skill gradient **passes** monotonically (73.9 / 53.9 / 27.6 / −155.4
|
||||
- Engine: chip-conserving. Covered by tests: side pots, uncalled-bet refunds,
|
||||
action order, malformed agent output, **TDA Rule 47** (incomplete raises do not
|
||||
reopen betting, but several that cumulatively reach a full raise do), and
|
||||
**TDA Rule 20** (odd chip to the first winner left of the button).
|
||||
- Bots: skill gradient **passes** monotonically (85.9 / 79.8 / 17.4 / −183.1
|
||||
bb/100 at 50k hands).
|
||||
|
||||
### Rules invariants that are easy to get wrong
|
||||
|
||||
- Reopening betting cannot be a boolean. `Seat.lastActedAtBet` records the bet
|
||||
level a player last acted at; betting reopens when `currentBet - lastActedAtBet
|
||||
>= minRaiseSize`. Several short all-ins can reach that together.
|
||||
- `PreflopChart` percentiles are weighted by **combination counts** (pair 6,
|
||||
suited 4, offsuit 12, total 1326), so "top 12%" means 12% of *dealt hands*, not
|
||||
12% of the 169 classes.
|
||||
- Anything consuming `DecisionContext.history` across hands must key off
|
||||
`handNumber`. History is cleared each hand, so a size comparison silently drops
|
||||
events.
|
||||
- Known-imperfect: win-rate magnitudes are still ~10x realistic, and several
|
||||
profiles are looser than their labels (the Rock plays ~38% VPIP, should be
|
||||
~12%). Tuning is the open work.
|
||||
|
||||
Reference in New Issue
Block a user