diff --git a/JoshHeaps.Net/wwwroot/js/casino/holdem/potWizard.js b/JoshHeaps.Net/wwwroot/js/casino/holdem/potWizard.js index ab36c9a..d9307b4 100644 --- a/JoshHeaps.Net/wwwroot/js/casino/holdem/potWizard.js +++ b/JoshHeaps.Net/wwwroot/js/casino/holdem/potWizard.js @@ -18,6 +18,7 @@ const PotWizard = { this.playerLabelById = new Map( players.map(p => [p.id, this.labelFor(p, state.seats.indexOf(p))]) ); + this.seatIndexById = new Map(players.map(p => [p.id, state.seats.indexOf(p)])); const contributions = players.map(p => ({ id: p.id, contribution: HoldemState.computeContribution(p, state.chipLegend, state.basePotAmount), @@ -49,6 +50,20 @@ const PotWizard = { this.totals.set(id, (this.totals.get(id) || 0) + amount); }, + // A chopped pot rarely divides exactly, and the odd chip goes to the first player + // left of the button — not to whoever the dealer happened to tick first. The + // calculator hands leftovers out in the order it's given the winners, so ordering + // them here is what makes the payout match the rule. + orderFromButton(ids) { + const distance = new Map(); + for (let step = 1; step <= this.state.seatCount; step++) { + distance.set(HoldemState.nextSeatIndex(this.state, this.state.dealerSeatIndex, step), step); + } + return [...ids].sort((a, b) => + (distance.get(this.seatIndexById.get(a)) ?? 0) - (distance.get(this.seatIndexById.get(b)) ?? 0) + ); + }, + renderStep() { // Auto-resolve any round where only one player is left standing — nothing to ask. let contenders = PotCalculator.getContenders(this.entries); @@ -127,7 +142,7 @@ const PotWizard = { confirmBtn.addEventListener("click", () => { const selected = Array.from(choices.querySelectorAll("input:checked")).map(i => i.value); if (selected.length === 0) return; - const result = PotCalculator.resolveRound(this.entries, selected); + const result = PotCalculator.resolveRound(this.entries, this.orderFromButton(selected)); this.recordRound(result); this.entries = result.updatedEntries; this.renderStep();