diff options
Diffstat (limited to 'internal/casino/blackjack.go')
| -rw-r--r-- | internal/casino/blackjack.go | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/internal/casino/blackjack.go b/internal/casino/blackjack.go index 4901c31..7c01c34 100644 --- a/internal/casino/blackjack.go +++ b/internal/casino/blackjack.go @@ -2,7 +2,6 @@ package casino import ( "fmt" - "math" "math/rand" "strings" "sync" @@ -147,9 +146,9 @@ func (t *blackjackTable) bet(name, spot string, amount int, wallet Wallet) []Eve if amount < t.Config.MinBet || amount > t.Config.MaxBet { return []Event{t.private(name, fmt.Sprintf("Blackjack bets must be %s.", betRangeText(t.Config.MinBet, t.Config.MaxBet)))} } - wager, ok := wallet.Wager(amount) - if !ok { - return []Event{t.private(name, "You don't have enough chips and credits for that bet.")} + wager, err := wallet.Wager(amount) + if err != nil { + return []Event{t.private(name, walletErrorMessage(err))} } p.HasBet, p.Wager, p.Wallet, p.lastBet = true, wager, wallet, amount events := []Event{t.playerAction(name, fmt.Sprintf("%s bets %d credits.", name, amount), fmt.Sprintf("You bet %d credits.", amount))} @@ -263,8 +262,8 @@ func (t *blackjackTable) action(name, action string) []Event { if len(hand.cards) != 2 || hand.doubled || hand.surrendered || fromSplitAces(hand) || (hand.fromSplit && !t.Rules.AllowsDoubleAfterSplit()) { return []Event{t.private(name, "You can only double a qualifying hand.")} } - if _, ok := p.Wallet.Wager(hand.bet); !ok { - return []Event{t.private(name, "You don't have enough chips and credits to double that hand.")} + if _, err := p.Wallet.Wager(hand.bet); err != nil { + return []Event{t.private(name, walletErrorMessage(err, "You don't have enough chips and credits to double that hand."))} } hand.bet *= 2 hand.doubled = true @@ -305,8 +304,8 @@ func (t *blackjackTable) insuranceAction(name, action string) []Event { if amount <= 0 { return []Event{t.private(name, "Your bet is too small to insure.")} } - if _, ok := p.Wallet.Wager(amount); !ok { - return []Event{t.private(name, "You don't have enough chips and credits for insurance.")} + if _, err := p.Wallet.Wager(amount); err != nil { + return []Event{t.private(name, walletErrorMessage(err, "You don't have enough chips and credits for insurance."))} } p.insurance = amount events = append(events, t.playerAction(name, fmt.Sprintf("%s takes insurance.", name), fmt.Sprintf("You place %d credits on insurance.", amount))) @@ -351,8 +350,8 @@ func (t *blackjackTable) splitHand(name string, p *blackjackPlayer, hand *blackj if hand.cards[0].rank == "A" && hand.fromSplit && !t.Rules.AllowsResplitAces() { return []Event{t.private(name, "Aces cannot be re-split at this table.")} } - if _, ok := p.Wallet.Wager(hand.bet); !ok { - return []Event{t.private(name, "You don't have enough chips and credits to split that hand.")} + if _, err := p.Wallet.Wager(hand.bet); err != nil { + return []Event{t.private(name, walletErrorMessage(err, "You don't have enough chips and credits to split that hand."))} } left := &blackjackHand{cards: []card{hand.cards[0]}, bet: hand.bet, fromSplit: true} right := &blackjackHand{cards: []card{hand.cards[1]}, bet: hand.bet, fromSplit: true} @@ -560,7 +559,7 @@ func (t *blackjackTable) settle() []Event { if p.insurance > 0 { insurancePayout := 0 if dealerBlackjack { - insurancePayout = int(math.Floor(float64(p.insurance) * (1 + t.Rules.InsurancePayout))) + insurancePayout, _ = MulPayout(p.insurance, 1+t.Rules.InsurancePayout) } if insurancePayout > 0 { p.Wallet.PayCredits(insurancePayout) @@ -594,7 +593,8 @@ func settleHand(hand *blackjackHand, dealerTotal int, dealerBlackjack bool, rule } if playerBlackjack { // Winnings round down to whole credits; never bet less than two. - return "blackjack", hand.bet + int(math.Floor(float64(hand.bet)*rules.BlackjackPayout)) + blackjackWin, _ := MulPayout(hand.bet, rules.BlackjackPayout) + return "blackjack", hand.bet + blackjackWin } if total > 21 || dealerTotal > total && dealerTotal <= 21 { return "loss", 0 @@ -728,3 +728,35 @@ func (t *blackjackTable) hasParticipant(name string) bool { defer t.mu.Unlock() return t.players.has(name) } + +// refundAll resolves every committed wager at this table (graceful +// shutdown): stakes return to their players through the wallet. +func (t *blackjackTable) refundAll() []Event { + t.mu.Lock() + defer t.mu.Unlock() + var events []Event + for _, p := range t.players.ordered() { + if !p.HasBet || p.Wallet == nil { + continue + } + name, refund := p.Name, p.Wager.Total + if refund <= 0 { + continue + } + if err := p.Wallet.PayCredits(refund); err != nil { + events = append(events, t.private(name, "Shutdown refund could not be persisted; the stake is recorded for recovery.")) + continue + } + events = append(events, t.playerAction(name, + fmt.Sprintf("%s is refunded %d credits as the casino closes.", name, refund), + fmt.Sprintf("The house refunds your %d credit stake for the shutdown.", refund))) + } + return events +} + +// setRoom updates the event-routing room after a room-ID rekey. Locked. +func (t *blackjackTable) setRoom(roomID int) { + t.mu.Lock() + defer t.mu.Unlock() + t.tableBase.setRoom(roomID) +} |
