package casino import ( "strconv" "testing" ) func TestRouletteAnimationTiming(t *testing.T) { for _, multiplayer := range []bool{false, true} { table := rouletteFixture() table.Config.Roulette.SpinTicks = 8 table.join("a") if multiplayer { table.join("b") } events := table.bet("a", "red", 10, &testWallet{chips: 100}) if multiplayer { table.tick() events = table.tick() } for _, e := range events { if e.Snapshot != nil { t.Fatal("spin announcement contains old wheel") } } var final *RouletteSnapshot for tick := 1; tick <= 8; tick++ { events = table.tick() switch { case tick <= 5: if len(events) != 1 { t.Fatalf("tick %d: missing frame", tick) } s := events[0].Snapshot.(*RouletteSnapshot) if s.SpinFrame != tick || s.BallPosition < -1 || s.BallPosition >= 10 { t.Fatalf("bad frame: %+v", s) } final = s case tick < 8: if len(events) != 0 { t.Fatalf("tick %d: pause interrupted", tick) } default: if len(events) == 0 || events[0].Snapshot.(*RouletteSnapshot).Phase != "result" { t.Fatal("missing result at tick 8") } result := events[0].Snapshot.(*RouletteSnapshot) if final.BallPosition < 0 || final.SpinPockets[final.BallPosition] != result.Pockets[2] { t.Fatal("final ball disagrees with result") } } } } } func TestRouletteSpinFramePockets(t *testing.T) { table := rouletteFixture() for frame := 1; frame <= 4; frame++ { for green := 1; green <= 36; green++ { for _, showBall := range []bool{false, true} { s := table.spinFrame(frame, showBall, 3, green) if (s.BallPosition == 3) != showBall || (!showBall && s.BallPosition != -1) { t.Fatal("ball visibility ignored") } want := "1" if frame%2 == 0 { want = "2" } if s.SpinPockets[0] != want { t.Fatal("starting color did not alternate") } for i, pocket := range s.SpinPockets { if pocket == "0" && (i == 0 || i == 9 || s.SpinPockets[i-1] == s.SpinPockets[i+1]) { t.Fatalf("green not between red and black: %v", s.SpinPockets) } } } } } for _, double := range []bool{false, true} { table.Config.Roulette.DoubleZero = double wheel := rouletteWheel(double) for index, winner := range wheel { table.winningIndex = index s := table.spinFrame(5, false, 0, 0) start, _ := strconv.Atoi(s.SpinPockets[0]) if !rouletteRed(start) { t.Fatal("final strip must start red after the black-starting fourth strip") } if s.BallPosition < 1 || s.BallPosition >= 9 || s.SpinPockets[s.BallPosition] != winner { t.Fatalf("missing winning ball for %s", winner) } for i, pocket := range s.SpinPockets { if pocket != wheel[(index+i-s.BallPosition+len(wheel))%len(wheel)] { t.Fatalf("wrong physical neighbors for %s", winner) } } if !double && winner == "26" && s.SpinPockets[s.BallPosition+1] != "0" { t.Fatal("26 must have green to its right") } } } }