Fix nurse shark and remove mid-battle choice.
This commit is contained in:
@@ -2,11 +2,11 @@ package game
|
||||
|
||||
import "testing"
|
||||
|
||||
// --- Nurse Shark: the mid-battle decision channel ---
|
||||
// --- Nurse Shark ---
|
||||
|
||||
// Nurse Shark suspends the battle to ask how many Trumpets to spend, then
|
||||
// resumes and throws two rocks per Trumpet spent.
|
||||
func TestNurseSharkSuspendsAndResumes(t *testing.T) {
|
||||
// Nurse Shark automatically spends every available Trumpet (up to 3), throwing
|
||||
// two rocks per Trumpet spent.
|
||||
func TestNurseSharkSpendsAllTrumpets(t *testing.T) {
|
||||
g, _, _ := testGame(t)
|
||||
g.RollDie = func() int { return 2 } // each rock deals 2
|
||||
res := forceBattle(t, g,
|
||||
@@ -14,25 +14,9 @@ func TestNurseSharkSuspendsAndResumes(t *testing.T) {
|
||||
[]Card{g.pet("Big", 4), g.pet("Tank", 6)},
|
||||
)
|
||||
// Nyala trades with Big (banking 2 Trumpets), then Nurse Shark enters and
|
||||
// the battle suspends on its choice.
|
||||
if g.PendingBattle == nil {
|
||||
t.Fatal("expected the battle to suspend on Nurse Shark's choice")
|
||||
}
|
||||
if g.PendingBattle.Seat != 0 || g.PendingBattle.Max != 2 || g.PendingBattle.Kind != "nurseShark" {
|
||||
t.Fatalf("unexpected pending decision: %+v", g.PendingBattle)
|
||||
}
|
||||
if res.WinnerSeat != -1 {
|
||||
t.Fatalf("a suspended battle has no winner yet, got %d", res.WinnerSeat)
|
||||
}
|
||||
// Spend both Trumpets: 4 rocks (2+2+2+2 = 8) kill the 6-power Tank.
|
||||
if err := g.BattleChoose(g.Players[0].ID, 2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if g.PendingBattle != nil {
|
||||
t.Fatalf("battle should have completed: %+v", g.PendingBattle)
|
||||
}
|
||||
// spends both: 4 rocks (2+2+2+2 = 8) kill the 6-power Tank.
|
||||
spends := 0
|
||||
for _, ev := range eventsOfType(g.Battle, "trumpet") {
|
||||
for _, ev := range eventsOfType(res, "trumpet") {
|
||||
if ev.Count < 0 {
|
||||
spends++
|
||||
}
|
||||
@@ -40,44 +24,51 @@ func TestNurseSharkSuspendsAndResumes(t *testing.T) {
|
||||
if spends != 1 {
|
||||
t.Fatalf("expected one trumpet spend, got %d", spends)
|
||||
}
|
||||
rocks := eventsOfType(g.Battle, "rock")
|
||||
rocks := eventsOfType(res, "rock")
|
||||
if len(rocks) != 1 || len(rocks[0].Dice) != 4 || !rocks[0].TargetDied {
|
||||
t.Fatalf("Nurse Shark should throw 4 rocks (2 per Trumpet) and kill Tank: %+v", rocks)
|
||||
}
|
||||
if g.Battle.WinnerSeat != 0 {
|
||||
t.Fatalf("seat 0 should win, got %d", g.Battle.WinnerSeat)
|
||||
if res.WinnerSeat != 0 {
|
||||
t.Fatalf("seat 0 should win, got %d", res.WinnerSeat)
|
||||
}
|
||||
}
|
||||
|
||||
// Choosing to spend zero Trumpets throws no rocks.
|
||||
func TestNurseSharkSpendZero(t *testing.T) {
|
||||
// The spend is capped at 3 Trumpets even when more are banked.
|
||||
func TestNurseSharkCapsAtThree(t *testing.T) {
|
||||
g, _, _ := testGame(t)
|
||||
g.RollDie = func() int { return 2 }
|
||||
forceBattle(t, g,
|
||||
[]Card{g.goldenPet(t, "Nyala"), g.goldenPet(t, "Nurse Shark")},
|
||||
[]Card{g.pet("Big", 4), g.pet("Tank", 6)},
|
||||
g.RollDie = func() int { return 1 } // each rock deals 1
|
||||
g.Players[0].PendingTrumpets = 5 // seed a pool larger than the cap
|
||||
res := forceBattle(t, g,
|
||||
[]Card{g.goldenPet(t, "Nurse Shark")},
|
||||
[]Card{g.pet("Wall", 20)},
|
||||
)
|
||||
if g.PendingBattle == nil {
|
||||
t.Fatal("expected a pending decision")
|
||||
var spend *BattleEvent
|
||||
for i, ev := range res.Events {
|
||||
if ev.Type == "trumpet" && ev.Count < 0 {
|
||||
spend = &res.Events[i]
|
||||
}
|
||||
}
|
||||
if err := g.BattleChoose(g.Players[0].ID, 0); err != nil {
|
||||
t.Fatal(err)
|
||||
if spend == nil || spend.Count != -3 {
|
||||
t.Fatalf("Nurse Shark should spend exactly 3 Trumpets: %+v", eventsOfType(res, "trumpet"))
|
||||
}
|
||||
if len(eventsOfType(g.Battle, "rock")) != 0 {
|
||||
t.Fatal("spending zero Trumpets should throw no rocks")
|
||||
rocks := eventsOfType(res, "rock")
|
||||
if len(rocks) != 1 || len(rocks[0].Dice) != 6 {
|
||||
t.Fatalf("spending 3 Trumpets should throw 6 rocks: %+v", rocks)
|
||||
}
|
||||
}
|
||||
|
||||
// With no Trumpets, Nurse Shark's choice is trivial (max 0) and the rollout
|
||||
// path auto-resolves without suspending.
|
||||
func TestNurseSharkAutoResolvesInRollout(t *testing.T) {
|
||||
// With no Trumpets, Nurse Shark throws no rocks and the battle still resolves.
|
||||
func TestNurseSharkNoTrumpets(t *testing.T) {
|
||||
res := SimulateBattle(1, 0,
|
||||
[]Card{cardWithName("Nurse Shark", 3, []Effect{{Trigger: TriggerPlay, Action: ActionSpendRocks, Count: 3}})},
|
||||
[]Card{{ID: "x", Kind: KindPet, Name: "Foe", Power: 2}},
|
||||
func() int { return 2 },
|
||||
)
|
||||
if res == nil || res.WinnerSeat < -1 {
|
||||
t.Fatalf("rollout should complete without suspending: %+v", res)
|
||||
t.Fatalf("battle should resolve: %+v", res)
|
||||
}
|
||||
if len(eventsOfType(res, "rock")) != 0 {
|
||||
t.Fatal("with no Trumpets, Nurse Shark should throw no rocks")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user