aboutsummaryrefslogtreecommitdiff
path: root/internal/game/render_roulette.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-29 19:48:32 -0400
committerhistoria <[not public]>2026-09-29 19:48:32 -0400
commitffc7b582e9c14fdc2e579b9239b5ff7ad9a0d90a (patch)
treee286210755094b41025f2947e412e05e59ec2ac9 /internal/game/render_roulette.go
parent624626b9a10ae47cf7d5f6e91765570ed759bd74 (diff)
downloadthehouseoficarus-ffc7b582e9c14fdc2e579b9239b5ff7ad9a0d90a.tar.gz
feat: roulette history tracker
Diffstat (limited to 'internal/game/render_roulette.go')
-rw-r--r--internal/game/render_roulette.go39
1 files changed, 28 insertions, 11 deletions
diff --git a/internal/game/render_roulette.go b/internal/game/render_roulette.go
index f6c6bb7..ce541c1 100644
--- a/internal/game/render_roulette.go
+++ b/internal/game/render_roulette.go
@@ -17,11 +17,12 @@ import (
func renderRouletteSnapshot(s *casino.RouletteSnapshot, mode string, unicode bool, size int) string {
switch s.Phase {
case "playing":
- return renderRouletteWheel(s.Wheel, mode, unicode)
+ // A blank line on either side keeps the wheel from crowding the prose.
+ return "\n" + renderRouletteWheel(s.Wheel, mode, unicode) + "\n"
case "result":
- return renderRouletteResult(s.Pockets, mode, unicode, size)
+ return "\n" + renderRouletteResult(s.Pockets, mode, unicode, size) + "\n"
default:
- return renderRouletteLayout(s.DoubleZero, s.Racetrack, mode, unicode)
+ return renderRouletteTracker(s, mode, unicode) + "\n" + renderRouletteLayout(s.DoubleZero, s.Racetrack, mode, unicode)
}
}
@@ -35,6 +36,11 @@ func roulettePaint(mode, text string, bg int) string {
return color.Render(mode, color.ColorSpec{Fg: 15, Bg: bg, Bold: true}, text)
}
+// rouletteWheelBlack is the spinning wheel's black pocket color. Plain black
+// background disappears on dark terminals, so the wheel uses a very dark blue
+// purely for visibility; the betting board and result cards keep true black.
+const rouletteWheelBlack = 17
+
func roulettePocketColor(pocket string) (int, string) {
if pocket == "0" || pocket == "00" {
return 2, "GREEN"
@@ -418,7 +424,7 @@ func renderRouletteWheel(wheel []string, mode string, unicode bool) string {
p := pocketIndex[i]
bg := 1
if p%2 == 1 {
- bg = 0
+ bg = rouletteWheelBlack
}
if p == greenPocket || (double && p == opposite) {
bg = 2
@@ -486,12 +492,11 @@ func renderRouletteRow(row []rouletteCell, mode string) string {
return sb.String()
}
-// renderRouletteResult draws the winning pocket and its two physical
-// neighbours at playing-card size. The pocket number sits on the top row, a
-// rule separates it from the ball (one row above centre), and the color is
-// spelled out on the bottom row only when color is off. There is no
-// surrounding prose.
-func renderRouletteResult(pockets [3]string, mode string, unicode bool, size int) string {
+// renderRouletteResult draws the winning pocket and two physical neighbours on
+// each side at playing-card size. The pocket number sits on the top row, a rule
+// separates it from the ball (one row above centre), and the color is spelled
+// out on the bottom row only when color is off. There is no surrounding prose.
+func renderRouletteResult(pockets [5]string, mode string, unicode bool, size int) string {
size = cardRenderSize(unicode, size)
if size < 5 {
size = 5
@@ -527,7 +532,7 @@ func renderRouletteResult(pockets [3]string, mode string, unicode bool, size int
if row == numberRow {
content = pocket
}
- if i == 1 && row == ballRow {
+ if i == len(pockets)/2 && row == ballRow {
content = ball
}
if plain && row == colorRow {
@@ -546,6 +551,18 @@ func (g *Game) renderCasinoRules(sess *net.Session, cfg casino.TableConfig) stri
rules := g.colorize(sess, "casino_action", cfg.RulesText())
if cfg.Game == casino.GameRoulette {
snap := &casino.RouletteSnapshot{DoubleZero: cfg.Roulette.DoubleZero, Racetrack: cfg.Roulette.Racetrack, Phase: "betting", Wheel: casino.WheelOrder(cfg.Roulette.DoubleZero)}
+ // Rules views draw a betting board too; use the live table's history
+ // rather than presenting an empty tracker after completed spins.
+ if g.Casino != nil && sess.Player != nil {
+ if table := g.Casino.Table(sess.Player.RoomID, cfg.ID); table != nil {
+ for _, event := range table.Status(sess.Player.Name) {
+ if view, ok := event.Snapshot.(*casino.RouletteSnapshot); ok {
+ snap.History = view.History
+ break
+ }
+ }
+ }
+ }
rules += "\n" + g.renderCasinoSnapshot(sess, snap) + "\n" + g.rouletteReminder(sess, cfg)
}
return rules