diff options
| author | historia <[not public]> | 2026-09-30 16:16:17 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-30 16:16:17 -0400 |
| commit | a4c09c2d38d1f3bc1d3ad4bdb0234bdea7c37e73 (patch) | |
| tree | 00c9567e620f331a59dd44f1f1fa779ecd94a845 /internal/casino/command_hints_test.go | |
| parent | 724079f8de1ae69965c6267dca3d7fc3cc86afa2 (diff) | |
| download | thehouseoficarus-a4c09c2d38d1f3bc1d3ad4bdb0234bdea7c37e73.tar.gz | |
feat: additional craps variants added, standardizard casino command hints
Diffstat (limited to 'internal/casino/command_hints_test.go')
| -rw-r--r-- | internal/casino/command_hints_test.go | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/internal/casino/command_hints_test.go b/internal/casino/command_hints_test.go new file mode 100644 index 0000000..c570e15 --- /dev/null +++ b/internal/casino/command_hints_test.go @@ -0,0 +1,155 @@ +package casino + +import ( + "strings" + "testing" + "time" +) + +func hintHas(commands []MenuCommand, command string) bool { + for _, c := range commands { + if c.Command == command { + return true + } + } + return false +} +func hintBet(commands []MenuCommand) bool { + for _, c := range commands { + if strings.HasPrefix(c.Command, "bet") { + return true + } + } + return false +} +func TestCrapsHintsFollowPlayerState(t *testing.T) { + for _, v := range crapsVariants { + tb := variantFixture(v) + tb.join("a") + w := &testWallet{chips: 1000} + commands := tb.commands("a") + if !hintBet(commands) || !hintHas(commands, "stop") { + t.Fatal(v, "missing idle actions", commands) + } + for _, c := range []string{"roll", "autoroll", "unbet <target> / unbet all"} { + if hintHas(commands, c) { + t.Fatal(v, "idle", c) + } + } + tb.bet("a", "pass", 10, w) + commands = tb.commands("a") + if !hintHas(commands, "roll") || !hintHas(commands, "autoroll") || hintHas(commands, "unbet <target> / unbet all") { + t.Fatal(v, "contract actions", commands) + } + if !tb.Config.Craps.allows("buy") && hintBet(commands) { + t.Fatal(v, "duplicate pass advertised") + } + tb.action("a", "autoroll") + if hintHas(tb.commands("a"), "autoroll") { + t.Fatal(v, "already enabled") + } + tb.join("b") + if hintHas(tb.commands("a"), "roll") { + t.Fatal(v, "roll before betting window ends") + } + tb.players.get("a").autoRoll = false + tb.bet("b", "pass", 10, &testWallet{chips: 1000}) + tb.tickElapsed(10 * time.Second) + if !hintHas(tb.commands("a"), "roll") || hintHas(tb.commands("b"), "roll") { + t.Fatal(v, "wrong shooter hints") + } + watch := tb.commands("watcher") + if len(watch) != 1 || watch[0].Command != "table" { + t.Fatal(v, "spectator actions", watch) + } + } +} +func TestCrapsHintsOnlyOfferRemovableWagers(t *testing.T) { + tb := crapsFixture() + tb.join("a") + w := &testWallet{chips: 1000} + tb.bet("a", "pass", 10, w) + tb.resolveRoll(2, 2) + if hintHas(tb.commands("a"), "unbet <target> / unbet all") { + t.Fatal("contract removable") + } + tb.bet("a", "odds pass", 10, w) + if !hintHas(tb.commands("a"), "unbet <target> / unbet all") { + t.Fatal("odds not removable") + } + tb.action("a", "unbet odds pass") + if hintHas(tb.commands("a"), "unbet <target> / unbet all") { + t.Fatal("removed odds still advertised") + } + tb.bet("a", "place 6", 12, w) + if !hintHas(tb.commands("a"), "unbet <target> / unbet all") { + t.Fatal("place removal missing") + } +} +func TestOtherCasinoHintsRespectCommitment(t *testing.T) { + bj := newBlackjackTable(1, TableConfig{ID: "bj", Game: GameBlackjack, BettingTicks: 10}, newTestRand()) + bj.join("a") + bj.join("b") + bj.bet("a", "", 10, &testWallet{chips: 1000}) + if hintBet(bj.menuEvent("a").Menu.Commands) { + t.Fatal("blackjack duplicate bet advertised") + } + if !hintBet(bj.menuEvent("b").Menu.Commands) { + t.Fatal("blackjack missing eligible bet") + } + bac := newBaccaratTable(1, TableConfig{ID: "bac", Game: GameBaccarat, BettingTicks: 10}, newTestRand()) + bac.join("a") + bac.join("b") + bac.bet("a", "banker", 10, &testWallet{chips: 1000}) + if hintBet(bac.menuEvent("a").Menu.Commands) { + t.Fatal("baccarat duplicate bet advertised") + } + if !hintBet(bac.menuEvent("b").Menu.Commands) { + t.Fatal("baccarat missing eligible bet") + } + r := newRouletteTable(1, TableConfig{ID: "r", Game: GameRoulette, BettingTicks: 10}, newTestRand()) + r.join("a") + r.join("b") + if hintHas(r.menuEvent("a").Menu.Commands, "bet / rebet") { + t.Fatal("roulette no wager to repeat") + } + r.bet("a", "red", 10, &testWallet{chips: 1000}) + if hintBet(r.menuEvent("a").Menu.Commands) { + t.Fatal("roulette duplicate bet advertised") + } + if !hintBet(r.menuEvent("b").Menu.Commands) { + t.Fatal("roulette missing eligible bet") + } + r.phase = phasePlaying + if hintBet(r.menuEvent("b").Menu.Commands) { + t.Fatal("roulette spinning bets advertised") + } + r.phase = phaseWaiting + r.players.get("a").HasBet = false + if !hintHas(r.menuEvent("a").Menu.Commands, "bet / rebet") { + t.Fatal("roulette repeat missing") + } +} +func TestSlotHintsRequirePriorWager(t *testing.T) { + m := newMachine(1, MachineConfig{ID: "slots", Game: GameSlots}, newTestRand()) + m.join("a") + for _, c := range []string{"spin", "autospin"} { + if hintHas(m.commands(), c) { + t.Fatal("fresh slots", c) + } + } + m.bet = 10 + for _, c := range []string{"spin", "autospin"} { + if !hintHas(m.commands(), c) { + t.Fatal("configured slots", c) + } + } + m.autoBet = true + if commands := m.commands(); len(commands) != 1 || commands[0].Command != "stop" { + t.Fatal("autospin hints", commands) + } + m.phase = machineSpinning + if events := m.privateMenu(""); events[0].Menu != nil { + t.Fatal("manual commands during spin") + } +} |
