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 97c8323677..23e9d33060 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 @@ -132,13 +132,17 @@ public class TestPlayer implements Player { } public TestPlayer(final TestPlayer testPlayer) { + this.AIPlayer = testPlayer.AIPlayer; + this.foundNoAction = testPlayer.foundNoAction; + this.actions.addAll(testPlayer.actions); this.choices.addAll(testPlayer.choices); this.targets.addAll(testPlayer.targets); this.modesSet.addAll(testPlayer.modesSet); this.computerPlayer = testPlayer.computerPlayer.copy(); - this.foundNoAction = testPlayer.foundNoAction; - + if (testPlayer.groupsForTargetHandling != null) { + this.groupsForTargetHandling = testPlayer.groupsForTargetHandling.clone(); + } } public void addChoice(String choice) { @@ -463,6 +467,21 @@ public class TestPlayer implements Player { break; } } + } else if (action.getAction().startsWith("playerAction:")) { + String command = action.getAction(); + command = command.substring(command.indexOf("playerAction:") + 13); + groupsForTargetHandling = null; + String[] groups = command.split("\\$"); + if (groups.length > 0) { + if (groups[0].equals("Rollback")) { + if (groups.length > 1 && groups[1].startsWith("turns=")) { + int turns = Integer.parseUnsignedInt(groups[1].substring(6)); + game.rollbackTurns(turns); + actions.remove(action); + break; + } + } + } } } } @@ -1041,6 +1060,14 @@ public class TestPlayer implements Player { @Override public void restore(Player player) { + this.modesSet.clear(); + this.modesSet.addAll(((TestPlayer) player).modesSet); + this.actions.clear(); + this.actions.addAll(((TestPlayer) player).actions); + this.choices.clear(); + this.choices.addAll(((TestPlayer) player).choices); + this.targets.clear(); + this.targets.addAll(((TestPlayer) player).targets); computerPlayer.restore(player); } diff --git a/Mage.Tests/src/test/java/org/mage/test/rollback/DemonicPactTest.java b/Mage.Tests/src/test/java/org/mage/test/rollback/DemonicPactTest.java new file mode 100644 index 0000000000..c9b2d123a9 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/rollback/DemonicPactTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.rollback; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class DemonicPactTest extends CardTestPlayerBase { + + @Test + public void testModes() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + // At the beginning of your upkeep, choose one that hasn't been chosen + // (1) - Demonic Pact deals 4 damage to target creature or player and you gain 4 life; + // (2) - Target opponent discards two cards + // (3) - Draw two cards + // (4) - You lose the game. + addCard(Zone.HAND, playerA, "Demonic Pact"); // Enchantment {2}{B}{B} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Demonic Pact"); + + setModeChoice(playerA, "3"); + + setModeChoice(playerA, "2"); + addTarget(playerA, playerB); + + setModeChoice(playerA, "1"); + addTarget(playerA, playerB); + + setStopAt(7, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, "Demonic Pact", 1); + assertLife(playerA, 24); + assertLife(playerB, 16); + assertHandCount(playerB, 1); // discard 2 + 3 from regular draws + + assertHandCount(playerA, 5); // two from Demonic Pact + 3 from regular draws + + } + + /* + The rollback to the start of the turn does not correctly reset the already selected choices from Demonic Pact. They are not available again. + */ + @Test + public void testModeAfterRollback() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + // At the beginning of your upkeep, choose one that hasn't been chosen + // (1) - Demonic Pact deals 4 damage to target creature or player and you gain 4 life; + // (2) - Target opponent discards two cards + // (3) - Draw two cards + // (4) - You lose the game. + addCard(Zone.HAND, playerA, "Demonic Pact"); // Enchantment {2}{B}{B} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Demonic Pact"); + + setModeChoice(playerA, "1"); + addTarget(playerA, playerB); + + rollbackTurns(3, PhaseStep.PRECOMBAT_MAIN, playerA, 0); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertHandCount(playerA, 1); // 1 from regular draws + assertHandCount(playerB, 1); // 1 from regular draw + + assertLife(playerA, 24); + assertLife(playerB, 16); + + } +} 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 c9686df11c..37fdf374e9 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 @@ -314,12 +314,15 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @return */ private List getCardList(Zone gameZone, TestPlayer player) { - if (gameZone.equals(Zone.HAND)) { - return getHandCards(player); - } else if (gameZone.equals(Zone.GRAVEYARD)) { - return getGraveCards(player); - } else if (gameZone.equals(Zone.LIBRARY)) { - return getLibraryCards(player); + switch (gameZone) { + case HAND: + return getHandCards(player); + case GRAVEYARD: + return getGraveCards(player); + case LIBRARY: + return getLibraryCards(player); + default: + break; } throw new AssertionError("Zone is not supported by test framework: " + gameZone); @@ -872,7 +875,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement Assert.assertEquals("(Graveyard " + player.getName() + ") Card counts are not equal (" + cardName + ")", count, actualCount); } - + /** * Assert library card count. * @@ -880,7 +883,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param count Expected count. */ public void assertLibraryCount(Player player, int count) throws AssertionError { - + List libraryList = player.getLibrary().getCards(currentGame); int actualCount = libraryList != null && !libraryList.isEmpty() ? libraryList.size() : 0; Assert.assertEquals("(Library " + player.getName() + ") counts are not equal", count, actualCount); @@ -951,6 +954,19 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement player.addAction(turnNum, step, "activate:Cast " + cardName + "$targetPlayer=" + target.getName() + "$manaInPool=" + manaInPool); } + /** + * Rollback the number of given turns: 0 = rollback to the start of the + * current turn + * + * @param turnNum + * @param step + * @param player + * @param turns + */ + public void rollbackTurns(int turnNum, PhaseStep step, TestPlayer player, int turns) { + player.addAction(turnNum, step, "playerAction:Rollback" + "$turns=" + turns); + } + /** * * @param turnNum @@ -1098,7 +1114,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * * @param player * @param choice starting with "1" for mode 1, "2" for mode 2 and so on (to - * set multiple modes call the command multiple times) + * set multiple modes call the command multiple times). If a spell mode can + * be used only once like Demonic Pact, the value has to be set to the + * number of the remaining modes (e.g. if only 2 are left the number need to + * be 1 or 2). */ public void setModeChoice(TestPlayer player, String choice) { player.addModeChoice(choice);