aboutsummaryrefslogtreecommitdiff
path: root/internal/game/render_roulette.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-30 03:55:37 -0400
committerhistoria <[not public]>2026-09-30 03:55:37 -0400
commit735428f0667f67c12fdf3caca872d7dc65e2ce26 (patch)
tree92c9931f223bfd50ced4f1954130d879640a435b /internal/game/render_roulette.go
parentffc7b582e9c14fdc2e579b9239b5ff7ad9a0d90a (diff)
downloadthehouseoficarus-735428f0667f67c12fdf3caca872d7dc65e2ce26.tar.gz
feat: restyle roulette presentation
Diffstat (limited to 'internal/game/render_roulette.go')
-rw-r--r--internal/game/render_roulette.go53
1 files changed, 51 insertions, 2 deletions
diff --git a/internal/game/render_roulette.go b/internal/game/render_roulette.go
index ce541c1..d69b5bf 100644
--- a/internal/game/render_roulette.go
+++ b/internal/game/render_roulette.go
@@ -22,7 +22,9 @@ func renderRouletteSnapshot(s *casino.RouletteSnapshot, mode string, unicode boo
case "result":
return "\n" + renderRouletteResult(s.Pockets, mode, unicode, size) + "\n"
default:
- return renderRouletteTracker(s, mode, unicode) + "\n" + renderRouletteLayout(s.DoubleZero, s.Racetrack, mode, unicode)
+ // A blank line above the tracker separates it from the prose or menu
+ // that precedes the board.
+ return "\n" + renderRouletteTracker(s, mode, unicode) + "\n" + renderRouletteLayout(s.DoubleZero, s.Racetrack, mode, unicode)
}
}
@@ -174,6 +176,18 @@ func renderRouletteRacetrack(mode string, unicode bool) string {
ink(58, 5, b.v)
ink(58, 6, bl+tr)
ink(59, 7, bl+tr)
+ // Labels are centered on the middle row; a label too wide to leave a blank
+ // cell against its dividers is wrapped onto the rows above and below it.
+ // Only the glyphs are written: the centering padding must not be painted
+ // over the step and curve dividers that share these rows.
+ labelX := func(left, right int, text string) int {
+ width := right - left - 1
+ pad := max(0, width-color.VisibleLen(text))
+ return left + 1 + pad/2
+ }
+ inkCenter := func(y, left, right int, text string) {
+ ink(labelX(left, right, text), y, text)
+ }
for _, label := range []struct {
left, right int
text string
@@ -181,7 +195,17 @@ func renderRouletteRacetrack(mode string, unicode bool) string {
{4, 22, "Tiers du Cylindre"}, {22, 40, "Orphelins"},
{40, 58, "Voisins du Zero"}, {58, 68, "Jeu Zero"},
} {
- ink(label.left+1, 5, rouletteCenter(label.text, label.right-label.left-1))
+ lines := rouletteWrapLabel(label.text, label.right-label.left-3)
+ if len(lines) == 1 {
+ inkCenter(5, label.left, label.right, lines[0])
+ continue
+ }
+ // Wrapped lines share the first line's left edge so the two words read
+ // as one label instead of drifting apart under independent centering.
+ x := labelX(label.left, label.right, lines[0])
+ for i, line := range lines {
+ ink(x, 4+2*i, line)
+ }
}
lines := make([]string, height)
for y, row := range grid {
@@ -190,6 +214,31 @@ func renderRouletteRacetrack(mode string, unicode bool) string {
return strings.Join(lines, "\n")
}
+// rouletteWrapLabel breaks a call-bet label on spaces so each line leaves a
+// blank cell against the track dividers. The caller knows the labels are short
+// enough to wrap onto at most two lines; a single over-long word is left whole
+// rather than hyphenated.
+func rouletteWrapLabel(text string, limit int) []string {
+ words := strings.Fields(text)
+ var lines []string
+ cur := ""
+ for _, word := range words {
+ switch {
+ case cur == "":
+ cur = word
+ case len(cur)+1+len(word) <= limit:
+ cur += " " + word
+ default:
+ lines = append(lines, cur)
+ cur = word
+ }
+ }
+ if cur != "" {
+ lines = append(lines, cur)
+ }
+ return lines
+}
+
// renderRouletteLayout draws the betting board. Green is reserved for the
// 0/00 lane: every other cell is red, black, or plain. The odds reminder is
// not part of the board (it is shown by the "table" command), so the board