diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index ad234852ca7..c2528aaa343 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -909,6 +909,7 @@ public class ComputerPlayer6 extends ComputerPlayer { List blockers = entry.getValue(); if (blockers != null) { for (Permanent blocker : blockers) { + // TODO: buggy or miss on multi blocker requirements?! player.declareBlocker(player.getId(), blocker.getId(), attackerId, game); blocked = true; } diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/util/CombatUtil.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/util/CombatUtil.java index 1d345fcba95..5a3f5bc8d98 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/util/CombatUtil.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/util/CombatUtil.java @@ -83,28 +83,17 @@ public final class CombatUtil { } public static void sortByPower(List permanents, final boolean ascending) { - Collections.sort(permanents, new Comparator() { - @Override - public int compare(Permanent o1, Permanent o2) { - if (ascending) { - return o1.getPower().getValue() - o2.getPower().getValue(); - } else { - return o2.getPower().getValue() - o1.getPower().getValue(); - } - } - }); + permanents.sort(Comparator.comparingInt(p -> p.getPower().getValue())); + if (!ascending) { + Collections.reverse(permanents); + } } public static Permanent getWorstCreature(List creatures) { if (creatures.isEmpty()) { return null; } - Collections.sort(creatures, new Comparator() { - @Override - public int compare(Permanent o1, Permanent o2) { - return o2.getPower().getValue() - o1.getPower().getValue(); - } - }); + creatures.sort(Comparator.comparingInt(p -> p.getPower().getValue())); return creatures.get(0); } diff --git a/Mage.Sets/src/mage/cards/d/DefiantVanguard.java b/Mage.Sets/src/mage/cards/d/DefiantVanguard.java index fa476e12d76..3a46e41e60f 100644 --- a/Mage.Sets/src/mage/cards/d/DefiantVanguard.java +++ b/Mage.Sets/src/mage/cards/d/DefiantVanguard.java @@ -1,7 +1,6 @@ package mage.cards.d; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; @@ -16,11 +15,7 @@ import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.game.Game; @@ -29,14 +24,18 @@ import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author bunchOfDevs */ public final class DefiantVanguard extends CardImpl { + protected static final String EFFECT_KEY = "DefiantVanguardEffect_"; + private static final FilterPermanentCard filter = new FilterPermanentCard("Rebel permanent card with mana value 4 or less"); + static { filter.add(SubType.REBEL.getPredicate()); filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 5)); @@ -100,8 +99,8 @@ class DefiantVanguardTriggeredAbility extends TriggeredAbilityImpl { Permanent blocked = game.getPermanent(event.getTargetId()); if (blocker != null && blocked != null) { - game.getState().setValue(blocked.toString(), blocked.getZoneChangeCounter(game)); // in case the attacker changes zone - game.getState().setValue(blocker.toString(), blocker.getZoneChangeCounter(game)); // in case the blocker changes zone + game.getState().setValue(DefiantVanguard.EFFECT_KEY + blocked.getId(), blocked.getZoneChangeCounter(game)); // in case the attacker changes zone + game.getState().setValue(DefiantVanguard.EFFECT_KEY + blocker.getId(), blocker.getZoneChangeCounter(game)); // in case the blocker changes zone getAllEffects().setTargetPointer(new FixedTarget(blocked.getId())); return true; } @@ -131,13 +130,13 @@ class DefiantVanguardEffect extends OneShotEffect { Permanent blockedCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent defiantVanguard = game.getPermanent(source.getSourceId()); if (blockedCreature != null) { - if (game.getState().getValue(blockedCreature.toString()).equals(blockedCreature.getZoneChangeCounter(game))) { // true if it did not change zones + if (game.getState().getValue(DefiantVanguard.EFFECT_KEY + blockedCreature.getId()).equals(blockedCreature.getZoneChangeCounter(game))) { // true if it did not change zones blockedCreature.destroy(source, game, false); result = true; } } if (defiantVanguard != null) { - if (game.getState().getValue(defiantVanguard.toString()).equals(defiantVanguard.getZoneChangeCounter(game))) { // true if it did not change zones + if (game.getState().getValue(DefiantVanguard.EFFECT_KEY + defiantVanguard.getId()).equals(defiantVanguard.getZoneChangeCounter(game))) { // true if it did not change zones defiantVanguard.destroy(source, game, false); result = true; } diff --git a/Mage.Tests/src/test/java/org/mage/test/AI/basic/BlockSimulationAITest.java b/Mage.Tests/src/test/java/org/mage/test/AI/basic/BlockSimulationAITest.java index 11acf4d8c08..ef83f53f4ab 100644 --- a/Mage.Tests/src/test/java/org/mage/test/AI/basic/BlockSimulationAITest.java +++ b/Mage.Tests/src/test/java/org/mage/test/AI/basic/BlockSimulationAITest.java @@ -32,7 +32,8 @@ public class BlockSimulationAITest extends CardTestPlayerBaseWithAIHelps { @Test public void test_Block_1_small_attacker_vs_2_big_blockers() { addCard(Zone.BATTLEFIELD, playerA, "Arbor Elf", 1); // 1/1 - addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 2); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, "Spectral Bears", 1); // 3/3 attack(1, playerA, "Arbor Elf"); @@ -161,6 +162,31 @@ public class BlockSimulationAITest extends CardTestPlayerBaseWithAIHelps { assertPermanentCount(playerB, "Spectral Bears", 1); } + @Test + public void test_Block_1_attacker_vs_many_blockers() { + addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2 + // + addCard(Zone.BATTLEFIELD, playerB, "Arbor Elf", 1); // 1/1 + addCard(Zone.BATTLEFIELD, playerB, "Spectral Bears", 1); // 3/3 + addCard(Zone.BATTLEFIELD, playerB, "Deadbridge Goliath", 1); // 5/5 + addCard(Zone.BATTLEFIELD, playerB, "Colossal Dreadmaw", 1); // 6/6 + + attack(1, playerA, "Balduvian Bears"); + + // ai must use smaller blocker and survive (3/3 must block 2/2) + aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB); + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + assertGraveyardCount(playerA, "Balduvian Bears", 1); + assertDamageReceived(playerB, "Spectral Bears", 2); + } + + // TODO: add tests with multi blocker requirement effects // TODO: add tests for DeathtouchAbility // TODO: add tests for FirstStrikeAbility // TODO: add tests for DoubleStrikeAbility diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 46f0a89a656..409ace36912 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -21,7 +21,7 @@ import mage.constants.*; import mage.counters.Counter; import mage.counters.CounterType; import mage.counters.Counters; -import mage.filter.*; +import mage.filter.FilterOpponent; import mage.game.Game; import mage.game.GameState; import mage.game.ZoneChangeInfo; @@ -210,8 +210,11 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { + ", " + getBasicMageObject().getClass().getSimpleName() + ", " + imageInfo + ", " + this.getPower() + "/" + this.getToughness() + + (this.getDamage() > 0 ? ", damage " + this.getDamage() : "") + (this.isCopy() ? ", copy" : "") - + (this.isTapped() ? ", tapped" : ""); + + (this.isTapped() ? ", tapped" : "") + + (this.isAttacking() ? ", attacking" : "") + + (this.getBlocking() > 0 ? ", blocking" : ""); } @Override