diff --git a/SVSim.BattleNode/Sessions/Engine/SessionBattleEngine.cs b/SVSim.BattleNode/Sessions/Engine/SessionBattleEngine.cs
index a198da8..ef5d2d3 100644
--- a/SVSim.BattleNode/Sessions/Engine/SessionBattleEngine.cs
+++ b/SVSim.BattleNode/Sessions/Engine/SessionBattleEngine.cs
@@ -224,7 +224,7 @@ internal sealed class SessionBattleEngine
/// evolve spends one EP, so the evolve test asserts this decrements by 1. EP is granted at setup by
/// the engine's SetupEvolCount (2 for the game-first seat, 3 for the second) and unlocks once
/// EvolveWaitTurnCount has counted down (M-HC-4b).
- public int Ep(bool playerSeat) => Seat(playerSeat).CurrentEpCount;
+ public int EpCount(bool playerSeat) => Seat(playerSeat).CurrentEpCount;
/// Turns remaining until may evolve
/// (); 0 means evolve is unlocked. Lets a test ramp to
diff --git a/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs b/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs
index 7b37fa6..3459bf8 100644
--- a/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs
+++ b/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs
@@ -461,24 +461,13 @@ public class HeadlessConductorTests
int attackerIdx = harness.InPlayCardIndex(playerSeat: true, boardPos: 0);
// --- ramp seat A to the turn its evolve unlocks (EvolveWaitTurnCount counts down per seat-A turn) ---
- // End turn 1 first (TurnEnd sets NowTurnEvol = true, the other CanEvolution precondition), then
- // alternate A/B TurnStart/TurnEnd until seat A's EvolveWaitTurnCount reaches 0, leaving seat A's
- // turn OPEN. A guard bounds the loop so a never-unlocking bug fails loud instead of hanging.
+ // End turn 1 first (TurnEnd sets NowTurnEvol = true, the other CanEvolution precondition), then ramp.
Assert.That(harness.Push(NetworkBattleUri.TurnEnd, TurnEndBody(), isPlayerSeat: true).Accepted, Is.True, "turn1 TurnEnd");
- bool seatA = false; // next TurnStart is seat B's
- int guard = 0;
- while (harness.EvolveWaitTurnCount(playerSeat: true) > 0)
- {
- Assert.That(++guard, Is.LessThan(20), "evolve never unlocked — EvolveWaitTurnCount stuck > 0");
- Assert.That(harness.Push(NetworkBattleUri.TurnStart, TurnStartBody(), isPlayerSeat: seatA).Accepted, Is.True, "ramp TurnStart");
- if (seatA && harness.EvolveWaitTurnCount(playerSeat: true) == 0) break; // leave seat A's turn open
- Assert.That(harness.Push(NetworkBattleUri.TurnEnd, TurnEndBody(), isPlayerSeat: seatA).Accepted, Is.True, "ramp TurnEnd");
- seatA = !seatA;
- }
+ RampSeatAToEvolveTurn(harness);
// EP precondition: seat A holds at least 1 evolve point and evolve is now unlocked.
Assert.That(harness.EvolveWaitTurnCount(playerSeat: true), Is.EqualTo(0), "evolve unlocked on seat A's turn");
- int epBefore = harness.Ep(playerSeat: true);
+ int epBefore = harness.EpCount(playerSeat: true);
Assert.That(epBefore, Is.GreaterThanOrEqualTo(1), "seat A must hold >= 1 EP before evolving");
// Pre-evolve stats: the un-evolved vanilla is 1/2 and not yet flagged evolved.
@@ -499,7 +488,7 @@ public class HeadlessConductorTests
"evolved atk must equal the card's evo_atk (3) — base 1 + evolve delta +2");
Assert.That(harness.InPlayCardLife(playerSeat: true, boardPos: 0), Is.EqualTo(evolvedLife),
"evolved life must equal the card's evo_life (4) — base 2 + evolve delta +2");
- Assert.That(harness.Ep(playerSeat: true), Is.EqualTo(epBefore - 1),
+ Assert.That(harness.EpCount(playerSeat: true), Is.EqualTo(epBefore - 1),
"an evolve must spend exactly one evolve point");
}
@@ -923,6 +912,24 @@ public class HeadlessConductorTests
}
}
+ // Ramp seat A to the turn its evolve unlocks (seat A's EvolveWaitTurnCount counts down per seat-A turn),
+ // leaving seat A's turn OPEN. Caller must have already ended seat A's first turn (TurnEnd sets
+ // NowTurnEvol = true, the other CanEvolution precondition) so the next TurnStart is seat B's. A guard
+ // bounds the loop so a never-unlocking bug fails loud instead of hanging.
+ private static void RampSeatAToEvolveTurn(NodeNativeBattleHarness harness)
+ {
+ bool seatA = false; // next TurnStart is seat B's
+ int guard = 0;
+ while (harness.EvolveWaitTurnCount(playerSeat: true) > 0)
+ {
+ Assert.That(++guard, Is.LessThan(20), "evolve never unlocked — EvolveWaitTurnCount stuck > 0");
+ Assert.That(harness.Push(NetworkBattleUri.TurnStart, TurnStartBody(), isPlayerSeat: seatA).Accepted, Is.True, "ramp TurnStart");
+ if (seatA && harness.EvolveWaitTurnCount(playerSeat: true) == 0) break; // leave seat A's turn open
+ Assert.That(harness.Push(NetworkBattleUri.TurnEnd, TurnEndBody(), isPlayerSeat: seatA).Accepted, Is.True, "ramp TurnEnd");
+ seatA = !seatA;
+ }
+ }
+
[Test]
public void Real_spell_charge_drops_engine_cost_and_count_no_seam()
{
@@ -1094,25 +1101,13 @@ public class HeadlessConductorTests
// --- ramp seat A to the turn its evolve unlocks (mirrors Evolve_resolves_on_engine_state_headless) ---
Assert.That(harness.Push(NetworkBattleUri.TurnEnd, TurnEndBody(), isPlayerSeat: true).Accepted, Is.True, "turn1 TurnEnd");
- bool seatA = false; // next TurnStart is seat B's
- int guard = 0;
- while (harness.EvolveWaitTurnCount(playerSeat: true) > 0)
- {
- Assert.That(++guard, Is.LessThan(20), "evolve never unlocked — EvolveWaitTurnCount stuck > 0");
- Assert.That(harness.Push(NetworkBattleUri.TurnStart, TurnStartBody(), isPlayerSeat: seatA).Accepted, Is.True, "ramp TurnStart");
- if (seatA && harness.EvolveWaitTurnCount(playerSeat: true) == 0) break; // leave seat A's turn open
- Assert.That(harness.Push(NetworkBattleUri.TurnEnd, TurnEndBody(), isPlayerSeat: seatA).Accepted, Is.True, "ramp TurnEnd");
- seatA = !seatA;
- }
+ RampSeatAToEvolveTurn(harness);
Assert.That(harness.EvolveWaitTurnCount(playerSeat: true), Is.EqualTo(0), "evolve unlocked on seat A's turn");
- Assert.That(harness.Ep(playerSeat: true), Is.GreaterThanOrEqualTo(1), "seat A must hold >= 1 EP before evolving");
+ Assert.That(harness.EpCount(playerSeat: true), Is.GreaterThanOrEqualTo(1), "seat A must hold >= 1 EP before evolving");
// The reducer must be IN HAND across the evolve (its when_evolve_other skill is scanned off the hand).
int reducerHandIdx = FindHandIdxByCardId(harness, BoardDependentCostCardId);
Assert.That(reducerHandIdx, Is.GreaterThan(0), "the board-dependent cost-reducer must be in seat A's hand at the evolve");
- Assert.That(harness.HandCardId(playerSeat: true,
- FindHandPosByEngineIdx(harness, reducerHandIdx)), Is.EqualTo((int)BoardDependentCostCardId),
- "located the reducer by identity");
// PRE-EVOLVE pin (non-vacuity + causation baseline): the reducer resolves to its BASE cost (6) while
// no follower has evolved yet. Read it WHILE in hand by its engine Index.
@@ -1395,14 +1390,4 @@ public class HeadlessConductorTests
Assert.That(tokenIdx, Is.EqualTo(0),
"FINDING: the autonomous token_draw seats the chosen token at engine Index 0 headless — not addressable by a wire idx");
}
-
- // The hand POSITION (0-based) of the seat-A hand card with the given engine Index, or -1. Lets a test
- // re-derive a HandCardId(seat, pos) lookup from an engine Index it already located by identity.
- private static int FindHandPosByEngineIdx(NodeNativeBattleHarness harness, int engineIdx)
- {
- for (int i = 0; i < harness.HandCount(playerSeat: true); i++)
- if (harness.HandCardIndex(playerSeat: true, i) == engineIdx)
- return i;
- return -1;
- }
}
diff --git a/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs b/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs
index 4634df3..cbac8a5 100644
--- a/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs
+++ b/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs
@@ -281,7 +281,7 @@ internal sealed class NodeNativeBattleHarness : IDisposable
public bool IsEvolved(bool playerSeat, int boardPos) => Engine.IsEvolved(playerSeat, boardPos);
/// The seat's current evolve-point count (M-HC-4b). An evolve spends one EP.
- public int Ep(bool playerSeat) => Engine.Ep(playerSeat);
+ public int EpCount(bool playerSeat) => Engine.EpCount(playerSeat);
/// Turns remaining until the seat may evolve (0 == unlocked) (M-HC-4b).
public int EvolveWaitTurnCount(bool playerSeat) => Engine.EvolveWaitTurnCount(playerSeat);