aboutsummaryrefslogtreecommitdiff
path: root/internal/game/render_casino_help_test.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-29 18:58:28 -0400
committerhistoria <[not public]>2026-09-29 18:58:28 -0400
commit624626b9a10ae47cf7d5f6e91765570ed759bd74 (patch)
tree9812f5d254b7d9cfe1d2fcb6da53362e974541b0 /internal/game/render_casino_help_test.go
parentff9002b96e35ad0808945e7c35791460c9ca8776 (diff)
downloadthehouseoficarus-624626b9a10ae47cf7d5f6e91765570ed759bd74.tar.gz
feat: better roulette racetrack graphics and payout table
Diffstat (limited to 'internal/game/render_casino_help_test.go')
-rw-r--r--internal/game/render_casino_help_test.go122
1 files changed, 122 insertions, 0 deletions
diff --git a/internal/game/render_casino_help_test.go b/internal/game/render_casino_help_test.go
new file mode 100644
index 0000000..246880f
--- /dev/null
+++ b/internal/game/render_casino_help_test.go
@@ -0,0 +1,122 @@
+package game
+
+import (
+ "strings"
+ "testing"
+
+ "thehouseoficarus/internal/casino"
+ "thehouseoficarus/internal/color"
+ "thehouseoficarus/internal/net"
+ "thehouseoficarus/internal/player"
+)
+
+func TestRoulettePayoutTables(t *testing.T) {
+ for _, mode := range []string{"none", "ansi", "xterm256"} {
+ for _, unicode := range []bool{false, true} {
+ for _, double := range []bool{false, true} {
+ for _, width := range []int{60, 78} {
+ g := &Game{}
+ p := player.New("alice")
+ p.Options = map[string]any{"color": mode, "unicode": unicode, "wrap_width": width}
+ sess := &net.Session{Player: p}
+ cfg := casino.TableConfig{Game: casino.GameRoulette, Roulette: casino.RouletteConfig{DoubleZero: double, Racetrack: !double}}
+ art := g.rouletteReminder(sess, cfg)
+ plain := stripANSI(art)
+ for _, want := range []string{"Roulette payouts", "Target / example", "Chance", "Profit", "35:1", "17:1", "11:1", "8:1", "5:1", "2:1", "1:1", "help roulette"} {
+ if !strings.Contains(plain, want) {
+ t.Fatalf("missing %q:\n%s", want, plain)
+ }
+ }
+ if double {
+ for _, want := range []string{"1/38", "5/38", "6:1", "0, 00"} {
+ if !strings.Contains(plain, want) {
+ t.Fatalf("missing %q", want)
+ }
+ }
+ if strings.Contains(plain, "Racetrack payouts") {
+ t.Fatal("American wheel has call bets")
+ }
+ } else {
+ for _, want := range []string{"1/37", "4/37", "17/37", "12/37", "8/37", "7/37", "9/37", "Racetrack payouts", "5:3", "13:5", "31:5", "7:2", "zero / jeu zero"} {
+ if !strings.Contains(plain, want) {
+ t.Fatalf("missing %q:\n%s", want, plain)
+ }
+ }
+ }
+ if (mode == "none") == strings.Contains(art, "\x1b[") {
+ t.Fatalf("wrong color mode %s", mode)
+ }
+ tableWidth := 0
+ for _, line := range strings.Split(art, "\n") {
+ plainLine := stripANSI(line)
+ if plainLine != "" && strings.ContainsRune("╔╟╚+", []rune(plainLine)[0]) {
+ tableWidth = color.VisibleLen(line)
+ }
+ if plainLine != "" && strings.ContainsRune("╔║╟╚+|", []rune(plainLine)[0]) {
+ if got := color.VisibleLen(line); got != tableWidth || got > width {
+ t.Errorf("uneven table width %d (want %d, max %d): %q", got, tableWidth, width, plainLine)
+ }
+ }
+ if !unicode {
+ for _, r := range plainLine {
+ if r > 127 {
+ t.Errorf("non-ASCII %q", r)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+func TestCasinoHelpTopics(t *testing.T) {
+ g := &Game{Deps: Deps{DataDir: "../../data"}}
+ conn := &casinoTestConn{}
+ sess := &net.Session{Player: player.New("alice"), Conn: conn}
+ for topic, want := range map[string]string{
+ "casino": "Profit odds", "play": "Casino quick guide",
+ "blackjack": "3:2", "baccarat": "0.95:1", "slots": "243",
+ "roulette": "35:1", "racetrack": "17/37", "zero": "Jeu Zero",
+ } {
+ conn.data = nil
+ g.doHelp(sess, topic)
+ if !strings.Contains(string(conn.data), want) {
+ t.Errorf("help %s: %s", topic, conn.data)
+ }
+ }
+}
+
+func TestTableHelpTeachesCurrentGame(t *testing.T) {
+ for _, game := range []casino.GameName{casino.GameBlackjack, casino.GameBaccarat, casino.GameRoulette} {
+ g, sess, conn := uxCasinoGame(t)
+ g.DataDir = "../../data"
+ g.Casino.Join(1, casino.TableConfig{ID: "test", Game: game}, "alice")
+ conn.data = nil
+ g.executeTableStatus(sess, []string{"help"}, "table help")
+ text := stripANSI(string(conn.data))
+ if strings.Contains(text, "No help") || !strings.Contains(text, "Table controls") || !strings.Contains(text, "pays") && !strings.Contains(text, "35:1") {
+ t.Fatalf("help %s: %s", game, text)
+ }
+ if game != casino.GameBlackjack && strings.Contains(text, "insurance / decline") {
+ t.Fatalf("blackjack-only controls shown for %s", game)
+ }
+ }
+ g, sess, conn := uxCasinoGame(t)
+ g.DataDir = "../../data"
+ g.executeTableStatus(sess, []string{"help"}, "table help")
+ if !strings.Contains(string(conn.data), "Casino quick guide") {
+ t.Fatal("unseated players cannot learn the games")
+ }
+}
+
+func TestTableHelpAtSlotMachine(t *testing.T) {
+ g, sess, conn := uxCasinoGame(t)
+ g.DataDir = "../../data"
+ g.Casino.JoinMachine(1, casino.MachineConfig{ID: "slots", Game: casino.GameSlots}, "alice")
+ g.executeTableStatus(sess, []string{"help"}, "table help")
+ if !strings.Contains(string(conn.data), "Slots quick guide") {
+ t.Fatal("machine player did not get the slots guide")
+ }
+}