diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/designations/InitiativeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/designations/InitiativeTest.java new file mode 100644 index 00000000000..246963dad85 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/designations/InitiativeTest.java @@ -0,0 +1,105 @@ +package org.mage.test.cards.designations; + +import mage.constants.MultiplayerAttackOption; +import mage.constants.PhaseStep; +import mage.constants.RangeOfInfluence; +import mage.constants.Zone; +import mage.game.FreeForAll; +import mage.game.Game; +import mage.game.GameException; +import mage.game.mulligan.MulliganType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestMultiPlayerBase; + +import java.io.FileNotFoundException; + +/** + * @author Susucr + */ +public class InitiativeTest extends CardTestMultiPlayerBase { + + @Override + protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { + // reason: must use MultiplayerAttackOption.MULTIPLE + Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7); + // Player order: A -> D -> C -> B + playerA = createPlayer(game, "PlayerA"); + playerB = createPlayer(game, "PlayerB"); + playerC = createPlayer(game, "PlayerC"); + playerD = createPlayer(game, "PlayerD"); + return game; + } + + @Test + public void test_InitiativeByCards() { + // Player order: A -> D -> C -> B + + // When Aarakocra Sneak enters the battlefield, you take the initiative. + addCard(Zone.HAND, playerA, "Aarakocra Sneak", 1); // {3}{U} + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + // + addCard(Zone.HAND, playerD, "Aarakocra Sneak", 1); // {3}{U} + addCard(Zone.BATTLEFIELD, playerD, "Island", 4); + + // no initiative before + checkInitative("no initiative before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, null); + + // A as monarch + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aarakocra Sneak"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + addTarget(playerA, "Mountain"); // search for "Secret Entrance" room + checkInitative("initiative 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerA); + + // D as monarch + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, "Aarakocra Sneak"); + waitStackResolved(2, PhaseStep.PRECOMBAT_MAIN); + addTarget(playerD, "Mountain"); // search for "Secret Entrance" room + checkInitative("initiative 2", 2, PhaseStep.PRECOMBAT_MAIN, playerD, playerD); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.END_TURN); + execute(); + } + + @Test + public void test_InitiativeByDamage() { + // Player order: A -> D -> C -> B + // game must use MultiplayerAttackOption.MULTIPLE + + // When Aarakocra Sneak enters the battlefield, you take the initiative. + addCard(Zone.HAND, playerA, "Aarakocra Sneak", 1); // {3}{U} + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + // + addCard(Zone.BATTLEFIELD, playerD, "Grizzly Bears", 1); + // + addCard(Zone.BATTLEFIELD, playerC, "Grizzly Bears", 1); + + // A as monarch + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aarakocra Sneak"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + addTarget(playerA, "Mountain"); // search for "Secret Entrance" room + checkInitative("initiative to A", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerA); + + // D steal monarch from A + attack(2, playerD, "Grizzly Bears", playerA); + addTarget(playerD, "Mountain"); // search for "Secret Entrance" room + checkInitative("initiative to D", 2, PhaseStep.POSTCOMBAT_MAIN, playerD, playerD); + + // C can't steal from A (nothing to steal) + attack(3, playerC, "Grizzly Bears", playerA); + checkInitative("nothing to steal (keep on D)", 3, PhaseStep.POSTCOMBAT_MAIN, playerC, playerD); + + // D 2nd turn, move to another room. + setChoice(playerD, false); // Go to "Lost Well" in dungeon + addTarget(playerD, "Mountain"); // for the Scry 2 of the "Lost Well" room. + + // C steal from D + attack(3 + 4, playerC, "Grizzly Bears", playerD); + addTarget(playerC, "Mountain"); // search for "Secret Entrance" room + checkInitative("initiative to C", 3 + 4, PhaseStep.POSTCOMBAT_MAIN, playerC, playerC); + + setStrictChooseMode(true); + setStopAt(3 + 4, PhaseStep.END_TURN); + execute(); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/designations/MonarchTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/designations/MonarchTest.java index 8ebf61abfea..a4407881e0d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/designations/MonarchTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/designations/MonarchTest.java @@ -70,7 +70,6 @@ public class MonarchTest extends CardTestMultiPlayerBase { // addCard(Zone.BATTLEFIELD, playerD, "Grizzly Bears", 1); // - // {T} : Prodigal Pyromancer deals 1 damage to any target. addCard(Zone.BATTLEFIELD, playerC, "Grizzly Bears", 1); // A as monarch diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index ff6d8181f3d..505adae6de9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -979,12 +979,19 @@ public class TestPlayer implements Player { wasProccessed = true; } - // check monarch: plyer id with monarch + // check monarch: player id with monarch if (params[0].equals(CHECK_COMMAND_MONARCH) && params.length == 2) { assertMonarch(action, game, params[1].equals("null") ? null : game.getPlayer(UUID.fromString(params[1]))); actions.remove(action); wasProccessed = true; } + + // check initiative: player id with monarch + if (params[0].equals(CHECK_COMMAND_INITIATIVE) && params.length == 2) { + assertInitiative(action, game, params[1].equals("null") ? null : game.getPlayer(UUID.fromString(params[1]))); + actions.remove(action); + wasProccessed = true; + } } if (wasProccessed) { return true; @@ -1729,6 +1736,20 @@ public class TestPlayer implements Player { } } + private void assertInitiative(PlayerAction action, Game game, Player player) { + if (player != null) { + // must be + if (game.getInitiativeId() != player.getId()) { + Assert.fail(action.getActionName() + " - game must have " + player.getName() + " as player with the initiative, but found " + game.getPlayer(game.getInitiativeId())); + } + } else { + // must not be + if (game.getInitiativeId() != null) { + Assert.fail(action.getActionName() + " - game must be without initiative, but found " + game.getPlayer(game.getInitiativeId())); + } + } + } + private void assertManaPoolInner(PlayerAction action, Player player, ManaType manaType, Integer amount) { Integer normal = player.getManaPool().getMana().get(manaType); Integer conditional = player.getManaPool().getConditionalMana().stream().mapToInt(a -> a.get(manaType)).sum(); // calcs FULL conditional mana, not real conditions diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 03b7fd69013..bb564a93476 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -108,6 +108,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement public static final String CHECK_COMMAND_STACK_SIZE = "STACK_SIZE"; public static final String CHECK_COMMAND_STACK_OBJECT = "STACK_OBJECT"; public static final String CHECK_COMMAND_MONARCH = "MONARCH"; + public static final String CHECK_COMMAND_INITIATIVE = "INITIATIVE"; // TODO: add target player param to commands public static final String SHOW_COMMAND_LIBRARY = "LIBRARY"; @@ -537,6 +538,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement check(checkName, turnNum, step, player, CHECK_COMMAND_MONARCH, (monarch == null ? "null" : monarch.getId().toString())); } + public void checkInitative(String checkName, int turnNum, PhaseStep step, TestPlayer player, TestPlayer withInitiative) { + check(checkName, turnNum, step, player, CHECK_COMMAND_INITIATIVE, (withInitiative == null ? "null" : withInitiative.getId().toString())); + } + // show commands private void show(String showName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) { String res = "show:" + command;