diff options
| author | historia <[not public]> | 2026-08-03 16:42:59 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-08-03 16:42:59 -0400 |
| commit | adda27dba5bf7bf1dee62159f0cbc0bd90734751 (patch) | |
| tree | 2a68c0bad42c3561cfcd7a32eee52f7ff7eb14f9 /internal/casino | |
| parent | fe15f2ffeb5685b056650a61aa0e23965ef51e95 (diff) | |
| download | thehouseoficarus-adda27dba5bf7bf1dee62159f0cbc0bd90734751.tar.gz | |
fix: blackjack game formatting
Diffstat (limited to 'internal/casino')
| -rw-r--r-- | internal/casino/blackjack.go | 6 | ||||
| -rw-r--r-- | internal/casino/blackjack_test.go | 25 | ||||
| -rw-r--r-- | internal/casino/machine.go | 20 | ||||
| -rw-r--r-- | internal/casino/manager.go | 4 | ||||
| -rw-r--r-- | internal/casino/manager_test.go | 7 |
5 files changed, 48 insertions, 14 deletions
diff --git a/internal/casino/blackjack.go b/internal/casino/blackjack.go index 80a4d15..ff334c9 100644 --- a/internal/casino/blackjack.go +++ b/internal/casino/blackjack.go @@ -399,7 +399,7 @@ func (t *blackjackTable) startRound() []Event { p.declinedInsurance = true } } - roundEvent := t.event("New blackjack hand!", true) + roundEvent := t.event("", true) roundEvent.Blackjack = t.snapshot(false) events := []Event{roundEvent} if t.dealer.cards[1].rank == "A" { @@ -528,7 +528,7 @@ func (t *blackjackTable) settle() []Event { t.dealer.cards = append(t.dealer.cards, t.shoe.draw()) } dealerTotal, _ := t.dealer.total() - dealerEvent := t.event("Dealer's hand:", true) + dealerEvent := t.event("", true) dealerEvent.Blackjack = t.snapshot(true) events := []Event{dealerEvent} dealerBlackjack := t.dealerBlackjack() @@ -662,7 +662,7 @@ func (t *blackjackTable) menu() string { func handScore(hand *blackjackHand) string { total, soft := hand.total() - if !soft { + if !soft || total == 21 { return fmt.Sprintf("%d", total) } return fmt.Sprintf("%d or %d", total-10, total) diff --git a/internal/casino/blackjack_test.go b/internal/casino/blackjack_test.go index f1bef99..89b5d06 100644 --- a/internal/casino/blackjack_test.go +++ b/internal/casino/blackjack_test.go @@ -19,6 +19,18 @@ func TestBlackjackHandTreatsAceAsElevenWhenPossible(t *testing.T) { } } +func TestBlackjackHandScoreShowsBlackjackAs21(t *testing.T) { + if got := handScore(&blackjackHand{cards: []card{{rank: "A"}, {rank: "K"}}}); got != "21" { + t.Fatalf("blackjack score=%q, want 21", got) + } + if got := handScore(&blackjackHand{cards: []card{{rank: "A"}, {rank: "6"}}}); got != "7 or 17" { + t.Fatalf("soft 17 score=%q, want 7 or 17", got) + } + if got := handScore(&blackjackHand{cards: []card{{rank: "10"}, {rank: "8"}}}); got != "18" { + t.Fatalf("hard 18 score=%q, want 18", got) + } +} + func TestBlackjackSettlementRules(t *testing.T) { rules := (BlackjackConfig{}).Normalize() natural := &blackjackHand{bet: 10, cards: []card{{rank: "A"}, {rank: "K"}}} @@ -46,7 +58,7 @@ func TestBlackjackTableStartsAfterAllPlayersBet(t *testing.T) { t.Fatal("round started before all players bet") } events := table.bet("bob", "", 10, wb) - if !hasMessage(events, "New blackjack hand") { + if !hasSnapshot(events) { t.Fatalf("round did not start after all players bet: %+v", events) } } @@ -197,7 +209,7 @@ func TestBlackjackBettingIgnoresDisconnected(t *testing.T) { table.markDisconnected("bob") w := &testWallet{credits: 100} events := table.bet("alice", "", 10, w) - if !hasMessage(events, "New blackjack hand") { + if !hasSnapshot(events) { t.Fatalf("disconnected player stalled the round: %+v", events) } } @@ -226,6 +238,15 @@ func hasMessage(events []Event, fragment string) bool { return false } +func hasSnapshot(events []Event) bool { + for _, event := range events { + if event.Blackjack != nil { + return true + } + } + return false +} + func contains(value, fragment string) bool { return strings.Contains(value, fragment) } diff --git a/internal/casino/machine.go b/internal/casino/machine.go index 887e154..0ee4cde 100644 --- a/internal/casino/machine.go +++ b/internal/casino/machine.go @@ -64,7 +64,7 @@ func (m *Machine) join(name string) []Event { return m.menuEvents("You resume your place at the slot machine.") } -func (m *Machine) setBet(name string, amount int) []Event { +func (m *Machine) setBet(name string, amount int, wallet Wallet) []Event { m.mu.Lock() defer m.mu.Unlock() if !m.owns(name) { @@ -79,8 +79,9 @@ func (m *Machine) setBet(name string, amount int) []Event { if amount < m.Config.MinBet || amount > m.Config.MaxBet { return m.private(fmt.Sprintf("Slot machine bets must be between %d and %d.", m.Config.MinBet, m.Config.MaxBet)) } - m.bet = amount - return m.menuEvents(fmt.Sprintf("Your slot machine bet is set to %d.", amount)) + return m.beginSpinLocked(name, amount, wallet, + fmt.Sprintf("%s sets the bet to %d and pulls the lever.", name, amount), + fmt.Sprintf("Bet set to %d. You pull the lever on the slots machine.", amount)) } func (m *Machine) start(name string, wallet Wallet) []Event { @@ -98,15 +99,22 @@ func (m *Machine) start(name string, wallet Wallet) []Event { if m.bet <= 0 { return m.private("Set a wager first with 'bet <amount>'.") } - if _, ok := wallet.Wager(m.bet); !ok { + return m.beginSpinLocked(name, m.bet, wallet, + fmt.Sprintf("%s pulls the lever on the slots machine.", name), + "You pull the lever on the slots machine.") +} + +func (m *Machine) beginSpinLocked(name string, amount int, wallet Wallet, publicMessage, privateMessage string) []Event { + if _, ok := wallet.Wager(amount); !ok { return m.private("You don't have enough chips and credits for that bet.") } - m.spinBet = m.bet + m.bet = amount + m.spinBet = amount m.player.Wallet = wallet m.spin = generateSlotSpinWithProfile(m.rng, m.spinBet, m.profile) m.reel, m.clock, m.suspense = 0, 0, false m.phase = machineSpinning - return m.playerAction(fmt.Sprintf("%s pulls the lever on the slots machine.", name), "You pull the lever on the slots machine.") + return m.playerAction(publicMessage, privateMessage) } func (m *Machine) enableAutoBet(name string, wallet Wallet) []Event { diff --git a/internal/casino/manager.go b/internal/casino/manager.go index c876226..60bf14d 100644 --- a/internal/casino/manager.go +++ b/internal/casino/manager.go @@ -97,14 +97,14 @@ func (m *Manager) JoinMachine(roomID int, cfg MachineConfig, name string) []Even return m.EnsureMachine(roomID, cfg).join(name) } -func (m *Manager) SetMachineBet(roomID int, machineID, name string, amount int) []Event { +func (m *Manager) SetMachineBet(roomID int, machineID, name string, amount int, wallet Wallet) []Event { m.mu.Lock() machine := m.machines[tableKey(roomID, machineID)] m.mu.Unlock() if machine == nil { return nil } - return machine.setBet(name, amount) + return machine.setBet(name, amount, wallet) } func (m *Manager) StartMachine(roomID int, machineID, name string, wallet Wallet) []Event { diff --git a/internal/casino/manager_test.go b/internal/casino/manager_test.go index f0809be..818f397 100644 --- a/internal/casino/manager_test.go +++ b/internal/casino/manager_test.go @@ -87,8 +87,13 @@ func TestMachineAutobetCountdownAndStop(t *testing.T) { m := NewManager(1) cfg := MachineConfig{ID: "slots", Game: GameSlots, SpinTicks: 1} m.JoinMachine(1, cfg, "alice") - m.SetMachineBet(1, "slots", "alice", 10) w := &testWallet{credits: 100} + if events := m.SetMachineBet(1, "slots", "alice", 10, w); len(events) == 0 { + t.Fatalf("setting a bet did not start a spin: %+v", events) + } + for m.MachineBusy("alice") { + m.Tick() + } if events := m.EnableMachineAutoBet(1, "slots", "alice", w); len(events) != 0 { t.Fatalf("enabling autobet emitted events before countdown: %+v", events) } |
