Work out who pays whom #64
Closed
jheaps
wants to merge 1 commits from
fix/casino-holdem-settle-up into fix/casino-holdem-allin-and-bar
pull from: fix/casino-holdem-settle-up
merge into: :fix/casino-holdem-allin-and-bar
:master
:feature/socialism
:polish/holdem-seats-one-size
:fix/holdem-dealer-chip-eats-its-seat
:polish/holdem-game-night-ready
:polish/holdem-round-next
:polish/holdem-seat-collisions
:polish/holdem-offline-and-render
:fix/naming-a-blind-deals-the-hand
:release/casino-holdem-polish
:fix/casino-holdem-phone-look
:fix/casino-holdem-sidebar-crowding
:fix/casino-holdem-contribution-rule
:fix/casino-holdem-one-stack-rule
:fix/casino-holdem-default-stack-buyin
:feat/casino-holdem-waiting-list
:feat/casino-holdem-misdeal
:feat/casino-holdem-cash-out
:feat/casino-holdem-clock
:feat/casino-holdem-rake
:fix/casino-holdem-stadium-ring
:fix/casino-holdem-phone-felt-shape
:fix/casino-holdem-audit-runs-everything
:feat/casino-holdem-straddle
:fix/casino-holdem-landscape-ring
:feat/casino-holdem-table-file
:fix/casino-holdem-touch-targets
:fix/casino-holdem-audit-modal-blindspot
:fix/casino-holdem-quicksplit-chop
:fix/casino-holdem-buildable-bet-sizes
:fix/casino-holdem-pot-sized-raise
:fix/casino-holdem-chips-to-count-out
:fix/casino-holdem-first-buy-in
:fix/casino-holdem-seating-a-table
:fix/casino-holdem-showdown-order
:fix/casino-holdem-hand-log-filter
:fix/casino-holdem-posting-in
:fix/casino-holdem-dead-button
:fix/casino-holdem-discarded-pot
:fix/casino-holdem-honest-tank-clock
:fix/casino-holdem-export-the-notes
:fix/casino-holdem-stacks-in-chips
:fix/casino-holdem-close-audit-blind-spots
:fix/casino-holdem-readable-dim-states
:fix/casino-holdem-drop-broken-watermark
:fix/casino-holdem-two-tabs
:fix/casino-holdem-unreadable-save
:fix/casino-holdem-say-when-not-saving
:fix/casino-holdem-shortcut-discovery
:fix/casino-holdem-rulings-index-compact
:fix/casino-holdem-rulings-index
:fix/casino-holdem-payout-in-chips
:fix/casino-holdem-move-seat-on-touch
:fix/casino-holdem-amount-fields-select
:fix/casino-holdem-touch-targets-by-pointer
:fix/casino-holdem-button-box-model
:fix/casino-holdem-blind-badge-placement
:fix/casino-holdem-buyin-deals-in
:fix/casino-holdem-bet-vs-raise
:fix/casino-holdem-deal-around-broke
:fix/casino-holdem-settle-up
:fix/casino-holdem-allin-and-bar
:fix/casino-holdem-one-dealer-button
:fix/casino-holdem-manual-deal
:fix/casino-holdem-less-guessing
:feature/casino-holdem-seat-editor
:fix/casino-holdem-landscape-table
:feature/casino-holdem-acting-seat
:feature/casino-holdem-raise-guard
:feature/casino-holdem-first-run
:feature/casino-holdem-contrast-audit
:feature/casino-holdem-layout-audit
:feature/casino-holdem-blind-fairness
:feature/casino-holdem-rulings-depth
:feature/casino-holdem-bank-audit
:feature/casino-holdem-fewer-taps
:feature/casino-holdem-render-perf
:feature/casino-holdem-keyboard-focus
:feature/casino-holdem-resilience
:feature/casino-holdem-messy-tables
:feature/casino-holdem-touch-mobile
:chore/casino-holdem-tech-debt
:feature/casino-holdem-dealer-batch
:feature/casino-holdem-seat-count-safety
:feature/casino-holdem-odd-chip
:feature/casino-holdem-button-moves
:feature/casino-holdem-allin-runout
:feature/casino-holdem-heads-up
:feature/casino-holdem-contrast
:feature/casino-holdem-touch-audit
:feature/casino-holdem-wizard-polish
:feature/casino-quicksplit-side-pots
:feature/casino-holdem-rebuys
:feature/casino-holdem-rulings
:feature/casino-holdem-sidebar-polish
:feature/casino-holdem-keyboard
:feature/casino-holdem-action-undo
:feature/casino-holdem-pace
:feature/casino-holdem-side-pot-breakdown
:feature/casino-holdem-gestures
:feature/casino-holdem-card-picker
:feature/casino-holdem-live-betting
:feature/casino-holdem-bet-chips
:feature/casino-holdem-seat-legibility
:feature/casino-holdem-undo-toasts
:feature/casino-holdem-quick-split
:feature/casino-holdem-mobile-table
:feature/casino-holdem-hand-history
:feature/casino-texas-holdem
:feature/casino-holdem-dealer-mode-polish
:feature/fractional-learned-weights
:fix/stockfish-dispose-hang
:fix/blog-cache-staleness
:fix/workflows
:gitea/workflows
:echo-acoustic-ranging
:chess-ui-overhaul
:feature/customChessEngine
:feature/blog
:AddProject
:feature/generalUpdate
:tech-debt/chess-cleanup
:tests/CreatePlaywrightTests
:UpdateParticleSimulatorButton
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
I went looking for what home-game dealers actually struggle with rather than reading the code again, and the answer that kept coming up was the end of the night: hosts reach for a separate app to finish a game "knowing exactly who owes whom in seconds rather than minutes". Stacked on #63.
This tool already had every number that answer needs. The standings panel knows what each player is up or down — chips in front of them less the cash they handed over — and then stops. Which leaves the dealer with six signed numbers at 2am and the actual job still to do. That last step is the part people get wrong, not the poker.
Largest debt against largest win, repeatedly. Greedy rather than optimal, which is the right trade here: the true minimum number of transfers is NP-hard, while this needs at most one payment fewer than there are people and each one it emits clears somebody out of the list entirely. A dealer wants a short list to read down, not a proof. Payers are the outer loop so everything one person owes prints together — the list gets read out one player at a time.
All of it in integer cents. A settlement that has to come out exactly right is the last place to let a float land on 41.99999999.
When the chips on the table don't match the cash taken
Then the payments can't all be made, and that is reported rather than quietly spread across them. It is never rounding — the arithmetic is integer cents — so it is always what the bank check sitting directly above it is already warning about: a rebuy nobody wrote down, or a miscount. Inventing a transfer to make the columns agree is how a real person ends up short.
The payment list goes into the CSV export too, under the standings it came from, with the caveat if there is one. Whoever opens that file wants the answer, not to redo the arithmetic in a spreadsheet.
Validation
13 tests (185 total): everyone ends up square, at most n−1 payments, a payer's lines stay together, cents survive, nobody pays themselves, no payment is ever for zero, both directions of an unbalanced bank, and one that settles a real table's standings rather than hand-made numbers.
Driven through the UI at six viewports, balanced and not: clean layout audit and contrast everywhere except the landscape phone already documented in #63. Verified the panel follows a stack edit live, and checked with 26-character names and seven-figure stacks on a 360px screen — names wrap, amounts stay whole and right-aligned, nothing overflows.
Sources: Poker Chip Forum — dealing at home games, Chips of Fury — house rules to keep the game moving, PokerTally
I went looking for what home-game dealers actually struggle with rather than reading the code again, and the answer that kept coming up was the end of the night: hosts reach for a separate app to finish a game "knowing exactly who owes whom in seconds rather than minutes". This tool already had every number that answer needs. The standings panel knows what each player is up or down -- chips in front of them less the cash they handed over -- and then stops. Which leaves the dealer with six signed numbers at 2am and the actual job still to do. That last step is the part people get wrong, not the poker. Ann +$75 Dee +$110 Fay -> Dee $70 Ben -$10 Eve -$40 Cal -> Dee $40 Cal -$65 Fay -$70 Cal -> Ann $25 Eve -> Ann $40 Ben -> Ann $10 Largest debt against largest win, repeatedly. Greedy rather than optimal, which is the right trade here: the true minimum number of transfers is NP-hard, while this needs at most one payment fewer than there are people and each one it emits clears somebody out of the list entirely. A dealer wants a short list to read down, not a proof. Payers are the outer loop so everything one person owes prints together -- the list gets read out one player at a time. All of it in integer cents. A settlement that has to come out exactly right is the last place to let a float land on 41.99999999. When the chips on the table don't match the cash taken Then the payments can't all be made, and that is reported rather than quietly spread across them. It is never rounding -- the arithmetic is integer cents -- so it is always what the bank check sitting right above it is already warning about: a rebuy nobody wrote down, or a miscount. Inventing a transfer to make the columns agree is how a real person ends up short. $100 of winnings has nothing to pay it -- there are more chips on the table than cash was taken for. Fix that above before anyone cashes out. The payment list goes into the CSV export too, under the standings it came from, with the caveat if there is one. Whoever opens that file wants the answer, not to redo the arithmetic in a spreadsheet. 13 tests (185 total): everyone ends up square, at most n-1 payments, a payer's lines stay together, cents survive, nobody pays themselves, no payment is ever for zero, both directions of an unbalanced bank, and one that settles a real table's standings rather than hand-made numbers. Driven through the UI at six viewports, balanced and not: clean layout audit and contrast everywhere but the landscape phone already known from #63. Checked with 26-character names and seven-figure stacks on a 360px screen -- names wrap, amounts stay whole and right-aligned, nothing overflows. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgbPull request closed