aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/blackjack.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/blackjack.go')
-rw-r--r--internal/casino/blackjack.go56
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)
+}