diff options
| author | historia <[not public]> | 2026-10-01 04:26:20 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-10-01 04:26:20 -0400 |
| commit | 0ba388bbe229dd1ccfcb0831d21a5542ae0935f1 (patch) | |
| tree | c5686cf404e3dc5001d2c9b2792749ae7a3c9801 /internal/game/video_poker_render_test.go | |
| parent | e3ff06fc79682673194c8913f0feb9e90920e7d0 (diff) | |
| download | thehouseoficarus-0ba388bbe229dd1ccfcb0831d21a5542ae0935f1.tar.gz | |
feat: video poker machines added to casino
Diffstat (limited to 'internal/game/video_poker_render_test.go')
| -rw-r--r-- | internal/game/video_poker_render_test.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/internal/game/video_poker_render_test.go b/internal/game/video_poker_render_test.go new file mode 100644 index 0000000..d618c36 --- /dev/null +++ b/internal/game/video_poker_render_test.go @@ -0,0 +1,112 @@ +package game + +import ( + "fmt" + "strings" + "testing" + + "thehouseoficarus/internal/casino" + "thehouseoficarus/internal/color" +) + +func TestPokerPayTableBordersPaletteAndColumns(t *testing.T) { + for _, cabinet := range []string{casino.CabinetClassic, casino.CabinetUXSingle, casino.CabinetUXMulti} { + cfg := (casino.VideoPokerConfig{Cabinet: cabinet, Variant: "double_double_bonus"}).Normalize() + snap := &casino.VideoPokerSnapshot{Config: cfg, Coins: 3, Hands: 3, Denomination: 10} + panel := renderPokerPayTable(snap, "xterm256") + for _, want := range []string{"┌", "┬", "┐", "│", "└", "┴", "┘", "....", "4000", "COINS PER HAND"} { + if !strings.Contains(panel, want) { + t.Fatalf("panel missing %q: %s", want, panel) + } + } + for _, seq := range []string{fmt.Sprintf("38;5;%d", pokerYellow), fmt.Sprintf("48;5;%d", pokerBlue), fmt.Sprintf("48;5;%d", pokerRed)} { + if !strings.Contains(panel, seq) { + t.Fatalf("missing palette %s", seq) + } + } + width := -1 + for _, line := range strings.Split(stripANSI(panel), "\n") { + if !strings.HasPrefix(line, "│") && !strings.HasPrefix(line, "┌") && !strings.HasPrefix(line, "├") && !strings.HasPrefix(line, "└") { + continue + } + if width < 0 { + width = color.VisibleLen(line) + } + if color.VisibleLen(line) != width { + t.Fatalf("unaligned pay table: %q (%d != %d)", line, color.VisibleLen(line), width) + } + if strings.HasPrefix(line, "│") { + cells := strings.Split(line, "│") + want := 8 + if cabinet != casino.CabinetClassic { + want = 9 + } + if len(cells) != want { + t.Fatalf("bad column count %d: %s", len(cells), line) + } + } + } + if cabinet != casino.CabinetClassic && strings.Count(stripANSI(panel), "NEXT X") != 1 { + t.Fatal("missing/duplicate next award heading") + } + plain := renderPokerPayTable(snap, "none") + if strings.Contains(plain, "\x1b") { + t.Fatal("plain display contains escapes") + } + } +} + +func TestPokerResultsBelowCardsAndHoldStyle(t *testing.T) { + cards := []casino.CardView{{Rank: "A", Suit: "hearts"}, {Rank: "K", Suit: "hearts"}, {Rank: "Q", Suit: "hearts"}, {Rank: "J", Suit: "hearts"}, {Rank: "10", Suit: "hearts"}} + cfg := (casino.VideoPokerConfig{Cabinet: casino.CabinetClassic}).Normalize() + for _, hands := range []int{1, 3, 100} { + for _, win := range []bool{false, true} { + line := casino.PokerLine{Cards: cards, Category: "No win", Multiplier: 1} + fg, text := 15, "No win" + if win { + line.Category = "Royal flush" + line.Coins = 4000 + fg = pokerYellow + text = "WIN: Royal flush — 4000 coins" + } + snap := &casino.VideoPokerSnapshot{Config: cfg, Hands: hands, Lines: []casino.PokerLine{line}, Multiplier: 1} + out := renderVideoPoker(snap, "xterm256", true, 7, "", nil) + styled := color.Render("xterm256", color.ColorSpec{Fg: fg, Bg: -1, Bold: true}, text) + if !strings.Contains(out, styled) { + t.Fatalf("missing result styling: %q", out) + } + plain := stripANSI(out) + result := strings.Index(plain, text) + // The result starts its own line and follows the card/badge line. + if result < 0 || result == 0 || plain[result-1] != '\n' || strings.Index(plain, "CLASSIC") > result { + t.Fatalf("result not below cards: %s", plain) + } + if hands == 100 && !strings.Contains(plain, "♥") { + t.Fatal("hundred-play missing compact Unicode suits") + } + } + } + held := [5]bool{true, false, true, false, true} + art := strings.Join(renderPokerCards(cards, &held, "xterm256", true, 5, "", nil), "\n") + for _, n := range []int{1, 3, 5} { + if !strings.Contains(art, color.Render("xterm256", color.ColorSpec{Fg: pokerYellow, Bg: -1, Bold: true}, fmt.Sprintf("%d HELD", n))) { + t.Fatal("HELD not bold yellow") + } + } +} + +func TestPokerDrawShortcutLeavesDownAlone(t *testing.T) { + g, sess, conn := casinoCrapsGame(t, "name: Poker\ncasino_tables:\n - id: vp\n game: video_poker\n") + g.executeCommand(sess, "d", nil, "d") + if !strings.Contains(string(conn.data), "You can't go that way.") { + t.Fatalf("d did not route down outside poker: %s", conn.data) + } + g.executePlay(sess, []string{"vp"}, "play vp") + g.executeBet(sess, nil, "bet") + g.executeTableAction(sess, "deal") + conn.data = nil + g.executeCommand(sess, "d", nil, "d") + if len(sess.Player.PendingWagers) != 0 || strings.Contains(string(conn.data), "You can't go that way.") { + t.Fatal("seated d did not settle the hand") + } +} |
