aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/craps_simplified_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/craps_simplified_test.go')
-rw-r--r--internal/casino/craps_simplified_test.go111
1 files changed, 110 insertions, 1 deletions
diff --git a/internal/casino/craps_simplified_test.go b/internal/casino/craps_simplified_test.go
index e36bc2d..b900c4f 100644
--- a/internal/casino/craps_simplified_test.go
+++ b/internal/casino/craps_simplified_test.go
@@ -1,6 +1,10 @@
package casino
-import "testing"
+import (
+ "strings"
+ "testing"
+ "time"
+)
func TestSimplifiedCrapsAll36SettlementsAndHouseEdge(t *testing.T) {
// Total returns for a one-credit wager, including the winning stake.
@@ -33,3 +37,108 @@ func TestSimplifiedCrapsAll36SettlementsAndHouseEdge(t *testing.T) {
t.Fatalf("all 36 rolls: returned %d, wins %d", totalReturned, wins)
}
}
+
+func TestSimplifiedCrapsAutomaticCountdownAndRoll(t *testing.T) {
+ tb := variantFixture("simplified")
+ tb.join("alice")
+ w := &testWallet{chips: 100}
+ events := tb.bet("alice", "pass", 10, w)
+ if text := crapsEventText(events); strings.Contains(strings.ToLower(text), "shake") {
+ t.Fatal("countdown started before the clock", text)
+ }
+ if v := tb.view(); v.ShootIn != 3 || v.DealerIn != 0 {
+ t.Fatal("no 3-second automatic window", v.ShootIn, v.DealerIn)
+ }
+ if text := crapsEventText(tb.tickElapsed(600 * time.Millisecond)); strings.Contains(strings.ToLower(text), "dice") {
+ t.Fatal("countdown fired early", text)
+ }
+ events = tb.tickElapsed(600 * time.Millisecond) // 1.2s
+ text := crapsEventText(events)
+ if !strings.Contains(text, "dice") || !strings.Contains(text, "alice") {
+ t.Fatal("first countdown line missing", text)
+ }
+ if !events[0].Public || events[0].PrivateMessage == "" {
+ t.Fatal("countdown must broadcast and speak to the shooter", events[0])
+ }
+ if text := crapsEventText(tb.tickElapsed(600 * time.Millisecond)); strings.Contains(strings.ToLower(text), "luck") {
+ t.Fatal("second countdown fired early", text)
+ }
+ events = tb.tickElapsed(600 * time.Millisecond) // 2.4s
+ if text := crapsEventText(events); !strings.Contains(text, "luck") {
+ t.Fatal("second countdown line missing", text)
+ }
+ if tb.dice != [2]int{} {
+ t.Fatal("rolled before 3 seconds", tb.dice)
+ }
+ events = tb.tickElapsed(600 * time.Millisecond) // 3.0s
+ text = strings.ToLower(crapsEventText(events))
+ if !strings.Contains(text, "shake") {
+ t.Fatal("third countdown line missing", crapsEventText(events))
+ }
+ if tb.dice == [2]int{} {
+ t.Fatal("dice did not roll automatically")
+ }
+ if tb.view().ShootIn != 0 {
+ t.Fatal("window stayed open after the roll")
+ }
+ // A rejected manual roll says the game rolls by itself.
+ tb = variantFixture("simplified")
+ tb.join("alice")
+ w = &testWallet{chips: 100}
+ tb.bet("alice", "pass", 10, w)
+ if text := crapsEventText(tb.action("alice", "roll")); !strings.Contains(text, "rolls by itself") {
+ t.Fatal(text)
+ }
+ if text := crapsEventText(tb.action("alice", "autoroll")); !strings.Contains(text, "rolls by itself") {
+ t.Fatal(text)
+ }
+ // Multiplayer: a single shared countdown, no 10-second manual window.
+ tb = variantFixture("simplified")
+ tb.join("alice")
+ tb.join("bob")
+ w = &testWallet{chips: 1000}
+ tb.bet("alice", "pass", 10, w)
+ if text := crapsEventText(tb.syncRoundClock()); strings.Contains(text, "10 seconds") {
+ t.Fatal("simplified opened a manual betting window", text)
+ }
+ tb.tickElapsed(3 * time.Second)
+ if tb.dice == [2]int{} {
+ t.Fatal("multiplayer countdown did not roll")
+ }
+}
+
+func TestSimplifiedCrapsCommandsHideRollAndRebet(t *testing.T) {
+ tb := variantFixture("simplified")
+ tb.join("alice")
+ w := &testWallet{chips: 100}
+ tb.bet("alice", "pass", 10, w)
+ tb.tickElapsed(3 * time.Second)
+ cmds := tb.commands("alice")
+ for _, c := range cmds {
+ if c.Command == "roll" || c.Command == "autoroll" {
+ t.Fatal("simplified offered a roll command", c)
+ }
+ }
+ joined := make([]string, len(cmds))
+ for i, c := range cmds {
+ joined[i] = c.Command
+ }
+ if strings.Contains(strings.Join(joined, "|"), "on pass") {
+ t.Fatal("simplified bet command still names a target", joined)
+ }
+ spot, amount := tb.rebet("alice")
+ if spot != "pass" || amount != 10 {
+ t.Fatal("bare bet must rebet the last wager", spot, amount)
+ }
+}
+
+func TestSimplifiedCrapsBetDefaultsToPass(t *testing.T) {
+ tb := variantFixture("simplified")
+ tb.join("alice")
+ w := &testWallet{chips: 100}
+ tb.bet("alice", "", 10, w)
+ bets := tb.players.get("alice").bets
+ if len(bets) != 1 || bets[0].kind != "pass" {
+ t.Fatal("targetless bet did not land on pass", bets)
+ }
+}