diff options
| author | historia <[not public]> | 2026-10-01 16:26:11 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-10-01 16:26:11 -0400 |
| commit | d762f8e1360cf38b8e11e69083c2dad59ec7130e (patch) | |
| tree | 4e684608e02b39b6b085e2a2ab9726bdae063240 /internal/game/pai_gow_test.go | |
| parent | c94728c929045f7c1bdf0166df152d944e5f99bc (diff) | |
| download | thehouseoficarus-d762f8e1360cf38b8e11e69083c2dad59ec7130e.tar.gz | |
fix: trim extra info from games, A2345 support in pai gow, remove bet timers for single player games
Diffstat (limited to 'internal/game/pai_gow_test.go')
| -rw-r--r-- | internal/game/pai_gow_test.go | 86 |
1 files changed, 67 insertions, 19 deletions
diff --git a/internal/game/pai_gow_test.go b/internal/game/pai_gow_test.go index f13655b..af6b749 100644 --- a/internal/game/pai_gow_test.go +++ b/internal/game/pai_gow_test.go @@ -25,9 +25,8 @@ func TestPaiGowCommandsLookAndSettlement(t *testing.T) { t.Fatalf("missing %s: %s", want, text) } } - g.executeBet(sess, []string{"20"}, "bet 20") g.executeBet(sess, []string{"5", "fortune"}, "bet 5 fortune") - g.executeTableAction(sess, "deal") + g.executeBet(sess, []string{"20"}, "bet 20") snap := table.Status(sess.Player.Name)[0].Snapshot.(*casino.PaiGowSnapshot) if len(snap.Cards) != 7 || len(snap.DealerHigh) != 0 || len(sess.Player.PendingWagers) != 2 { t.Fatal("deal/side bet") @@ -132,34 +131,24 @@ func TestPaiGowContextHintsFollowState(t *testing.T) { g, sess, conn := casinoCrapsGame(t, "name: Pai Gow\ncasino_tables:\n - id: fortune\n game: paigow\n min_bet: 5\n max_bet: 1000\n pai_gow:\n envy: true\n") g.executePlay(sess, []string{"pai"}, "play pai") - // A fresh bettor is told how to place the main wager. + // A fresh bettor is told about the side bet and the main wager, plus the + // shared tail. conn.data = nil g.executeTableStatus(sess, nil, "table") text := stripANSI(string(conn.data)) - if !strings.Contains(text, "bet <amount>") { - t.Fatalf("missing main-bet hint: %s", text) - } - - // After the main wager the live menu offers Fortune and deal, not a second - // main bet, and the shared tail is present. - conn.data = nil - g.executeBet(sess, []string{"20"}, "bet 20") - text = stripANSI(string(conn.data)) - for _, want := range []string{"bet <amount> fortune", "deal", "table rules", "rules", "stop"} { + for _, want := range []string{"bet <amount> fortune", "bet <amount>", "table rules", "rules", "stop"} { if !strings.Contains(text, want) { - t.Fatalf("missing %q after main bet: %s", want, text) + t.Fatalf("missing %q at a fresh table: %s", want, text) } } - // Setting offers the split selectors and the house-way shortcut. - g.executeBet(sess, []string{"5", "fortune"}, "bet 5 fortune") - g.executeTableAction(sess, "deal") + // A lone main wager deals immediately; the live menu moves to setting. conn.data = nil - g.executeTableStatus(sess, nil, "table") + g.executeBet(sess, []string{"20"}, "bet 20") text = stripANSI(string(conn.data)) for _, want := range []string{"24 / 13456", "house"} { if !strings.Contains(text, want) { - t.Fatalf("missing %q while setting: %s", want, text) + t.Fatalf("missing %q after the main wager: %s", want, text) } } } @@ -186,3 +175,62 @@ func TestJokerEmptySuitDoesNotPanic(t *testing.T) { } } } + +func pgBoolPtr(b bool) *bool { return &b } + +func TestPaiGowFeltEndsAtBottomBorderAndNotesA2345(t *testing.T) { + on := renderPaiGowFelt(casino.TableConfig{Game: casino.GamePaiGow}, "none", false) + if !strings.Contains(on, "A2345 is second-highest straight.") { + t.Fatalf("enabled felt is missing the A2345 rule:\n%s", on) + } + lines := strings.Split(strings.TrimRight(on, "\n"), "\n") + // The bottom border is the final row and the joker note sits directly + // above it: the old blank interior row is gone. + if last := lines[len(lines)-1]; !strings.HasPrefix(last, "+") { + t.Fatalf("felt does not end on its bottom border: %q", last) + } + if !strings.Contains(lines[len(lines)-2], "Joker:") { + t.Fatalf("blank line below the joker note: %q", lines[len(lines)-2]) + } + offFelt := renderPaiGowFelt(casino.TableConfig{Game: casino.GamePaiGow, PaiGow: casino.PaiGowConfig{A2345SecondHighest: pgBoolPtr(false)}}, "none", false) + if strings.Contains(offFelt, "A2345 is second-highest straight.") { + t.Fatal("disabled felt still advertises the A2345 rule") + } +} + +func TestPaiGowEnvyColumnCentersUnderLabel(t *testing.T) { + cfg := casino.TableConfig{Game: casino.GamePaiGow, PaiGow: casino.PaiGowConfig{Envy: true}} + lines := strings.Split(renderPaiGowFelt(cfg, "none", false), "\n") + header := lines[5] + row := lines[6] + hi := strings.Index(header, "ENVY") + vi := strings.Index(row, "500") + if hi < 0 || vi < 0 { + t.Fatalf("missing header/value:\n%s\n%s", header, row) + } + // A value must sit within the label's four-column span. + if vi < hi || vi+len("500") > hi+len("ENVY") { + t.Fatalf("ENVY header and value are not aligned: header=%d value=%d\n%s\n%s", hi, vi, header, row) + } +} + +func TestPaiGowStopMidRoundQueuesDeparture(t *testing.T) { + g, sess, conn := casinoCrapsGame(t, "name: Pai Gow\ncasino_tables:\n - id: fortune\n game: paigow\n min_bet: 5\n max_bet: 1000\n") + g.executePlay(sess, []string{"pai"}, "play pai") + // A lone main wager deals at once, so stop reaches the committed-round path. + g.executeBet(sess, []string{"20"}, "bet 20") + conn.data = nil + g.executeCommand(sess, "stop", nil, "stop") + text := stripANSI(string(conn.data)) + if !strings.Contains(text, "leave after this round") { + t.Fatalf("stop mid-round did not queue a departure: %s", text) + } + if _, playing := g.Casino.Participation(sess.Player.Name); !playing { + t.Fatal("stop mid-round removed the seat too early") + } + // Finishing the hand applies the queued departure. + g.executeCommand(sess, "house", nil, "house") + if _, playing := g.Casino.Participation(sess.Player.Name); playing { + t.Fatal("queued stop did not leave after the round") + } +} |
