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 ed9a7c8abb..03dc1a6747 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 @@ -91,7 +91,7 @@ public class LondonMulliganTest extends MulliganTestBase { }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - assertEquals(2, count); + assertEquals(1, count); assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); assertEquals(discarded, scenario.getLibraryRangeSize(26, 1)); assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(27, 6))); @@ -101,11 +101,23 @@ public class LondonMulliganTest extends MulliganTestBase { remainingHand.addAll(Sets.difference(scenario.getHand(), new HashSet<>(discarded))); return discarded; }); + scenario.discardBottom(count -> { + scenario.assertSizes(6, 34); + assertEquals(1, count); + assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); + assertEquals(discarded, scenario.getNBottomOfLibrary(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)); + assertEquals(discarded, scenario.getNBottomOfLibrary(1)); hand3.addAll(scenario.getHand()); return false; }); @@ -115,7 +127,7 @@ public class LondonMulliganTest extends MulliganTestBase { assertEquals(hand1, new HashSet<>(scenario.getLibraryRangeSize(19, 7))); assertEquals(hand2, new HashSet<>(scenario.getLibraryRangeSize(27, 6))); assertEquals(hand3, scenario.getHand()); - assertEquals(discarded, scenario.getNBottomOfLibrary(2)); + assertEquals(discarded, scenario.getNBottomOfLibrary(1)); }); } @@ -221,7 +233,12 @@ public class LondonMulliganTest extends MulliganTestBase { }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - assertEquals(2, count); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(6, 34); + assertEquals(1, count); return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.mulligan(() -> { @@ -230,7 +247,17 @@ public class LondonMulliganTest extends MulliganTestBase { }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - assertEquals(3, count); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(6, 34); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(5, 35); + assertEquals(1, count); return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.mulligan(() -> { @@ -239,7 +266,22 @@ public class LondonMulliganTest extends MulliganTestBase { }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - assertEquals(4, count); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(6, 34); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(5, 35); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(4, 36); + assertEquals(1, count); return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.mulligan(() -> { @@ -248,7 +290,27 @@ public class LondonMulliganTest extends MulliganTestBase { }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - assertEquals(5, count); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(6, 34); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(5, 35); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(4, 36); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(3, 37); + assertEquals(1, count); return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.mulligan(() -> { @@ -257,7 +319,32 @@ public class LondonMulliganTest extends MulliganTestBase { }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - assertEquals(6, count); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(6, 34); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(5, 35); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(4, 36); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(3, 37); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(2, 38); + assertEquals(1, count); return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.mulligan(() -> { @@ -266,7 +353,37 @@ public class LondonMulliganTest extends MulliganTestBase { }); scenario.discardBottom(count -> { scenario.assertSizes(7, 33); - assertEquals(7, count); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(6, 34); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(5, 35); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(4, 36); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(3, 37); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(2, 38); + assertEquals(1, count); + return scenario.getHand().stream().limit(count).collect(Collectors.toList()); + }); + scenario.discardBottom(count -> { + scenario.assertSizes(1, 39); + assertEquals(1, count); return scenario.getHand().stream().limit(count).collect(Collectors.toList()); }); scenario.run(() -> { diff --git a/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java b/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java index 33a213ca23..86917145d8 100644 --- a/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java +++ b/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java @@ -1,13 +1,12 @@ package mage.game.mulligan; -import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.Outcome; -import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; -import mage.target.TargetCard; +import mage.target.Target; +import mage.target.common.TargetCardInHand; import java.util.HashMap; import java.util.Map; @@ -15,8 +14,8 @@ import java.util.UUID; public class LondonMulligan extends Mulligan { - protected Map startingHandSizes = new HashMap<>(); - protected Map openingHandSizes = new HashMap<>(); + private final Map startingHandSizes = new HashMap<>(); + private final Map openingHandSizes = new HashMap<>(); public LondonMulligan(int freeMulligans) { super(freeMulligans); @@ -93,27 +92,20 @@ public class LondonMulligan extends Mulligan { openingHandSizes.put(playerId, openingHandSizes.get(playerId) - deduction); int newHandSize = openingHandSizes.get(player.getId()); if (deduction == 0) { - game.fireInformEvent(new StringBuilder(player.getLogName()) - .append(" mulligans for free.") - .toString()); + game.fireInformEvent(player.getLogName() + + " mulligans for free."); } else { - game.fireInformEvent(new StringBuilder(player.getLogName()) - .append(" mulligans") - .append(" down to ") - .append(newHandSize) - .append(newHandSize == 1 ? " card" : " cards").toString()); + game.fireInformEvent(player.getLogName() + + " mulligans down to " + + newHandSize + + (newHandSize == 1 ? " card" : " cards")); } player.drawCards(numCards, null, game); - if (player.getHand().size() > newHandSize) { - int cardsToDiscard = player.getHand().size() - newHandSize; - Cards cards = new CardsImpl(); - cards.addAll(player.getHand()); - TargetCard target = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, - new FilterCard("card" + (cardsToDiscard > 1 ? "s" : "") + " to PUT on the BOTTOM of your library (Discard for Mulligan)")); - player.chooseTarget(Outcome.Neutral, cards, target, null, game); + while (player.getHand().size() > newHandSize) { + Target target = new TargetCardInHand(new FilterCard("card (" + (player.getHand().size() - newHandSize) + " more) to put on the bottom of your library")); + player.chooseTarget(Outcome.Discard, target, null, game); player.putCardsOnBottomOfLibrary(new CardsImpl(target.getTargets()), game, null, true); - cards.removeAll(target.getTargets()); } } @@ -128,5 +120,4 @@ public class LondonMulligan extends Mulligan { mulligan.startingHandSizes.putAll(startingHandSizes); return mulligan; } - } diff --git a/Mage/src/main/java/mage/players/StubPlayer.java b/Mage/src/main/java/mage/players/StubPlayer.java index 6891338002..6b1fe798d3 100644 --- a/Mage/src/main/java/mage/players/StubPlayer.java +++ b/Mage/src/main/java/mage/players/StubPlayer.java @@ -13,6 +13,7 @@ import mage.cards.decks.Deck; import mage.choices.Choice; import mage.constants.Outcome; import mage.constants.RangeOfInfluence; +import mage.filter.FilterMana; import mage.game.Game; import mage.game.combat.CombatGroup; import mage.game.draft.Draft; @@ -25,13 +26,12 @@ import mage.target.TargetCard; import mage.target.TargetPlayer; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; import static com.google.common.collect.Iterables.getOnlyElement; -import static java.util.stream.Collectors.toList; -import mage.filter.FilterMana; public class StubPlayer extends PlayerImpl implements Player { @@ -54,15 +54,10 @@ public class StubPlayer extends PlayerImpl implements Player { @Override public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) { - if (target.getFilter().getMessage() != null && target.getFilter().getMessage().endsWith("(Discard for Mulligan)")) { - chooseDiscardBottom(game, target.getMinNumberOfTargets(), cards.getCards(game) - .stream().map(MageItem::getId).collect(toList())).forEach(cardId -> target.add(cardId, game)); - } else { - UUID cardId = getOnlyElement(cards.getCards(game)).getId(); - if (chooseScry(game, cardId)) { - target.add(cardId, game); - return true; - } + UUID cardId = getOnlyElement(cards.getCards(game)).getId(); + if (chooseScry(game, cardId)) { + target.add(cardId, game); + return true; } return false; } @@ -111,6 +106,10 @@ public class StubPlayer extends PlayerImpl implements Player { @Override public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) { + if (target.getFilter().getMessage() != null && target.getFilter().getMessage().endsWith(" more) to put on the bottom of your library")) { + chooseDiscardBottom(game, target.getMinNumberOfTargets(), new ArrayList<>(target.possibleTargets(null, null, game))) + .forEach(cardId -> target.add(cardId, game)); + } return false; }