aboutsummaryrefslogtreecommitdiff
path: root/internal/game/pai_gow_test.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-10-01 16:26:11 -0400
committerhistoria <[not public]>2026-10-01 16:26:11 -0400
commitd762f8e1360cf38b8e11e69083c2dad59ec7130e (patch)
tree4e684608e02b39b6b085e2a2ab9726bdae063240 /internal/game/pai_gow_test.go
parentc94728c929045f7c1bdf0166df152d944e5f99bc (diff)
downloadthehouseoficarus-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.go86
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")
+ }
+}