diff options
Diffstat (limited to 'internal/casino/craps_review_test.go')
| -rw-r--r-- | internal/casino/craps_review_test.go | 119 |
1 files changed, 118 insertions, 1 deletions
diff --git a/internal/casino/craps_review_test.go b/internal/casino/craps_review_test.go index 04f72b2..3a518fc 100644 --- a/internal/casino/craps_review_test.go +++ b/internal/casino/craps_review_test.go @@ -1,6 +1,123 @@ package casino -import "testing" +import ( + "strings" + "testing" +) + +func TestCrapsPointPromptOnlyForPassBettors(t *testing.T) { + tb := crapsFixture() + tb.join("alice") // shooter + tb.join("bob") + w := &testWallet{chips: 1000} + tb.bet("alice", "pass", 10, w) + tb.bet("bob", "field", 10, w) + events := tb.resolveRoll(2, 2) // establishes point 4 + publicPoint := false + var privateTo []string + for _, e := range events { + if e.Public && strings.Contains(e.Message, "POINT 4") { + publicPoint = true + if strings.Contains(e.Message, "Make your point") { + t.Fatalf("public point event still urges the whole room: %q", e.Message) + } + } + if e.PrivateTo != "" && strings.Contains(e.Message, "Make your point") { + privateTo = append(privateTo, e.PrivateTo) + } + } + if !publicPoint { + t.Fatal("no public point event") + } + if len(privateTo) != 1 || privateTo[0] != "alice" { + t.Fatalf("Make your point targeted %v, want [alice]", privateTo) + } +} + +func TestCrapsVigOnlyOnWinsRoundedDown(t *testing.T) { + buy := &crapsBet{kind: "buy", number: 4, stake: Wager{Total: 20}} + if got := crapsReturn(buy, 2, 1, 0, false); got != 59 { + t.Fatalf("winning buy = %d, want 59", got) + } + if got := crapsReturn(buy, -1, 1, 0, false); got != 0 { + t.Fatalf("losing buy returned %d, want 0", got) + } + // A directly-constructed odd stake proves the vig rounds down, not up: + // 5% of 21 is 1.05, so the house keeps 1 credit, not 2. + odd := &crapsBet{kind: "buy", number: 4, stake: Wager{Total: 21}} + if got := crapsReturn(odd, 2, 1, 0, false); got != 62 { // 21 + 42 - 1 + t.Fatalf("buy vig rounded up: %d, want 62", got) + } +} + +func TestCrapsVigUnitsRoundUp(t *testing.T) { + for _, tc := range []struct { + kind string + n int + want int + }{ + {"buy", 4, 20}, {"buy", 6, 20}, + {"lay", 4, 40}, {"lay", 5, 30}, {"lay", 6, 24}, + {"lay", 2, 120}, {"lay", 3, 60}, {"lay", 12, 120}, + } { + if got := crapsVigUnit(tc.kind, tc.n); got != tc.want { + t.Fatalf("%s %d unit = %d, want %d", tc.kind, tc.n, got, tc.want) + } + } + for _, tc := range []struct { + spot string + amount int + want int + }{ + {"buy 6", 3, 20}, {"buy 6", 5, 20}, {"buy 6", 20, 20}, + {"buy 4", 3, 20}, {"buy 4", 21, 40}, + {"lay 6", 30, 48}, {"lay 6", 24, 24}, + } { + tb := crapsFixture() + tb.point = 6 + tb.join("a") + w := &testWallet{chips: 1000} + events := tb.bet("a", tc.spot, tc.amount, w) + bets := tb.players.get("a").bets + if len(bets) != 1 { + t.Fatalf("%s %d was rejected", tc.spot, tc.amount) + } + if got := bets[0].stake.Total; got != tc.want { + t.Fatalf("%s %d rounded to %d, want %d", tc.spot, tc.amount, got, tc.want) + } + if tc.amount != tc.want { + notice := false + for _, e := range events { + if e.PrivateTo == "a" && strings.Contains(e.PrivateMessage, "Rounded up") { + notice = true + } + } + if !notice { + t.Fatalf("%s %d rounded without a notice", tc.spot, tc.amount) + } + } + } +} + +func TestCrapsBusyHoldsAcrossPendingRoll(t *testing.T) { + tb := crapsFixture() + tb.join("alice") + tb.bet("alice", "pass", 10, &testWallet{chips: 100}) + if tb.busy("alice") || tb.busy("bob") { + t.Fatal("table busy before a roll") + } + tb.action("alice", "roll") + if !tb.busy("alice") { + t.Fatal("shooter not busy while the dice are in the air") + } + if tb.busy("bob") { + t.Fatal("non-shooter marked busy") + } + tb.advance(crapsManualRollTicks) + if tb.busy("alice") { + t.Fatal("still busy after the roll resolved") + } +} func TestCrapsTakenDownRollDoesNotCarryIntoNewBet(t *testing.T) { tb := crapsFixture() |
