From 5b36756127f1a4fb6efedc6d43324b8d6195d85a Mon Sep 17 00:00:00 2001 From: drmDev Date: Fri, 1 Apr 2016 19:52:11 -0400 Subject: [PATCH] Creeping Dread tests and error checking --- .../shadowsoverinnistrad/CreepingDread.java | 28 ++-- .../test/multiplayer/CreepingDreadTest.java | 155 ++++++++++++++++++ 2 files changed, 171 insertions(+), 12 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/multiplayer/CreepingDreadTest.java diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/CreepingDread.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/CreepingDread.java index 937bf1c3c8a..43fee7ef2e9 100644 --- a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/CreepingDread.java +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/CreepingDread.java @@ -124,15 +124,17 @@ class CreepingDreadEffect extends OneShotEffect { TargetCard target = new TargetCard(Zone.HAND, new FilterCard()); if(opponent.choose(Outcome.Discard, opponent.getHand(), target, game)) { Card card = opponent.getHand().get(target.getFirstTarget(), game); - if (card != null) { - for (CardType cType : typesChosen) { - for (CardType oType : card.getCardType()) { - if (cType == oType) { - opponentsAffected.add(opponent); - break; + if (card != null) { + if (!typesChosen.isEmpty()) { + for (CardType cType : typesChosen) { + for (CardType oType : card.getCardType()) { + if (cType == oType) { + opponentsAffected.add(opponent); + break; + } } } - } + } cardsChosen.put(opponent, card); } @@ -148,11 +150,13 @@ class CreepingDreadEffect extends OneShotEffect { } // everyone discards the card at the same time - for (Map.Entry entry : cardsChosen.entrySet()) { - Player player = entry.getKey(); - Card cardChosen = entry.getValue(); - if (player != null && cardChosen != null) { - player.discard(cardChosen, source, game); + if (!cardsChosen.isEmpty()) { + for (Map.Entry entry : cardsChosen.entrySet()) { + Player player = entry.getKey(); + Card cardChosen = entry.getValue(); + if (player != null && cardChosen != null) { + player.discard(cardChosen, source, game); + } } } diff --git a/Mage.Tests/src/test/java/org/mage/test/multiplayer/CreepingDreadTest.java b/Mage.Tests/src/test/java/org/mage/test/multiplayer/CreepingDreadTest.java new file mode 100644 index 00000000000..6c508213d9d --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/multiplayer/CreepingDreadTest.java @@ -0,0 +1,155 @@ +package org.mage.test.multiplayer; + +import java.io.FileNotFoundException; +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 org.junit.Test; +import org.mage.test.serverside.base.CardTestMultiPlayerBase; + +/** + * Enchantment {3}{B} + * At the beginning of your upkeep, each player discards a card. + * Each opponent who discarded a card that shares a card type with the card you discarded loses 3 life. + * (Players reveal the discarded cards simultaneously.) + * + * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com + */ +public class CreepingDreadTest extends CardTestMultiPlayerBase { + + @Override + protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { + Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, 0, 40); + // Player order: A -> D -> C -> B + playerA = createPlayer(game, playerA, "PlayerA"); + playerB = createPlayer(game, playerB, "PlayerB"); + playerC = createPlayer(game, playerC, "PlayerC"); + playerD = createPlayer(game, playerD, "PlayerD"); + return game; + } + + /** + * Discard creature and all opponents who discard creature lose 3 life + */ + @Test + public void basicTest() { + + addCard(Zone.BATTLEFIELD, playerA, "Creeping Dread"); + addCard(Zone.HAND, playerA, "Merfolk Looter"); + addCard(Zone.HAND, playerB, "Hill Giant"); + addCard(Zone.HAND, playerC, "Elite Vanguard"); + addCard(Zone.HAND, playerD, "Bone Saw"); + + setChoice(playerA, "Merfolk Looter"); + setChoice(playerB, "Hill Giant"); + setChoice(playerC, "Elite Vanguard"); + setChoice(playerD, "Bone Saw"); + + setStopAt(1, PhaseStep.DRAW); + execute(); + + assertGraveyardCount(playerA, "Merfolk Looter", 1); + assertGraveyardCount(playerB, "Hill Giant", 1); + assertGraveyardCount(playerC, "Elite Vanguard", 1); + assertGraveyardCount(playerD, "Bone Saw", 1); + + assertLife(playerA, 40); // 4-player commander so 40 life starting + assertLife(playerB, 37); // matched creature type + assertLife(playerC, 37); + assertLife(playerD, 40); // no match + } + + /** + * Discard Artifact Creature and all opponents who discard either an Artifact or Creature lose 3 life + */ + @Test + public void twoTypesTest() { + + addCard(Zone.BATTLEFIELD, playerA, "Creeping Dread"); + addCard(Zone.HAND, playerA, "Bronze Sable"); + addCard(Zone.HAND, playerB, "Hill Giant"); + addCard(Zone.HAND, playerC, "Swamp"); + addCard(Zone.HAND, playerD, "Bone Saw"); + + setChoice(playerA, "Bronze Sable"); + setChoice(playerB, "Hill Giant"); + setChoice(playerC, "Swamp"); + setChoice(playerD, "Bone Saw"); + + setStopAt(1, PhaseStep.DRAW); + execute(); + + assertGraveyardCount(playerA, "Bronze Sable", 1); + assertGraveyardCount(playerB, "Hill Giant", 1); + assertGraveyardCount(playerC, "Swamp", 1); + assertGraveyardCount(playerD, "Bone Saw", 1); + + assertLife(playerA, 40); // artifact-creature discarded + assertLife(playerB, 37); // creature + assertLife(playerC, 40); // neither + assertLife(playerD, 37); // artifact + } + + /** + * Discard enchantment and no opponents discard an enchantment, so no one loses life + */ + @Test + public void noMatchesTest() { + + addCard(Zone.BATTLEFIELD, playerA, "Creeping Dread"); + addCard(Zone.HAND, playerA, "Moat"); // enchantment + addCard(Zone.HAND, playerB, "Hill Giant"); + addCard(Zone.HAND, playerC, "Swamp"); + addCard(Zone.HAND, playerD, "Bone Saw"); + + setChoice(playerA, "Moat"); + setChoice(playerB, "Hill Giant"); + setChoice(playerC, "Swamp"); + setChoice(playerD, "Bone Saw"); + + setStopAt(1, PhaseStep.DRAW); + execute(); + + assertGraveyardCount(playerA, "Moat", 1); + assertGraveyardCount(playerB, "Hill Giant", 1); + assertGraveyardCount(playerC, "Swamp", 1); + assertGraveyardCount(playerD, "Bone Saw", 1); + + assertLife(playerA, 40); // no matches + assertLife(playerB, 40); + assertLife(playerC, 40); + assertLife(playerD, 40); + } + + /** + * Upkeep player has no cards to discard, so no matches + */ + @Test + public void noDiscardNoMatches() { + + addCard(Zone.BATTLEFIELD, playerA, "Creeping Dread"); + addCard(Zone.HAND, playerB, "Hill Giant"); + addCard(Zone.HAND, playerC, "Swamp"); + addCard(Zone.HAND, playerD, "Bone Saw"); + + setChoice(playerB, "Hill Giant"); + setChoice(playerC, "Swamp"); + setChoice(playerD, "Bone Saw"); + + setStopAt(1, PhaseStep.DRAW); + execute(); + + assertGraveyardCount(playerB, "Hill Giant", 1); + assertGraveyardCount(playerC, "Swamp", 1); + assertGraveyardCount(playerD, "Bone Saw", 1); + + assertLife(playerA, 40); // no matches + assertLife(playerB, 40); + assertLife(playerC, 40); + assertLife(playerD, 40); + } +}