174 lines
5.6 KiB
Go
174 lines
5.6 KiB
Go
package game
|
|
|
|
import "testing"
|
|
|
|
// Highland Cow banks Trumpets equal to its power on entry.
|
|
func TestHighlandCowTrumpetsFromPower(t *testing.T) {
|
|
g, _, _ := testGame(t)
|
|
res := forceBattle(t, g,
|
|
[]Card{g.goldenPet(t, "Highland Cow")}, // power 3
|
|
[]Card{g.pet("Foe", 1)},
|
|
)
|
|
var gain *BattleEvent
|
|
for i, ev := range res.Events {
|
|
if ev.Type == "trumpet" && ev.Seat == 0 && ev.Count == 3 {
|
|
gain = &res.Events[i]
|
|
}
|
|
}
|
|
if gain == nil {
|
|
t.Fatalf("Highland Cow should bank 3 Trumpets (its power): %+v", eventsOfType(res, "trumpet"))
|
|
}
|
|
}
|
|
|
|
// Wildebeest spends 3 Trumpets on entry to shield its first hit.
|
|
func TestWildebeestSpendsForShield(t *testing.T) {
|
|
g, _, _ := testGame(t)
|
|
res := forceBattle(t, g,
|
|
[]Card{g.goldenPet(t, "Highland Cow"), g.goldenPet(t, "Wildebeest")}, // Cow banks 3
|
|
[]Card{g.pet("Chip", 1), g.pet("Hitter", 6)},
|
|
)
|
|
// Cow banks 3 Trumpets and trades with Chip, then dies to Hitter; Wildebeest
|
|
// enters, spends the 3 Trumpets for a shield, and blocks Hitter's blow.
|
|
spent := false
|
|
for _, ev := range eventsOfType(res, "trumpet") {
|
|
if ev.Seat == 0 && ev.Count == -3 {
|
|
spent = true
|
|
}
|
|
}
|
|
if !spent {
|
|
t.Fatalf("Wildebeest should spend 3 Trumpets: %+v", eventsOfType(res, "trumpet"))
|
|
}
|
|
if len(eventsOfType(res, "shield")) == 0 {
|
|
t.Fatal("Wildebeest should block a hit with its shield")
|
|
}
|
|
if res.WinnerSeat != 0 {
|
|
t.Fatalf("Wildebeest should survive the block and win, got %d", res.WinnerSeat)
|
|
}
|
|
}
|
|
|
|
// Grizzly Bear throws a rock per friendly fainted pet.
|
|
func TestGrizzlyRocksPerFainted(t *testing.T) {
|
|
g, _, _ := testGame(t)
|
|
g.RollDie = func() int { return 2 }
|
|
res := forceBattle(t, g,
|
|
[]Card{g.pet("F1", 1), g.pet("F2", 1), g.goldenPet(t, "Grizzly Bear")},
|
|
[]Card{g.pet("K1", 1), g.pet("K2", 1), g.pet("Tank", 2)},
|
|
)
|
|
rocks := eventsOfType(res, "rock")
|
|
if len(rocks) != 1 || len(rocks[0].Dice) != 2 || !rocks[0].TargetDied {
|
|
t.Fatalf("Grizzly should throw 2 rocks (one per friendly faint) and kill Tank: %+v", rocks)
|
|
}
|
|
}
|
|
|
|
// Catfish reactivates every pet's Buy ability at battle prep.
|
|
func TestCatfishReactivatesBuys(t *testing.T) {
|
|
g, p1, _ := goldenGame(t)
|
|
p1.Deck = []Card{g.goldenPet(t, "Catfish"), g.realPet(t, "Otter")} // Otter buy: +1 apple
|
|
g.beginArrange()
|
|
if countApplesIn(p1.Deck) != 1 {
|
|
t.Fatalf("Catfish should re-fire Otter's buy for 1 apple, got %d", countApplesIn(p1.Deck))
|
|
}
|
|
}
|
|
|
|
// Komodo shuffles 6 apples into the deck when it is the first pet.
|
|
func TestKomodoShufflesApplesFirstPet(t *testing.T) {
|
|
g, _, _ := testGame(t)
|
|
res := forceBattle(t, g,
|
|
[]Card{g.goldenPet(t, "Komodo")}, // power 6, first pet
|
|
[]Card{g.pet("Foe", 1)},
|
|
)
|
|
apples := 0
|
|
for _, ev := range eventsOfType(res, "summon") {
|
|
if ev.Card != nil && ev.Card.Name == "Apple" && ev.Seat == 0 {
|
|
apples++
|
|
}
|
|
}
|
|
if apples != 6 {
|
|
t.Fatalf("Komodo should shuffle 6 apples in as the first pet, got %d", apples)
|
|
}
|
|
}
|
|
|
|
// Komodo does nothing when it is not the first pet played.
|
|
func TestKomodoNoShuffleWhenNotFirst(t *testing.T) {
|
|
g, _, _ := testGame(t)
|
|
res := forceBattle(t, g,
|
|
[]Card{g.pet("Weak", 1), g.goldenPet(t, "Komodo")},
|
|
[]Card{g.pet("K", 1), g.pet("Foe", 1)},
|
|
)
|
|
for _, ev := range eventsOfType(res, "summon") {
|
|
if ev.Card != nil && ev.Card.Name == "Apple" {
|
|
t.Fatal("Komodo should not shuffle apples when it isn't the first pet")
|
|
}
|
|
}
|
|
}
|
|
|
|
// Bird of Paradise banks 2 apples-in-play and 2 Trumpets for the next battle.
|
|
func TestBirdOfParadiseBuy(t *testing.T) {
|
|
g, p1, _ := goldenGame(t)
|
|
g.ShopRow[0] = g.goldenPet(t, "Bird of Paradise")
|
|
g.Turn = 0
|
|
if err := g.Buy(p1.ID, 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if p1.PendingApplesInPlay != 2 || p1.PendingTrumpets != 2 {
|
|
t.Fatalf("Bird of Paradise should bank 2 apples + 2 Trumpets, got %d/%d",
|
|
p1.PendingApplesInPlay, p1.PendingTrumpets)
|
|
}
|
|
}
|
|
|
|
// The banked Trumpets appear in the pool at battle start, and reset after.
|
|
func TestPendingTrumpetsSeedBattle(t *testing.T) {
|
|
g, p1, _ := testGame(t)
|
|
p1.PendingTrumpets = 2
|
|
res := forceBattle(t, g, []Card{g.pet("Hero", 3)}, []Card{g.pet("Foe", 1)})
|
|
var seeded *BattleEvent
|
|
for i, ev := range res.Events {
|
|
if ev.Type == "trumpet" && ev.Seat == 0 && ev.Count == 2 {
|
|
seeded = &res.Events[i]
|
|
}
|
|
}
|
|
if seeded == nil {
|
|
t.Fatalf("the battle should start with 2 Trumpets in the pool: %+v", eventsOfType(res, "trumpet"))
|
|
}
|
|
if p1.PendingTrumpets != 0 {
|
|
t.Fatalf("PendingTrumpets should reset after the battle, got %d", p1.PendingTrumpets)
|
|
}
|
|
}
|
|
|
|
// German Shepherd guards the Golden Retriever's first hit.
|
|
func TestGermanShepherdGuardsRetriever(t *testing.T) {
|
|
g, _, _ := testGame(t)
|
|
res := forceBattle(t, g,
|
|
[]Card{g.goldenPet(t, "German Shepherd"), g.goldenPet(t, "Nyala")}, // Nyala banks 2 Trumpets
|
|
[]Card{g.pet("BigA", 5), g.pet("BigB", 9)},
|
|
)
|
|
// German Shepherd faints (guard aside), Nyala faints (+2 Trumpets), then the
|
|
// Golden Retriever arrives and its first hit is shaved by 5.
|
|
var guarded *BattleEvent
|
|
for i, ev := range res.Events {
|
|
if ev.Type == "prevent" && ev.Seat == 0 && ev.Count == 5 {
|
|
guarded = &res.Events[i]
|
|
}
|
|
}
|
|
if guarded == nil {
|
|
t.Fatalf("the Golden Retriever's first hit should be guarded for 5: %+v", eventsOfType(res, "prevent"))
|
|
}
|
|
}
|
|
|
|
// Tomato is a perk that throws 4 rocks on play.
|
|
func TestTomatoThrowsRocks(t *testing.T) {
|
|
g, _, _ := testGame(t)
|
|
g.RollDie = func() int { return 1 }
|
|
res := forceBattle(t, g,
|
|
[]Card{g.goldenFood(t, "Tomato"), g.pet("Holder", 2)},
|
|
[]Card{g.pet("Tank", 3)},
|
|
)
|
|
rocks := eventsOfType(res, "rock")
|
|
if len(rocks) != 1 || rocks[0].Roll != 4 || !rocks[0].TargetDied {
|
|
t.Fatalf("Tomato should throw 4 rocks and kill the 3-power Tank: %+v", rocks)
|
|
}
|
|
if res.WinnerSeat != 0 {
|
|
t.Fatalf("seat 0 should win, got %d", res.WinnerSeat)
|
|
}
|
|
}
|