aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/roulette.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/roulette.go')
-rw-r--r--internal/casino/roulette.go61
1 files changed, 20 insertions, 41 deletions
diff --git a/internal/casino/roulette.go b/internal/casino/roulette.go
index be8966c..ed649e9 100644
--- a/internal/casino/roulette.go
+++ b/internal/casino/roulette.go
@@ -22,6 +22,10 @@ func rouletteWheel(double bool) []string {
}
return europeanWheel
}
+
+// WheelOrder returns a copy of the pocket order (clockwise from the top) for
+// presentation layers that draw the wheel themselves.
+func WheelOrder(double bool) []string { return append([]string(nil), rouletteWheel(double)...) }
func rouletteRed(n int) bool {
switch n {
case 1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36:
@@ -101,7 +105,7 @@ func newRouletteTable(room int, cfg TableConfig, rng *rand.Rand) *rouletteTable
return &rouletteTable{tableCore: newTableCore[*roulettePlayer](&tableBase{RoomID: room, Config: cfg}), rng: rng}
}
func (t *rouletteTable) view() *RouletteSnapshot {
- s := &RouletteSnapshot{DoubleZero: t.Config.Roulette.DoubleZero, Phase: string(t.phase)}
+ s := &RouletteSnapshot{DoubleZero: t.Config.Roulette.DoubleZero, Phase: string(t.phase), Wheel: rouletteWheel(t.Config.Roulette.DoubleZero)}
for _, p := range t.players.ordered() {
s.Players = append(s.Players, p.Name)
}
@@ -109,7 +113,7 @@ func (t *rouletteTable) view() *RouletteSnapshot {
}
func (t *rouletteTable) menuEvent(name string) Event {
e := t.betMenuEvent(name, []MenuCommand{
- {Command: "bet <amount> on <target>", Desc: "One wager per spin; numbers pay 35:1, outside bets 1:1, dozens/columns 2:1"},
+ {Command: "bet <amount> on <target>", Desc: "Place one wager per spin (help roulette)"},
{Command: "bet / rebet", Desc: "Repeat your previous wager"},
{Command: "table / sitout / stop", Desc: "View layout / sit out / leave after this spin"},
})
@@ -256,7 +260,9 @@ func (t *rouletteTable) settle() []Event {
public = p.Name + "'s settlement is pending recovery."
}
event := t.playerAction(p.Name, public, text)
- event.ShowBalance = !failed
+ // Returning players get their balance in the next-spin menu. Only
+ // departures/sit-outs need a balance attached to the settlement.
+ event.ShowBalance = !failed && (p.LeaveAfter || p.SitOutAfter || !p.Connected)
if result == "win" && !failed {
event.Color = "casino_big_win"
}
@@ -296,7 +302,11 @@ func (t *rouletteTable) rebet(name string) (string, int) {
func (t *rouletteTable) status(name string) []Event {
t.mu.Lock()
defer t.mu.Unlock()
- e := t.private(name, t.overviewLocked()+"\n"+t.seatStatusLocked(name))
+ message := t.overviewLocked()
+ if text := t.seatStatusLocked(name); text != "" {
+ message += "\n" + text
+ }
+ e := t.private(name, message)
e.Snapshot = t.view()
events := []Event{e}
if t.phase == phaseWaiting && t.lastResult != nil {
@@ -335,48 +345,17 @@ func (t *rouletteTable) refundAll() []Event {
return events
}
-// RouletteSnapshot keeps ASCII views available to spectators and players
-// without coupling the engine to terminal color or card-art settings.
+// RouletteSnapshot describes the view without coupling the engine to terminal
+// colors, Unicode preferences, or card-art settings.
type RouletteSnapshot struct {
DoubleZero bool
Phase string
Pockets [3]string // physical wheel neighbors, not numerical neighbors
Players []string
+ // Wheel is the pocket order clockwise from the top; the renderer colors
+ // and places each pocket. It carries the zero count (one or two) so the
+ // drawn wheel always matches the configured table.
+ Wheel []string
}
func (*RouletteSnapshot) snapshot() {}
-func (s *RouletteSnapshot) ASCII() string {
- if s.Phase == "result" {
- return fmt.Sprintf("+-----+-----+-----+\n| %-3s | %-3s | %-3s |\n| | o | |\n+-----+-----+-----+\n WINNER", s.Pockets[0], s.Pockets[1], s.Pockets[2])
- }
- if s.Phase == string(phasePlaying) {
- bottom := " * "
- if s.DoubleZero {
- bottom = "00 "
- }
- return " .--[ 0 ]--.\n / * | * \\\n | * --+-- * |\n \\ * | * /\n '--[" + bottom + "]--'\n Spinning"
- }
- var b strings.Builder
- b.WriteString("ROULETTE | R=red B=black G=green\n[0 G]")
- if s.DoubleZero {
- b.WriteString(" [00 G]")
- }
- b.WriteString("\n")
- for row := 3; row >= 1; row-- {
- b.WriteString("|")
- for n := row; n <= 36; n += 3 {
- color := "B"
- if rouletteRed(n) {
- color = "R"
- }
- fmt.Fprintf(&b, "%2d%s|", n, color)
- }
- fmt.Fprintf(&b, " column%d\n", row)
- }
- b.WriteString("| dozen1 | dozen2 | dozen3 |\n| low (1-18) | even | red | black | odd | high (19-36) |\nTargets: 0-36")
- if s.DoubleZero {
- b.WriteString(", 00")
- }
- b.WriteString(", red, black, odd, even, low, high,\n dozen1/2/3, column1/2/3\nExample: bet 10 on 17 (one wager per spin)")
- return b.String()
-}