package ai import ( "encoding/json" "testing" "github.com/greyson/super-auto-pets-board-game/internal/game" ) // A debug report is only worth taking if replaying it reproduces the battle it // captured, and the situations worth reporting are the messy ones — six seats, // three packs shuffled together, Mana and Trumpets banked, Komodo shuffling // apples into a deck mid-fight. This test lives in the ai package because that // is where full games get played: it hands the bots a table, then replays every // battle of the last round out of the report and demands the identical result. // // If it ever fails, the engine has grown a source of randomness (or a piece of // battle input) that the result doesn't record, and reports of that battle are // no longer reproducible. func TestDebugReportReplaysRealGames(t *testing.T) { for _, tc := range []struct { name string packs []string levels []float64 }{ {"two seats, one pack", []string{"turtle"}, []float64{0.9, 0.9}}, {"six seats, three packs", []string{"turtle", "golden", "unicorn"}, []float64{0.9, 0.9, 0.9, 0.9, 0.9, 0.9}}, } { t.Run(tc.name, func(t *testing.T) { g := playBotTable(t, tc.packs, tc.levels...) rep, err := g.DebugReport() if err != nil { t.Fatal(err) } if len(g.Battles) == 0 { t.Fatal("a finished game should have battles to replay") } for i, recorded := range g.Battles { replayed, err := rep.ReplayBattle(i) if err != nil { t.Fatalf("battle %d: %v", i, err) } if got, want := marshal(t, replayed), marshal(t, recorded); got != want { t.Fatalf("battle %d replayed differently:\nrecorded %s\nreplayed %s", i, want, got) } } }) } } func marshal(t *testing.T, res *game.BattleResult) string { t.Helper() b, err := json.Marshal(res) if err != nil { t.Fatal(err) } return string(b) }