From 1ca876c2ed6a9a5087099c3b6da2864b2f3f0163 Mon Sep 17 00:00:00 2001 From: John Hitchings Date: Wed, 20 Mar 2019 23:23:28 -0700 Subject: [PATCH] Fixed LondonMulligan to give mulligan choice after discarding to bottom, which fixes the interaction with Serum Powder. --- .../test/mulligan/LondonMulliganTest.java | 138 ++++++++++++------ .../mage/game/mulligan/LondonMulligan.java | 43 +++--- 2 files changed, 114 insertions(+), 67 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/mulligan/LondonMulliganTest.java b/Mage.Tests/src/test/java/org/mage/test/mulligan/LondonMulliganTest.java index 5bd8aac5c5b..ed9a7c8abb8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/mulligan/LondonMulliganTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/mulligan/LondonMulliganTest.java @@ -5,6 +5,7 @@ import mage.game.mulligan.MulliganType; import org.junit.Test; import java.util.*; +import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; @@ -37,25 +38,26 @@ public class LondonMulliganTest extends MulliganTestBase { hand1.addAll(scenario.getHand()); return true; }); - scenario.mulligan(() -> { - scenario.assertSizes(7, 33); - assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); - hand2.addAll(scenario.getHand()); - return false; - }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); assertEquals(1, count); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); - assertEquals(hand2, scenario.getHand()); scenario.getHand().stream().limit(count).forEach(discarded::add); remainingHand.addAll(Sets.difference(scenario.getHand(), new HashSet<>(discarded))); return discarded; }); + scenario.mulligan(() -> { + scenario.assertSizes(6, 34); + assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); + assertEquals(remainingHand, scenario.getHand()); + hand2.addAll(scenario.getHand()); + return false; + }); scenario.run(() -> { scenario.assertSizes(6, 34); assertEquals(remainingHand, new HashSet<>(scenario.getHand())); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); + assertEquals(hand2, scenario.getHand()); assertEquals(discarded, scenario.getNBottomOfLibrary(1)); }); } @@ -73,34 +75,46 @@ public class LondonMulliganTest extends MulliganTestBase { hand1.addAll(scenario.getHand()); return true; }); - scenario.mulligan(() -> { + scenario.discardBottom(count -> { scenario.assertSizes(7, 33); + assertEquals(1, count); + assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); + scenario.getHand().stream().limit(count).forEach(discarded::add); + remainingHand.addAll(Sets.difference(scenario.getHand(), new HashSet<>(discarded))); + return discarded; + }); + scenario.mulligan(() -> { + scenario.assertSizes(6, 34); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); hand2.addAll(scenario.getHand()); return true; }); - scenario.mulligan(() -> { - scenario.assertSizes(7, 33); - assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); - assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); - hand3.addAll(scenario.getHand()); - return false; - }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); assertEquals(2, count); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); - assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); - assertEquals(hand3, scenario.getHand()); + assertEquals(discarded, scenario.getLibraryRangeSize(26, 1)); + assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(27, 6))); + discarded.clear(); + remainingHand.clear(); scenario.getHand().stream().limit(count).forEach(discarded::add); remainingHand.addAll(Sets.difference(scenario.getHand(), new HashSet<>(discarded))); return discarded; }); + scenario.mulligan(() -> { + scenario.assertSizes(5, 35); + assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); + assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(27, 6))); + assertEquals(discarded, scenario.getNBottomOfLibrary(2)); + hand3.addAll(scenario.getHand()); + return false; + }); scenario.run(() -> { scenario.assertSizes(5, 35); assertEquals(remainingHand, new HashSet<>(scenario.getHand())); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); - assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); + assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(27, 6))); + assertEquals(hand3, scenario.getHand()); assertEquals(discarded, scenario.getNBottomOfLibrary(2)); }); } @@ -162,27 +176,28 @@ public class LondonMulliganTest extends MulliganTestBase { hand2.addAll(scenario.getHand()); return true; }); - scenario.mulligan(() -> { - scenario.assertSizes(7, 33); - assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); - assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); - hand3.addAll(scenario.getHand()); - return false; - }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); assertEquals(1, count); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); - assertEquals(hand3, scenario.getHand()); scenario.getHand().stream().limit(count).forEach(discarded::add); remainingHand.addAll(Sets.difference(scenario.getHand(), new HashSet<>(discarded))); return discarded; }); + scenario.mulligan(() -> { + scenario.assertSizes(6, 34); + assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); + assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); + assertEquals(discarded, scenario.getNBottomOfLibrary(1)); + hand3.addAll(scenario.getHand()); + return false; + }); scenario.run(() -> { scenario.assertSizes(6, 34); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(26, 7))); + assertEquals(hand3, scenario.getHand()); assertEquals(remainingHand, new HashSet<>(scenario.getHand())); assertEquals(discarded, scenario.getNBottomOfLibrary(1)); }); @@ -195,33 +210,64 @@ public class LondonMulliganTest extends MulliganTestBase { scenario.assertSizes(7, 33); return true; }); - scenario.mulligan(() -> { + scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - return true; + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.mulligan(() -> { - scenario.assertSizes(7, 33); - return true; - }); - scenario.mulligan(() -> { - scenario.assertSizes(7, 33); - return true; - }); - scenario.mulligan(() -> { - scenario.assertSizes(7, 33); - return true; - }); - scenario.mulligan(() -> { - scenario.assertSizes(7, 33); - return true; - }); - scenario.mulligan(() -> { - scenario.assertSizes(7, 33); + scenario.assertSizes(6, 34); return true; }); scenario.discardBottom(count -> { + scenario.assertSizes(7, 33); + assertEquals(2, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.mulligan(() -> { + scenario.assertSizes(5, 35); + return true; + }); + scenario.discardBottom(count -> { + scenario.assertSizes(7, 33); + assertEquals(3, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.mulligan(() -> { + scenario.assertSizes(4, 36); + return true; + }); + scenario.discardBottom(count -> { + scenario.assertSizes(7, 33); + assertEquals(4, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.mulligan(() -> { + scenario.assertSizes(3, 37); + return true; + }); + scenario.discardBottom(count -> { + scenario.assertSizes(7, 33); + assertEquals(5, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.mulligan(() -> { + scenario.assertSizes(2, 38); + return true; + }); + scenario.discardBottom(count -> { + scenario.assertSizes(7, 33); + assertEquals(6, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.mulligan(() -> { + scenario.assertSizes(1, 39); + return true; + }); + scenario.discardBottom(count -> { + scenario.assertSizes(7, 33); assertEquals(7, count); - return new ArrayList<>(scenario.getHand()); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.run(() -> { scenario.assertSizes(0, 40); diff --git a/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java b/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java index 0ced5be7236..5c9e85a4d69 100644 --- a/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java +++ b/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java @@ -6,15 +6,17 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; -import mage.game.events.GameEvent; import mage.players.Player; import mage.target.TargetCard; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; public class LondonMulligan extends Mulligan { protected Map startingHandSizes = new HashMap<>(); + protected Map openingHandSizes = new HashMap<>(); public LondonMulligan(int freeMulligans) { super(freeMulligans); @@ -39,25 +41,11 @@ public class LondonMulligan extends Mulligan { */ for (UUID playerId : game.getState().getPlayerList(game.getStartingPlayerId())) { + openingHandSizes.put(playerId, startingHandSize); startingHandSizes.put(playerId, startingHandSize); } super.executeMulliganPhase(game, startingHandSize); - - for (UUID playerId : game.getState().getPlayerList(game.getStartingPlayerId())) { - int handSize = startingHandSizes.get(playerId); - Player player = game.getPlayer(playerId); - if (player != null && player.getHand().size() > handSize) { - int cardsToDiscard = player.getHand().size() - handSize; - Cards cards = new CardsImpl(); - cards.addAll(player.getHand()); - TargetCard target = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, - new FilterCard("cards to PUT on the BOTTOM of your library (Discard for Mulligan)")); - player.chooseTarget(Outcome.Neutral, cards, target, null, game); - player.putCardsOnBottomOfLibrary(new CardsImpl(target.getTargets()), game, null, true); - cards.removeAll(target.getTargets()); - } - } } @Override @@ -74,18 +62,18 @@ public class LondonMulligan extends Mulligan { deduction = 0; } } - return startingHandSizes.get(playerId) - deduction; + return openingHandSizes.get(playerId) - deduction; } @Override public boolean canTakeMulligan(Game game, Player player) { - return super.canTakeMulligan(game, player) && startingHandSizes.get(player.getId()) > 0; + return super.canTakeMulligan(game, player) && openingHandSizes.get(player.getId()) > 0; } @Override public void mulligan(Game game, UUID playerId) { Player player = game.getPlayer(playerId); - int numCards = player.getHand().size(); + int numCards = startingHandSizes.get(player.getId()); player.getLibrary().addAll(player.getHand().getCards(game), game); player.getHand().clear(); player.shuffleLibrary(null, game); @@ -102,7 +90,7 @@ public class LondonMulligan extends Mulligan { usedFreeMulligans.put(player.getId(), 1); } } - startingHandSizes.put(playerId, startingHandSizes.get(playerId) - deduction); + openingHandSizes.put(playerId, openingHandSizes.get(playerId) - deduction); if (deduction == 0) { game.fireInformEvent(new StringBuilder(player.getLogName()) .append(" mulligans for free.") @@ -115,6 +103,18 @@ public class LondonMulligan extends Mulligan { .append(numCards - deduction == 1 ? " card" : " cards").toString()); } player.drawCards(numCards, game); + + int handSize = openingHandSizes.get(player.getId()); + if (player.getHand().size() > handSize) { + int cardsToDiscard = player.getHand().size() - handSize; + Cards cards = new CardsImpl(); + cards.addAll(player.getHand()); + TargetCard target = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, + new FilterCard("cards to PUT on the BOTTOM of your library (Discard for Mulligan)")); + player.chooseTarget(Outcome.Neutral, cards, target, null, game); + player.putCardsOnBottomOfLibrary(new CardsImpl(target.getTargets()), game, null, true); + cards.removeAll(target.getTargets()); + } } @Override @@ -123,6 +123,7 @@ public class LondonMulligan extends Mulligan { @Override public LondonMulligan copy() { LondonMulligan mulligan = new LondonMulligan(getFreeMulligans()); + mulligan.openingHandSizes.putAll(openingHandSizes); mulligan.startingHandSizes.putAll(startingHandSizes); return mulligan; }