aboutsummaryrefslogtreecommitdiff
path: root/internal/game/render_roulette_test.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-29 15:19:40 -0400
committerhistoria <[not public]>2026-09-29 15:19:40 -0400
commitbfe22e10b5b9f2c7039d1d67021229659a06a226 (patch)
treef7c85d40f848e6fe3ec11d8d29eaf078ea4212b7 /internal/game/render_roulette_test.go
parent61fb8e950e0b30ef0ee65aa5882545e5292d9112 (diff)
downloadthehouseoficarus-bfe22e10b5b9f2c7039d1d67021229659a06a226.tar.gz
feat: better wheel graphics, better pocket graphics
Diffstat (limited to 'internal/game/render_roulette_test.go')
-rw-r--r--internal/game/render_roulette_test.go115
1 files changed, 96 insertions, 19 deletions
diff --git a/internal/game/render_roulette_test.go b/internal/game/render_roulette_test.go
index c1065e5..b1a6005 100644
--- a/internal/game/render_roulette_test.go
+++ b/internal/game/render_roulette_test.go
@@ -97,28 +97,30 @@ func TestRouletteArtModes(t *testing.T) {
wheelArt := renderRouletteWheel(wheelOrder, mode, unicode)
plainWheel := plainRoulette(wheelArt)
lines := strings.Split(plainWheel, "\n")
- if len(lines) != 23 {
- t.Fatalf("wheel height = %d, want 23", len(lines))
+ if len(lines) != 9 {
+ t.Fatalf("wheel height = %d, want 9", len(lines))
}
- wantDoubleZeroLabel := 0
- if double {
- wantDoubleZeroLabel = 1
- }
- if got := strings.Count(plainWheel, "00"); got != wantDoubleZeroLabel {
- t.Fatalf("double-zero labels = %d, want %d", got, wantDoubleZeroLabel)
+ if strings.ContainsAny(plainWheel, "0123456789") {
+ t.Fatalf("wheel should not show numbers:\n%s", plainWheel)
}
- if mode != "none" {
- wantGreen := 1
- if double {
- wantGreen = 2
+ if mode == "none" || mode == "" {
+ for _, r := range "RBG" {
+ if !strings.ContainsRune(plainWheel, r) {
+ t.Fatalf("colorless wheel missing %q:\n%s", r, plainWheel)
+ }
}
- greens := strings.Count(wheelArt, color.BgCode(mode, 2))
- if greens != wantGreen {
- t.Fatalf("green pockets = %d, want %d", greens, wantGreen)
+ // The top and bottom rows must be several cells wide so the
+ // disc reads as a circle rather than a pointed oval.
+ for _, idx := range []int{0, 8} {
+ if got := len(strings.TrimSpace(lines[idx])); got != 5 {
+ t.Fatalf("wheel row %d = %d wide, want 5:\n%s", idx, got, plainWheel)
+ }
}
- total := greens + strings.Count(wheelArt, color.BgCode(mode, 0)) + strings.Count(wheelArt, color.BgCode(mode, 1))
- if total != len(wheelOrder) {
- t.Fatalf("drawn pockets = %d, want %d", total, len(wheelOrder))
+ } else {
+ for _, bg := range []int{0, 1, 2} {
+ if !strings.Contains(wheelArt, color.BgCode(mode, bg)) {
+ t.Fatalf("wheel missing pocket background %d", bg)
+ }
}
}
@@ -134,6 +136,21 @@ func TestRouletteArtModes(t *testing.T) {
}
}
+// TestRouletteWheelGreenPockets checks that the single-zero wheel has one green
+// pocket and the American wheel adds the diametrically opposite one.
+func TestRouletteWheelGreenPockets(t *testing.T) {
+ single := plainRoulette(renderRouletteWheel(casino.WheelOrder(false), "none", true))
+ double := plainRoulette(renderRouletteWheel(casino.WheelOrder(true), "none", true))
+ singleGreen := strings.Count(single, "G")
+ doubleGreen := strings.Count(double, "G")
+ if singleGreen == 0 {
+ t.Fatalf("single-zero wheel has no green:\n%s", single)
+ }
+ if doubleGreen <= singleGreen {
+ t.Fatalf("double-zero green = %d, want more than single-zero %d:\n%s", doubleGreen, singleGreen, double)
+ }
+}
+
// TestRouletteLayoutConnections guards the box-drawing joints: the dozen-row
// boxes must connect to the numbered grid above and be closed under, the
// row-bet cells must be boxed on the right, and the bottom rule must tee under
@@ -197,7 +214,7 @@ func TestRouletteResultSizesAndNeighbors(t *testing.T) {
t.Fatalf("unequal pocket widths: %q", line)
}
}
- center := []rune(lines[height/2])
+ center := []rune(lines[1])
if !strings.Contains(string(center[:width]), "1") || !strings.Contains(string(center[width+1:2*width+1]), "00") || !strings.Contains(string(center[2*width+2:]), "27") {
t.Fatal("wrong pocket order", art)
}
@@ -212,6 +229,66 @@ func TestRouletteResultSizesAndNeighbors(t *testing.T) {
}
}
+// TestRouletteResultLayout checks the new card shape: number on top, a rule
+// under it, the ball one row above centre, and the color spelled out on the
+// bottom row only when color is off. cardRenderSize caps non-Unicode cards at
+// five rows, so the full nine-row shape is exercised through Unicode.
+func TestRouletteResultLayout(t *testing.T) {
+ pockets := [3]string{"1", "10", "27"} // RED, BLACK, RED
+ for _, tc := range []struct {
+ unicode bool
+ size int
+ height int
+ }{
+ {true, 9, 9},
+ {true, 7, 7},
+ {true, 5, 5},
+ {false, 9, 5},
+ } {
+ unicode, height := tc.unicode, tc.height
+ ball := "o"
+ rule := "-"
+ if unicode {
+ ball = "●"
+ rule = "─"
+ }
+ ballRow := height / 2
+ colorRow := height - 2
+ hasRule := ballRow > 2
+
+ colored := plainRoulette(renderRouletteResult(pockets, "xterm256", unicode, tc.size))
+ lines := strings.Split(colored, "\n")
+ if len(lines) != height {
+ t.Fatalf("unicode=%v size=%d: height=%d, want %d", unicode, tc.size, len(lines), height)
+ }
+ for i, want := range pockets {
+ if !strings.Contains(lines[1], want) {
+ t.Fatalf("unicode=%v size=%d: top row missing pocket %d (%s):\n%s", unicode, tc.size, i, want, colored)
+ }
+ }
+ if hasRule {
+ if !strings.Contains(lines[2], rule) {
+ t.Fatalf("unicode=%v size=%d: missing rule under the number:\n%s", unicode, tc.size, colored)
+ }
+ }
+ if !strings.Contains(lines[ballRow], ball) {
+ t.Fatalf("unicode=%v size=%d: ball should be on row %d:\n%s", unicode, tc.size, ballRow, colored)
+ }
+ if strings.Contains(colored, "RED") || strings.Contains(colored, "BLACK") {
+ t.Fatalf("unicode=%v size=%d: color label shown while color is on:\n%s", unicode, tc.size, colored)
+ }
+
+ plain := plainRoulette(renderRouletteResult(pockets, "none", unicode, tc.size))
+ plainLines := strings.Split(plain, "\n")
+ if strings.Contains(plainLines[1], "RED") || strings.Contains(plainLines[1], "BLACK") {
+ t.Fatalf("unicode=%v size=%d: color label should not be on the top row:\n%s", unicode, tc.size, plain)
+ }
+ if !strings.Contains(plainLines[colorRow], "RED") || !strings.Contains(plainLines[colorRow], "BLACK") {
+ t.Fatalf("unicode=%v size=%d: missing color label on row %d:\n%s", unicode, tc.size, colorRow, plain)
+ }
+ }
+}
+
func TestRouletteEventColorsDoNotWrapArt(t *testing.T) {
for _, public := range []bool{false, true} {
for _, mode := range []string{"none", "ansi", "xterm256"} {