diff options
Diffstat (limited to 'internal/casino/machine.go')
| -rw-r--r-- | internal/casino/machine.go | 54 |
1 files changed, 19 insertions, 35 deletions
diff --git a/internal/casino/machine.go b/internal/casino/machine.go index d9fa590..887e154 100644 --- a/internal/casino/machine.go +++ b/internal/casino/machine.go @@ -40,6 +40,7 @@ func newMachine(roomID int, cfg MachineConfig, rng *rand.Rand) *Machine { if cfg.Payout > 0 { profile = ScaleToRTP(profile, cfg.Payout) } + profile = profile.Normalize() return &Machine{RoomID: roomID, Config: cfg, phase: machineReady, profile: profile, rng: rng} } @@ -97,23 +98,14 @@ func (m *Machine) start(name string, wallet Wallet) []Event { if m.bet <= 0 { return m.private("Set a wager first with 'bet <amount>'.") } - wager := m.bet - if m.freeSpins > 0 { - m.spinBet = wager - } else { - if _, ok := wallet.Wager(wager); !ok { - return m.private("You don't have enough chips and credits for that bet.") - } - m.spinBet = wager + if _, ok := wallet.Wager(m.bet); !ok { + return m.private("You don't have enough chips and credits for that bet.") } + m.spinBet = m.bet 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 - if m.freeSpins > 0 { - m.freeSpins-- - return m.playerAction(fmt.Sprintf("%s begins a free spin.", name), "You begin a free spin.") - } return m.playerAction(fmt.Sprintf("%s pulls the lever on the slots machine.", name), "You pull the lever on the slots machine.") } @@ -179,7 +171,7 @@ func (m *Machine) tick() []Event { m.reel++ message := fmt.Sprintf("Reel %d stops...", m.reel) events := m.publicSlot(message, m.reel) - if m.reel < 5 && stoppedScatters(m.spin.Grid, m.reel) >= 2 && !m.suspense { + if m.reel < 5 && stoppedScatters(m.spin.Grid, m.reel, m.profile.FreeSpinTrigger) >= 2 && !m.suspense { m.suspense = true events = append(events, m.public("Two scatters! The remaining reels slow down...")...) } @@ -232,19 +224,16 @@ func (m *Machine) finishSpin() []Event { if credits > m.spinBet { winEvents[0].Color = "casino_big_win" } - if credits >= 2*m.spinBet { - winEvents[0].Color = "casino_jackpot_win" - } events = append(events, winEvents...) } if len(m.spin.Wins) > 0 { - winEvents := m.private(formatWins(m.spin.Wins)) + winEvents := m.private(formatWins(m.spin.Wins, m.profile.Ways)) winEvents[0].Color = "casino_win" events = append(events, winEvents...) } if m.spin.ScatterCount >= 3 && m.freeSpins == 0 { - m.freeSpins = 8 - events = append(events, m.public("Three scatter symbols trigger 8 free spins!")...) + m.freeSpins = m.profile.FreeSpinCount + events = append(events, m.public(fmt.Sprintf("Three scatter symbols trigger %d free spins!", m.profile.FreeSpinCount))...) } if m.freeSpins > 0 { m.freeSpins-- @@ -269,6 +258,7 @@ func (m *Machine) leave(name string) []Event { } m.player = nil m.bet = 0 + m.payoutRemainder = 0 return []Event{{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventLeft, Player: name, Message: fmt.Sprintf("%s stands up from the slots machine.", name), PrivateMessage: "You stand up from the slot machine.", PrivateTo: name, Color: "casino_action", Public: true}} } @@ -322,11 +312,11 @@ func (m *Machine) publicSlot(message string, stopped int) []Event { Message: message, Color: "casino_action", Public: true, Slot: &SlotSnapshot{Grid: m.spin.Grid, StoppedReels: stopped}}} } -func stoppedScatters(grid [3][5]string, reels int) int { +func stoppedScatters(grid [3][5]string, reels int, trigger string) int { count := 0 for row := 0; row < 3; row++ { for reel := 0; reel < reels && reel < 5; reel++ { - if grid[row][reel] == "scatter" { + if grid[row][reel] == trigger { count++ } } @@ -334,28 +324,22 @@ func stoppedScatters(grid [3][5]string, reels int) int { return count } -func formatWins(wins []SlotWin) string { - message := "Winning lines/ways (243-way evaluation):\n" +func formatWins(wins []SlotWin, ways int) string { + message := fmt.Sprintf("Winning lines/ways (%d-way evaluation):\n", ways) for _, win := range wins { - message += fmt.Sprintf(" %s x%d: %d ways x %.4gx bet / 243 = %.4f credits\n", win.Symbol, win.Length, win.Ways, win.Multiplier, win.Payout) + message += fmt.Sprintf(" %s x%d: %d ways x %.4gx bet / %d = %.4f credits\n", win.Symbol, win.Length, win.Ways, win.Multiplier, ways, win.Payout) } return message[:len(message)-1] } +const slotMenuText = "Slot machine commands:\n bet <amount> Set your wager\n bet max Set the maximum wager\n spin Spin using your current wager\n autospin Start automatic betting\n stop Leave the slot machine" + func (m *Machine) privateMenu(prefix string) []Event { - if m.phase != machineReady { - events := m.private(prefix) - events[0].Color = "casino_menu" - return events - } - menu := "Slot machine commands:\n bet <amount> Set your wager\n bet max Set the maximum wager\n spin Spin using your current wager\n autospin Start automatic betting\n stop Leave the slot machine" - if prefix == "" { - prefix = "\n" + menu - } else { - prefix += "\n\n" + menu - } events := m.private(prefix) events[0].Color = "casino_menu" + if m.phase == machineReady { + events[0].Menu = &MenuView{Kind: MenuSlotCommands, Body: slotMenuText} + } return events } |
