Initial pass at Golden Pack.

This commit is contained in:
Greyson Parrelli
2026-07-24 07:47:05 -04:00
parent e74f983470
commit dd395f4bbf
27 changed files with 2770 additions and 150 deletions
+41
View File
@@ -11,7 +11,26 @@ import (
// It fails the test if a bot ever produces an illegal action or the game
// stops making progress.
func playBotGame(t *testing.T, levelA, levelB float64) *game.Game {
return playBotGamePack(t, game.DefaultPack, levelA, levelB)
}
// forcePlayable temporarily marks a (possibly gated) pack Playable so tests can
// start a game on it, returning a restore func.
func forcePlayable(id string) func() {
for i := range game.Packs {
if game.Packs[i].ID == id {
prev := game.Packs[i].Playable
game.Packs[i].Playable = true
idx := i
return func() { game.Packs[idx].Playable = prev }
}
}
return func() {}
}
func playBotGamePack(t *testing.T, pack string, levelA, levelB float64) *game.Game {
t.Helper()
defer forcePlayable(pack)()
g := game.New()
pa, err := g.AddBot("Bot A", levelA)
if err != nil {
@@ -21,6 +40,9 @@ func playBotGame(t *testing.T, levelA, levelB float64) *game.Game {
if err != nil {
t.Fatalf("AddBot B: %v", err)
}
if err := g.SetPack(pack); err != nil {
t.Fatalf("SetPack %s: %v", pack, err)
}
if err := g.StartGame(); err != nil {
t.Fatalf("StartGame: %v", err)
}
@@ -68,12 +90,18 @@ func applyAction(g *game.Game, playerID string, a *Action) error {
switch a.Type {
case "buy":
return g.Buy(playerID, a.Row)
case "buyAvocado":
return g.BuyAvocado(playerID, a.Row)
case "sell":
return g.Sell(playerID, a.Cards)
case "trade":
return g.TradeStart(playerID, a.Cards)
case "tradeChoose":
return g.TradeChoose(playerID, a.Pick)
case "revealChoose":
return g.RevealChoose(playerID, a.CardID)
case "battleChoose":
return g.BattleChoose(playerID, a.Value)
case "pass":
return g.Pass(playerID)
case "arrange":
@@ -98,6 +126,19 @@ func TestBotsFinishGames(t *testing.T) {
}
}
// TestBotsFinishGoldenGame plays complete games on the Golden pack (tiers 1-3
// printed; 4-6 empty). It exercises the Trumpet/Golden Retriever/Cone Snail
// battle mechanics via SimulateBattle rollouts and the new shop effects, and
// fails on any illegal or missing bot action.
func TestBotsFinishGoldenGame(t *testing.T) {
for range 5 {
g := playBotGamePack(t, "golden", 1, 0.6)
if g.Round != game.MaxRounds {
t.Errorf("golden game ended on round %d, want %d", g.Round, game.MaxRounds)
}
}
}
// TestObserveTracksOpponentDeck checks the memory's opponent model against
// the opponent's real deck after known public actions. The model may only
// contain information a human spectator would have.