diff options
Diffstat (limited to 'internal/casino/blackjack.go')
| -rw-r--r-- | internal/casino/blackjack.go | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/internal/casino/blackjack.go b/internal/casino/blackjack.go index 16a480c..fd0572b 100644 --- a/internal/casino/blackjack.go +++ b/internal/casino/blackjack.go @@ -618,7 +618,16 @@ func (t *blackjackTable) settle() []Event { } payoutFailed := false for _, hand := range p.hands { - result, payout := settleHand(hand, dealerTotal, dealerBlackjack, t.Rules) + result, payout, settleErr := settleHand(hand, dealerTotal, dealerBlackjack, t.Rules) + if settleErr != nil { + // A payout multiplier that overflows the credit cap is a + // configuration defect, not a payable win. Treat it like a + // failed settlement so the stake stays open for recovery to + // refund rather than paying a clamped/absurd amount. + payoutFailed = true + events = append(events, t.playerAction(p.Name, "Settlement unavailable.", payoutFailedMessage())) + continue + } if payout > 0 && p.Wallet != nil { if err := p.Wallet.PayStakeCover(payout, hand.stakes); err != nil { // The payout could not be made durable. The journal @@ -658,10 +667,17 @@ func (t *blackjackTable) settle() []Event { } if p.insurance > 0 { insurancePayout := 0 + var insuranceErr error if dealerBlackjack { - insurancePayout, _ = MulPayout(p.insurance, 1+t.Rules.InsurancePayout) + insurancePayout, insuranceErr = MulPayout(p.insurance, 1+t.Rules.InsurancePayout) } - if insurancePayout > 0 { + switch { + case insuranceErr != nil: + // Overflow is a config defect: leave the insurance stake open + // for recovery to refund instead of paying a clamped amount. + payoutFailed = true + events = append(events, t.private(p.Name, payoutFailedMessage())) + case insurancePayout > 0: if err := p.Wallet.PayStakeCover(insurancePayout, []string{p.insuranceStakeID}); err != nil { payoutFailed = true events = append(events, t.private(p.Name, payoutFailedMessage())) @@ -669,7 +685,7 @@ func (t *blackjackTable) settle() []Event { p.Wallet.ResolveStake(p.insuranceStakeID) events = append(events, t.private(p.Name, fmt.Sprintf("Insurance pays %d credits.", insurancePayout))) } - } else { + default: // Insurance lost: its stake was consumed by the rules. p.Wallet.ResolveStake(p.insuranceStakeID) events = append(events, t.private(p.Name, "Insurance pays 0 credits.")) @@ -690,36 +706,36 @@ func (t *blackjackTable) settle() []Event { return events } -func settleHand(hand *blackjackHand, dealerTotal int, dealerBlackjack bool, rules BlackjackConfig) (string, int) { +func settleHand(hand *blackjackHand, dealerTotal int, dealerBlackjack bool, rules BlackjackConfig) (string, int, error) { total, _ := hand.total() if hand.surrendered { - return "surrender", hand.bet / 2 + return "surrender", hand.bet / 2, nil } if hand.bust { - return "bust", 0 + return "bust", 0, nil } playerBlackjack := hand.blackjack(rules) if playerBlackjack && dealerBlackjack { - return "push", hand.bet + return "push", hand.bet, nil } if dealerBlackjack { - return "dealer blackjack", 0 + return "dealer blackjack", 0, nil } if playerBlackjack { // Winnings round down to whole credits; never bet less than two. - blackjackWin, _ := MulPayout(hand.bet, rules.BlackjackPayout) - return "blackjack", hand.bet + blackjackWin + blackjackWin, err := MulPayout(hand.bet, rules.BlackjackPayout) + if err != nil { + return "blackjack", 0, err + } + return "blackjack", hand.bet + blackjackWin, nil } if total > 21 || dealerTotal > total && dealerTotal <= 21 { - return "loss", 0 + return "loss", 0, nil } if dealerTotal == total { - return "push", hand.bet - } - if dealerTotal > 21 { - return "win", hand.bet * 2 + return "push", hand.bet, nil } - return "win", hand.bet * 2 + return "win", hand.bet * 2, nil } func (t *blackjackTable) resetRound() { |
