package casino import ( "reflect" "strconv" "testing" ) func TestPokerEveryCabinetTierGameAndAward(t *testing.T) { for cabinet, games := range cabinetGames { table, _, _ := pokerTestCabinet(t, VideoPokerConfig{Cabinet: cabinet}) for _, tier := range []string{"low", "normal", "full"} { table.action("alice", "payout "+tier) for _, variant := range games { events := table.action("alice", "game "+variant) p := table.players["alice"] if p.variant != variant || p.config.Payout != tier || len(events) != 1 || events[0].Snapshot == nil { t.Fatalf("%s/%s/%s failed selection: %+v", cabinet, tier, variant, p.config) } if err := p.config.Validate(); err != nil { t.Fatal(err) } for _, hands := range CabinetHandCounts(cabinet, variant) { table.action("alice", "hands "+strconv.Itoa(hands)) for _, row := range p.config.PayRows(hands) { if row.Coins[4] <= 0 { t.Fatalf("zero payout: %s", row.Name) } if p.config.Feature == PokerUltimateX && (row.NextAward < 2 || row.NextAward > 12) { t.Fatalf("missing UX award: %s/%s/%d/%s = %d", cabinet, variant, hands, row.Name, row.NextAward) } } } } } table.action("alice", "payout low") table.leave("alice") table.join("bob") if table.players["bob"].config.Payout != "low" { t.Fatal("machine tier changed with occupant") } } } func TestPokerInvalidLoadPreservesPreviousCoins(t *testing.T) { table, _, _ := pokerTestCabinet(t, VideoPokerConfig{Cabinet: CabinetClassic}) table.action("alice", "coins 2") for _, input := range []string{"coins nope", "coins 0", "coins 5", "coins -1", "coins 1 2"} { table.action("alice", input) if table.players["alice"].loaded != 2 || table.players["alice"].lastBet != 2 { t.Fatalf("invalid load %q changed wager", input) } } } func TestPokerDuplicateHoldDigitsToggleOnce(t *testing.T) { table, w, _ := pokerTestCabinet(t, VideoPokerConfig{Cabinet: CabinetClassic}) pokerDeal(t, table, w) table.action("alice", "5 3 1 1 3 5") want := [5]bool{true, false, true, false, true} if table.players["alice"].held != want { t.Fatal("duplicates did not toggle once") } table.action("alice", "hold none") if table.players["alice"].held != want { t.Fatal("hold none changed cards") } table.action("alice", "hold 531") if table.players["alice"].held != ([5]bool{}) { t.Fatal("second hold command did not release cards") } } func TestPokerFailedUXSettlementPreservesBankAndFinalHands(t *testing.T) { table, w, bank := pokerTestCabinet(t, VideoPokerConfig{Cabinet: CabinetUXSingle}) p := table.players["alice"] key := table.multiplierKey(p) table.banks[key] = []int{3} pokerDeal(t, table, w) p.cards = pokerHand("Ah 3h 6h 9h Jh") table.action("alice", "12345") w.fail = true table.action("alice", "draw") frozen := append([]PokerLine(nil), p.lines...) if bank.writes != 0 || !reflect.DeepEqual(table.banks[key], []int{3}) || !p.active { t.Fatal("failed payout consumed old bank") } table.action("alice", "draw") if !reflect.DeepEqual(frozen, p.lines) { t.Fatal("retry changed final cards") } w.fail = false table.action("alice", "draw") if w.paid != 90 || bank.writes != 1 || !reflect.DeepEqual(table.banks[key], []int{10}) { t.Fatalf("retry: paid=%d bank=%v writes=%d", w.paid, table.banks[key], bank.writes) } table.action("alice", "draw") if bank.writes != 1 || w.paid != 90 { t.Fatal("settlement replayed") } table.leave("alice") table.join("bob") snap := table.status("bob")[0].Snapshot.(*VideoPokerSnapshot) if !reflect.DeepEqual(snap.Next, []int{10}) { t.Fatal("new occupant did not inherit earned bank") } } func TestPokerKnownFeatureScheduleValues(t *testing.T) { cases := []struct{ cabinet, tier, variant, table string }{ {CabinetHotRoll, "normal", "jacks_or_better", "9/5"}, {CabinetHotRoll, "normal", "double_double_bonus", "9/5"}, {CabinetSuperTimesPay, "full", "double_double_bonus", "9/6"}, {CabinetSuperTimesPay, "full", "double_bonus", "9/7"}, {CabinetUXMulti, "full", "double_bonus", "9/6/5"}, } for _, tt := range cases { c := (VideoPokerConfig{Cabinet: tt.cabinet, Payout: tt.tier, Variant: tt.variant}).Normalize() if c.PayTable != tt.table { t.Fatalf("%+v => %s", tt, c.PayTable) } } for _, variant := range []string{"bonus_poker", "double_double_bonus"} { cfg := (VideoPokerConfig{Cabinet: CabinetUXSingle, Variant: variant}).Normalize() want := 3 if variant == "double_double_bonus" { want = 4 } for _, category := range []string{"Royal flush", "Straight flush", "Four aces", "Four 2s-4s", "Four 5s-Ks"} { if got := cfg.NextAward(1, category); got != want { t.Fatalf("%s %s: %dx != %dx", variant, category, got, want) } } } }