From 15d3074d84bd8aca63be6a611e44694b3c1728e8 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Fri, 28 Sep 2012 22:59:08 +0000 Subject: [PATCH] Trying to use less CardLists and/or hardcoded constants --- src/main/java/forge/CardList.java | 35 +--- src/main/java/forge/CardPredicates.java | 82 +++++--- src/main/java/forge/GameAction.java | 4 +- src/main/java/forge/GameActionUtil.java | 3 +- .../AbilityFactoryChangeZone.java | 8 +- .../abilityfactory/AbilityFactoryChoose.java | 3 +- .../abilityfactory/AbilityFactoryCombat.java | 3 +- .../abilityfactory/AbilityFactoryEffect.java | 5 +- .../AbilityFactoryPermanentState.java | 14 +- .../AbilityFactoryPreventDamage.java | 5 +- .../AbilityFactoryRegenerate.java | 7 +- .../cardfactory/CardFactoryArtifacts.java | 19 +- .../cardfactory/CardFactoryCreatures.java | 42 ++-- .../cardfactory/CardFactoryEnchantments.java | 5 +- .../card/cardfactory/CardFactoryInstants.java | 16 +- .../card/cardfactory/CardFactoryLands.java | 4 +- .../cardfactory/CardFactorySorceries.java | 50 ++--- .../card/cardfactory/CardFactoryUtil.java | 182 +++++------------- src/main/java/forge/card/mana/Mana.java | 11 -- .../card/spellability/SpellPermanent.java | 6 +- .../java/forge/control/input/InputAttack.java | 7 +- src/main/java/forge/game/GameNew.java | 51 ++--- src/main/java/forge/game/phase/Combat.java | 3 +- .../java/forge/game/phase/CombatUtil.java | 14 +- .../java/forge/game/phase/PhaseHandler.java | 2 +- src/main/java/forge/game/phase/Upkeep.java | 5 +- src/main/java/forge/game/player/AIPlayer.java | 6 +- .../java/forge/game/player/ComputerUtil.java | 19 +- .../forge/game/player/ComputerUtilAttack.java | 5 +- src/main/java/forge/game/player/Player.java | 11 +- src/main/java/forge/util/Aggregates.java | 53 ++--- 31 files changed, 274 insertions(+), 406 deletions(-) diff --git a/src/main/java/forge/CardList.java b/src/main/java/forge/CardList.java index da0c056543a..ed424114688 100644 --- a/src/main/java/forge/CardList.java +++ b/src/main/java/forge/CardList.java @@ -118,43 +118,12 @@ public class CardList extends ArrayList { return this.filter(Predicates.not(CardPredicates.isProtectedFrom(source))); } - /** - *

- * getValidCards. - *

- * - * @param restrictions - * a {@link java.lang.String} object. - * @param sourceController - * a {@link forge.game.player.Player} object. - * @param source - * a {@link forge.Card} object. - * @return a {@link forge.CardList} object. - */ public final CardList getValidCards(final String restrictions, final Player sourceController, final Card source) { - return this.getValidCards(restrictions.split(","), sourceController, source); + return this.filter(CardPredicates.restriction(restrictions.split(","), sourceController, source)); } - /** - *

- * getValidCards. - *

- * - * @param restrictions - * a {@link java.lang.String} object. - * @param sourceController - * a {@link forge.game.player.Player} object. - * @param source - * a {@link forge.Card} object. - * @return a {@link forge.CardList} object. - */ public final CardList getValidCards(final String[] restrictions, final Player sourceController, final Card source) { - return this.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return (c != null) && c.isValid(restrictions, sourceController, source); - } - }); + return this.filter(CardPredicates.restriction(restrictions, sourceController, source)); } diff --git a/src/main/java/forge/CardPredicates.java b/src/main/java/forge/CardPredicates.java index b0e1d2fbd5d..87ed0fdb6e2 100644 --- a/src/main/java/forge/CardPredicates.java +++ b/src/main/java/forge/CardPredicates.java @@ -21,6 +21,7 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; +import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; import forge.game.phase.CombatUtil; import forge.game.player.Player; @@ -37,7 +38,7 @@ import forge.util.PredicateString; */ public final class CardPredicates { - public static Predicate isController(final Player p) { + public final static Predicate isController(final Player p) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -45,7 +46,7 @@ public final class CardPredicates { } }; } - public static Predicate isOwner(final Player p) { + public final static Predicate isOwner(final Player p) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -54,7 +55,7 @@ public final class CardPredicates { }; } - public static Predicate isType(final String cardType) { + public final static Predicate isType(final String cardType) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -63,7 +64,7 @@ public final class CardPredicates { }; } - public static Predicate hasKeyword(final String keyword) { + public final static Predicate hasKeyword(final String keyword) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -72,7 +73,7 @@ public final class CardPredicates { }; } - public static Predicate containsKeyword(final String keyword) { + public final static Predicate containsKeyword(final String keyword) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -81,7 +82,7 @@ public final class CardPredicates { }; } - public static Predicate isTargetableBy(final SpellAbility source) { + public final static Predicate isTargetableBy(final SpellAbility source) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -90,7 +91,7 @@ public final class CardPredicates { }; } - public static Predicate nameEquals(final String name) { + public final static Predicate nameEquals(final String name) { return new Predicate() { @Override public boolean apply(Card c) { @@ -100,7 +101,7 @@ public final class CardPredicates { } - public static Predicate possibleBlockers(final Card attacker) { + public final static Predicate possibleBlockers(final Card attacker) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -116,7 +117,7 @@ public final class CardPredicates { } }; - public static Predicate isProtectedFrom(final Card source) { + public final static Predicate isProtectedFrom(final Card source) { return new Predicate() { @Override public boolean apply(final Card c) { @@ -125,6 +126,15 @@ public final class CardPredicates { }; } + + public final static Predicate restriction(final String[] restrictions, final Player sourceController, final Card source) { + return new Predicate() { + @Override + public boolean apply(final Card c) { + return (c != null) && c.isValid(restrictions, sourceController, source); + } + }; + } public static class Presets { @@ -155,6 +165,15 @@ public final class CardPredicates { return c.isCreature(); } }; + + + public static final Predicate CREATURES_CAN_ATTACK = new Predicate() { + @Override + public boolean apply(final Card c) { + return c.isCreature() && CombatUtil.canAttack(c); + } + }; + /** * a Predicate to get all enchantments. */ @@ -209,15 +228,6 @@ public final class CardPredicates { return c.isToken(); } }; - /** - * a Predicate to get all nonbasic lands. - */ - public static final Predicate NON_BASIC_LAND = new Predicate() { - @Override - public boolean apply(Card c) { - return !c.isBasicLand(); - } - }; /** * a Predicate to get all basicLands. */ @@ -255,15 +265,7 @@ public final class CardPredicates { return c.isLand(); } }; - /** - * a Predicate to get all nonlands. - */ - public static final Predicate NON_LANDS = new Predicate() { - @Override - public boolean apply(Card c) { - return !c.isLand(); - } - }; + /** * a Predicate to get all cards that are black. */ @@ -323,6 +325,18 @@ public final class CardPredicates { return c.isCreature() && (!c.hasFirstStrike() || c.hasDoubleStrike()); } }; + public static final Predicate SNOW_LANDS = new Predicate() { + @Override + public boolean apply(final Card c) { + return c.isLand() && c.isSnow(); + } + }; + public static final Predicate PLANEWALKERS = new Predicate() { + @Override + public boolean apply(final Card c) { + return c.isPlaneswalker(); + } + }; } public static class Accessors { @@ -332,6 +346,13 @@ public final class CardPredicates { return a.getNetDefense(); } }; + + public static final Function fnGetNetAttack = new Function() { + @Override + public Integer apply(Card a) { + return a.getNetAttack(); + } + }; public static final Function fnGetAttack = new Function() { @Override @@ -346,5 +367,12 @@ public final class CardPredicates { return a.getCMC(); } }; + + public static final Function fnEvaluateCreature = new Function() { + @Override + public Integer apply(Card a) { + return CardFactoryUtil.evaluateCreature(a); + } + }; } } diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index 472bc5b81fb..08c9c41ddd6 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -1217,7 +1217,7 @@ public class GameAction { */ private void destroyPlaneswalkers() { // get all Planeswalkers - final CardList list = AllZoneUtil.getCardsIn(ZoneType.Battlefield).getType("Planeswalker"); + final CardList list = AllZoneUtil.getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.PLANEWALKERS); Card c; for (int i = 0; i < list.size(); i++) { @@ -1772,7 +1772,7 @@ public class GameAction { manaCost.decreaseColorlessMana(numToExile); } } else if (spell.getSourceCard().hasKeyword("Convoke")) { - CardList untappedCreats = spell.getActivatingPlayer().getCardsIn(ZoneType.Battlefield).getType("Creature"); + CardList untappedCreats = spell.getActivatingPlayer().getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.CREATURES); untappedCreats = untappedCreats.filter(new Predicate() { @Override public boolean apply(final Card c) { diff --git a/src/main/java/forge/GameActionUtil.java b/src/main/java/forge/GameActionUtil.java index ad0b3e8193c..411cbe4b238 100644 --- a/src/main/java/forge/GameActionUtil.java +++ b/src/main/java/forge/GameActionUtil.java @@ -19,6 +19,7 @@ package forge; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import javax.swing.JOptionPane; @@ -1229,7 +1230,7 @@ public final class GameActionUtil { // add +1/+1 to cards list.clear(); final int num = AllZoneUtil.getCardsIn(ZoneType.Battlefield, "Coat of Arms").size(); - final CardList creatures = AllZoneUtil.getCardsIn(ZoneType.Battlefield).getType("Creature"); + final List creatures = AllZoneUtil.getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.CREATURES); for (Card c : creatures) { for (Card c2 : creatures) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java index 9736120396d..d1dd598e54d 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java @@ -1232,7 +1232,7 @@ public final class AbilityFactoryChangeZone { System.out.println("Don't need a land or none available; trying for a creature."); fetchList = fetchList.getNotType("Land"); // Prefer to pull a creature, generally more useful for AI. - c = chooseCreature(fetchList.getType("Creature")); + c = chooseCreature(fetchList.filter(CardPredicates.Presets.CREATURES)); } if (c == null) { // Could not find a creature. if (ai.getLife() <= 5) { // Desperate? @@ -1699,7 +1699,7 @@ public final class AbilityFactoryChangeZone { } // Save combatants else if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { - final CardList combatants = aiPermanents.getType("Creature"); + final CardList combatants = aiPermanents.filter(CardPredicates.Presets.CREATURES); CardListUtil.sortByEvaluateCreature(combatants); for (final Card c : combatants) { @@ -1808,7 +1808,7 @@ public final class AbilityFactoryChangeZone { } else if (destination.equals(ZoneType.Hand) || destination.equals(ZoneType.Library)) { CardList nonLands = list.getNotType("Land"); // Prefer to pull a creature, generally more useful for AI. - choice = chooseCreature(nonLands.getType("Creature")); + choice = chooseCreature(nonLands.filter(CardPredicates.Presets.CREATURES)); if (choice == null) { // Could not find a creature. if (AllZone.getComputerPlayer().getLife() <= 5) { // Desperate? // Get something AI can cast soon. @@ -1921,7 +1921,7 @@ public final class AbilityFactoryChangeZone { } else if (destination.equals(ZoneType.Hand) || destination.equals(ZoneType.Library)) { CardList nonLands = list.getNotType("Land"); // Prefer to pull a creature, generally more useful for AI. - choice = chooseCreature(nonLands.getType("Creature")); + choice = chooseCreature(nonLands.filter(CardPredicates.Presets.CREATURES)); if (choice == null) { // Could not find a creature. if (AllZone.getComputerPlayer().getLife() <= 5) { // Desperate? // Get something AI can cast soon. diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java index ab7e751ce3e..f251c526872 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java @@ -34,6 +34,7 @@ import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.CardUtil; import forge.Constant; @@ -738,7 +739,7 @@ public final class AbilityFactoryChoose { CardList list = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); if (list.isEmpty()) { list = AllZoneUtil.getCardsInGame().getController(AllZone.getHumanPlayer()) - .getType("Creature"); + .filter(CardPredicates.Presets.CREATURES); } chosen = CardFactoryUtil.getMostProminentColor(list); } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java index b35ee97d5c7..a5764e24326 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java @@ -25,6 +25,7 @@ import com.google.common.base.Predicate; import forge.AllZone; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.Singletons; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.AbilityActivated; @@ -1059,7 +1060,7 @@ public final class AbilityFactoryCombat { boolean chance = false; if (abTgt != null) { - CardList list = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield).getType("Creature"); + CardList list = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.CREATURES); list = list.getTargetableCards(sa); list = list.getValidCards(abTgt.getValidTgts(), source.getController(), source); list = list.filter(new Predicate() { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java index 816d5edb258..48be0fc149f 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java @@ -27,6 +27,7 @@ import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.Command; import forge.Singletons; import forge.card.cardfactory.CardFactoryUtil; @@ -297,8 +298,8 @@ public class AbilityFactoryEffect { } else if (logic.equals("Always")) { randomReturn = true; } else if (logic.equals("Evasion")) { - CardList comp = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield).getType("Creature"); - CardList human = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield).getType("Creature"); + CardList comp = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.CREATURES); + CardList human = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.CREATURES); // only count creatures that can attack or block comp = comp.filter(new Predicate() { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java index 93a9229a3ed..a972a9bbc74 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java @@ -23,11 +23,13 @@ import java.util.Iterator; import java.util.Random; import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.Singletons; import forge.card.cardfactory.CardFactoryUtil; @@ -1065,16 +1067,8 @@ public class AbilityFactoryPermanentState { } else if (phase.isPlayerTurn(AllZone.getHumanPlayer()) && phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) { // Tap creatures possible blockers before combat during AI's turn. - if (!tapList.getType("Creature").isEmpty()) { - CardList creatureList = tapList.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - if (c.isCreature()) { - return CombatUtil.canAttack(c); - } - return false; - } - }); + if (Iterables.any(tapList, CardPredicates.Presets.CREATURES)) { + CardList creatureList = tapList.filter(CardPredicates.Presets.CREATURES_CAN_ATTACK); choice = CardFactoryUtil.getBestCreatureAI(creatureList); } else { // no creatures available choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java index 317555b1507..60aa3f3d560 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java @@ -25,6 +25,7 @@ import forge.AllZoneUtil; import forge.Card; import forge.CardList; import forge.CardListUtil; +import forge.CardPredicates; import forge.CardUtil; import forge.Singletons; import forge.card.cardfactory.CardFactoryUtil; @@ -379,7 +380,7 @@ public class AbilityFactoryPreventDamage { if (targetables.size() == 0) { return false; } - final CardList combatants = targetables.getType("Creature"); + final CardList combatants = targetables.filter(CardPredicates.Presets.CREATURES); CardListUtil.sortByEvaluateCreature(combatants); for (final Card c : combatants) { @@ -469,7 +470,7 @@ public class AbilityFactoryPreventDamage { } if (compTargetables.size() > 0) { - final CardList combatants = compTargetables.getType("Creature"); + final CardList combatants = compTargetables.filter(CardPredicates.Presets.CREATURES); CardListUtil.sortByEvaluateCreature(combatants); if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { for (final Card c : combatants) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java index 3d6a6eb9466..782a6534c72 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java @@ -26,6 +26,7 @@ import forge.AllZoneUtil; import forge.Card; import forge.CardList; import forge.CardListUtil; +import forge.CardPredicates; import forge.Command; import forge.Singletons; import forge.card.cardfactory.CardFactoryUtil; @@ -340,7 +341,7 @@ public class AbilityFactoryRegenerate { } } else { if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { - final CardList combatants = targetables.getType("Creature"); + final CardList combatants = targetables.filter(CardPredicates.Presets.CREATURES); CardListUtil.sortByEvaluateCreature(combatants); for (final Card c : combatants) { @@ -429,7 +430,7 @@ public class AbilityFactoryRegenerate { } if (compTargetables.size() > 0) { - final CardList combatants = compTargetables.getType("Creature"); + final CardList combatants = compTargetables.filter(CardPredicates.Presets.CREATURES); CardListUtil.sortByEvaluateCreature(combatants); if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { for (final Card c : combatants) { @@ -739,7 +740,7 @@ public class AbilityFactoryRegenerate { } else { if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { - final CardList combatants = list.getType("Creature"); + final CardList combatants = list.filter(CardPredicates.Presets.CREATURES); for (final Card c : combatants) { if ((c.getShield() == 0) && CombatUtil.combatantWouldBeDestroyed(c)) { diff --git a/src/main/java/forge/card/cardfactory/CardFactoryArtifacts.java b/src/main/java/forge/card/cardfactory/CardFactoryArtifacts.java index f28f814a3a5..6bd0a394c03 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryArtifacts.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryArtifacts.java @@ -2,12 +2,11 @@ package forge.card.cardfactory; import javax.swing.JOptionPane; -import com.google.common.base.Predicate; - import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.Command; import forge.Counters; @@ -185,12 +184,7 @@ class CardFactoryArtifacts { } } else { CardList list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); - list = list.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return (c.isLand()); - } - }); + list = list.filter(CardPredicates.Presets.LANDS); AllZone.getComputerPlayer().discard(list.get(0), this); } // else } // resolve() @@ -223,12 +217,7 @@ class CardFactoryArtifacts { public boolean canPlay() { CardList list = card.getController().getCardsIn(ZoneType.Hand); list.remove(card); - list = list.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return (c.isLand()); - } - }); + list = list.filter(CardPredicates.Presets.LANDS); return (list.size() != 0) && super.canPlay(); } // canPlay() }; @@ -399,7 +388,7 @@ class CardFactoryArtifacts { private CardList getComputerLands() { final CardList list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Graveyard); - return list.getType("Basic"); + return list.filter(CardPredicates.Presets.BASIC_LANDS); } } final Cost abCost = new Cost(card, "1 T Sac<1/CARDNAME>", true); diff --git a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java index 0cf248db428..390401eb2a9 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java @@ -57,7 +57,7 @@ import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.gui.GuiUtils; import forge.gui.match.CMatchUI; - +import forge.util.Aggregates; import forge.view.ButtonUtil; /** @@ -215,7 +215,7 @@ public class CardFactoryCreatures { if (card.getController().isHuman()) { final CardList artifacts = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield) - .getType("Artifact"); + .filter(CardPredicates.Presets.ARTIFACTS); if (artifacts.size() != 0) { final Card c = GuiUtils.chooseOne("Select an artifact put a phylactery counter on", artifacts); @@ -257,8 +257,8 @@ public class CardFactoryCreatures { @Override public boolean canPlayAI() { - return (!AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield).getType("Artifact").isEmpty() && AllZone - .getZoneOf(this.getSourceCard()).is(ZoneType.Hand)); + return Iterables.any(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.ARTIFACTS) + && AllZone.getZoneOf(this.getSourceCard()).is(ZoneType.Hand); } }); card.addComesIntoPlayCommand(intoPlay); @@ -541,29 +541,18 @@ public class CardFactoryCreatures { } private static final long serialVersionUID = 35050145102566898L; + private final Predicate untappedCreature = Predicates.and(CardPredicates.Presets.UNTAPPED, CardPredicates.Presets.CREATURES); @Override public boolean canPlayAI() { - CardList wolves = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - wolves = wolves.getType("Wolf"); - - wolves = wolves.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return c.isUntapped() && c.isCreature(); - } - }); - int power = 0; - for (int i = 0; i < wolves.size(); i++) { - power += wolves.get(i).getNetAttack(); - } - - if (power == 0) { + List wolves = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield).getType("Wolf"); + Iterable untappedWolves = Iterables.filter(wolves, untappedCreature); + + final int totalPower = Aggregates.sum(untappedWolves, CardPredicates.Accessors.fnGetNetAttack); + if (totalPower == 0) { return false; } - final int totalPower = power; - CardList targetables = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); targetables = targetables.getTargetableCards(this).filter(new Predicate() { @@ -585,15 +574,8 @@ public class CardFactoryCreatures { @Override public void resolve() { - CardList wolves = card.getController().getCardsIn(ZoneType.Battlefield); - wolves = wolves.getType("Wolf"); - - wolves = wolves.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return c.isUntapped() && c.isCreature(); - } - }); + CardList wolves = card.getController().getCardsIn(ZoneType.Battlefield).getType("Wolf"); + wolves = wolves.filter(untappedCreature); final Card target = this.getTargetCard(); diff --git a/src/main/java/forge/card/cardfactory/CardFactoryEnchantments.java b/src/main/java/forge/card/cardfactory/CardFactoryEnchantments.java index 3b631904661..e743edeace7 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryEnchantments.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryEnchantments.java @@ -20,6 +20,7 @@ import forge.game.zone.ZoneType; import forge.gui.GuiUtils; import forge.gui.match.CMatchUI; import forge.view.ButtonUtil; +import forge.CardPredicates; /** * TODO: Write javadoc for this type. @@ -81,8 +82,8 @@ class CardFactoryEnchantments { public void showMessage() { CardList grave = AllZone.getHumanPlayer().getCardsIn(ZoneType.Graveyard); CardList aiGrave = AllZone.getComputerPlayer().getCardsIn(ZoneType.Graveyard); - grave = grave.getType("Creature"); - aiGrave = aiGrave.getType("Creature"); + grave = grave.filter(CardPredicates.Presets.CREATURES); + aiGrave = aiGrave.filter(CardPredicates.Presets.CREATURES); if (this.once || ((grave.size() < 2) && (aiGrave.size() < 2))) { this.once = false; diff --git a/src/main/java/forge/card/cardfactory/CardFactoryInstants.java b/src/main/java/forge/card/cardfactory/CardFactoryInstants.java index 3ae115f3f5b..9d26ff9acf1 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryInstants.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryInstants.java @@ -17,12 +17,16 @@ */ package forge.card.cardfactory; +import java.util.List; + import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.Command; import forge.Singletons; @@ -77,9 +81,8 @@ public class CardFactoryInstants { @Override public boolean canPlayAI() { - CardList humanArts = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); - humanArts = humanArts.getType("Artifact"); - return humanArts.size() > 0; + List humanCards = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); + return Iterables.any(humanCards, CardPredicates.Presets.ARTIFACTS); } //canPlayAI @Override @@ -91,7 +94,7 @@ public class CardFactoryInstants { public void resolve() { Player player = getTargetPlayer(); CardList artifacts = AllZoneUtil.getCardsIn(ZoneType.Battlefield); - artifacts = artifacts.getType("Artifact"); + artifacts = artifacts.filter(CardPredicates.Presets.ARTIFACTS); for (int i = 0; i < artifacts.size(); i++) { Card thisArtifact = artifacts.get(i); @@ -209,9 +212,8 @@ public class CardFactoryInstants { @Override public boolean canPlayAI() { - CardList creature = AllZone.getComputerPlayer().getCardsIn(ZoneType.Library); - creature = creature.getType("Creature"); - return creature.size() >= 3; + Iterable creature = Iterables.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Library), CardPredicates.Presets.CREATURES); + return Iterables.size(creature) >= 3; } }; // SpellAbility diff --git a/src/main/java/forge/card/cardfactory/CardFactoryLands.java b/src/main/java/forge/card/cardfactory/CardFactoryLands.java index 95f373d1419..f5a9266d77e 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryLands.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryLands.java @@ -25,6 +25,7 @@ import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.Command; import forge.Counters; @@ -381,8 +382,7 @@ class CardFactoryLands { if (this.player.isComputer()) { if (plains.size() > 1) { - CardList tappedPlains = new CardList(plains); - tappedPlains = tappedPlains.getType("Basic"); + CardList tappedPlains = plains.filter(CardPredicates.Presets.BASIC_LANDS); for (final Card c : tappedPlains) { Singletons.getModel().getGameAction().sacrifice(c, null); } diff --git a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java index 60d6d5f4476..e4291c0fb99 100644 --- a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java +++ b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java @@ -21,11 +21,14 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map.Entry; import java.util.Vector; +import java.util.List; import javax.swing.JOptionPane; import com.esotericsoftware.minlog.Log; import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; import forge.AllZone; import forge.AllZoneUtil; @@ -36,6 +39,7 @@ import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.CardUtil; import forge.Command; +import forge.Constant; import forge.Singletons; import forge.card.cost.Cost; import forge.card.spellability.AbilitySub; @@ -372,9 +376,8 @@ public class CardFactorySorceries { // figure out which basic land types the computer has CardList land = AllZoneUtil.getPlayerLandsInPlay(AllZone.getComputerPlayer()); - final String[] basic = { "Forest", "Plains", "Mountain", "Island", "Swamp" }; - for (final String element : basic) { + for (final String element : Constant.Color.BASIC_LANDS) { final CardList cl = land.getType(element); if (!cl.isEmpty()) { // remove one land of this basic type from this list @@ -505,9 +508,8 @@ public class CardFactorySorceries { // figure out which basic land types the human has // put those in an set to use later final CardList land = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); - final String[] basic = { "Forest", "Plains", "Mountain", "Island", "Swamp" }; - for (final String element : basic) { + for (final String element : Constant.Color.BASIC_LANDS) { final CardList c = land.getType(element); if (!c.isEmpty()) { humanBasic.add(element); @@ -531,6 +533,7 @@ public class CardFactorySorceries { // *************** START *********** START ************************** else if (cardName.equals("Haunting Echoes")) { + final Predicate nonBasicLands = Predicates.not(CardPredicates.Presets.BASIC_LANDS); final Cost cost = new Cost(card, "3 B B", false); final Target tgt = new Target(card, "Select a Player", "Player"); final SpellAbility spell = new Spell(card, cost, tgt) { @@ -540,33 +543,21 @@ public class CardFactorySorceries { public boolean canPlayAI() { // Haunting Echoes shouldn't be cast if only basic land in // graveyard or library is empty - CardList graveyard = AllZone.getHumanPlayer().getCardsIn(ZoneType.Graveyard); - final CardList library = AllZone.getHumanPlayer().getCardsIn(ZoneType.Library); - final int graveCount = graveyard.size(); - graveyard = graveyard.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return c.isBasicLand(); - } - }); - + final List graveyard = AllZone.getHumanPlayer().getCardsIn(ZoneType.Graveyard); + final List library = AllZone.getHumanPlayer().getCardsIn(ZoneType.Library); + this.setTargetPlayer(AllZone.getHumanPlayer()); - return (((graveCount - graveyard.size()) > 0) && (library.size() > 0)); + return Iterables.any(graveyard, nonBasicLands) && !library.isEmpty(); } @Override public void resolve() { final Player player = this.getTargetPlayer(); - - CardList grave = player.getCardsIn(ZoneType.Graveyard); - grave = grave.getNotType("Basic"); - final CardList lib = player.getCardsIn(ZoneType.Library); - for (final Card c : grave) { - final CardList remLib = lib.filter(CardPredicates.nameEquals(c.getName())); - for (final Card rem : remLib) { + for (final Card c : Iterables.filter(player.getCardsIn(ZoneType.Graveyard), nonBasicLands)) { + for (final Card rem : Iterables.filter(lib, CardPredicates.nameEquals(c.getName()))) { Singletons.getModel().getGameAction().exile(rem); lib.remove(rem); } @@ -697,7 +688,7 @@ public class CardFactorySorceries { final CardList humCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); CardList compCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer()); - compCreats = compCreats.getType("Creature"); + compCreats = compCreats.filter(CardPredicates.Presets.CREATURES); diff += 1.5 * (humCreats.size() - compCreats.size()); final CardList humHand = AllZone.getHumanPlayer().getCardsIn(ZoneType.Hand); @@ -724,10 +715,7 @@ public class CardFactorySorceries { // turn // is structured, it will already have played land to it's // limit - - CardList hand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); - hand = hand.getType("Land"); - return hand.size() > 0; + return Iterables.any(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS); } @Override @@ -764,10 +752,7 @@ public class CardFactorySorceries { // turn // is structured, it will already have played its first // land. - CardList list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); - - list = list.getType("Land"); - return list.size() > 0; + return Iterables.any(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS); } @Override @@ -1047,8 +1032,7 @@ public class CardFactorySorceries { final HashMap countInGraveyard = new HashMap(); final CardList allGrave = AllZone.getComputerPlayer().getCardsIn(ZoneType.Graveyard); - allGrave.getType("Creature"); - for (final Card c : allGrave) { + for (final Card c : Iterables.filter(allGrave, CardPredicates.Presets.CREATURES)) { for (final String type : c.getType()) { if (CardUtil.isACreatureType(type)) { if (countInGraveyard.containsKey(type)) { diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 3c7b5a23fea..a0e8e7f53c5 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -27,6 +27,7 @@ import java.util.TreeMap; import com.esotericsoftware.minlog.Log; import com.google.common.base.Predicate; +import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import forge.AllZone; @@ -40,6 +41,7 @@ import forge.CardPredicates.Presets; import forge.CardUtil; import forge.Command; import forge.CommandArgs; +import forge.Constant; import forge.Counters; import forge.GameActionUtil; import forge.Singletons; @@ -225,40 +227,32 @@ public class CardFactoryUtil { * @return a {@link forge.Card} object. */ public static Card getBestLandAI(final CardList list) { - final CardList land = list.getType("Land"); + final CardList land = list.filter(CardPredicates.Presets.LANDS); if (!(land.size() > 0)) { return null; } // prefer to target non basic lands - final CardList nbLand = land.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return (!c.isBasicLand()); - } - }); + final CardList nbLand = land.filter(Predicates.not(CardPredicates.Presets.BASIC_LANDS)); if (nbLand.size() > 0) { // TODO - Rank non basics? - - final Random r = MyRandom.getRandom(); - return nbLand.get(r.nextInt(nbLand.size())); + return Aggregates.random(nbLand); } // if no non-basic lands, target the least represented basic land type - final String[] names = { "Plains", "Island", "Swamp", "Mountain", "Forest" }; String sminBL = ""; int iminBL = 20000; // hopefully no one will ever have more than 20000 // lands of one type.... int n = 0; - for (int i = 0; i < 5; i++) { - n = land.getType(names[i]).size(); + for (String name : Constant.Color.BASIC_LANDS) { + n = land.getType(name).size(); if ((n < iminBL) && (n > 0)) { // if two or more are tied, only the // first // one checked will be used iminBL = n; - sminBL = names[i]; + sminBL = name; } } if (iminBL == 20000) { @@ -266,16 +260,14 @@ public class CardFactoryUtil { } final CardList bLand = land.getType(sminBL); - for (int i = 0; i < bLand.size(); i++) { - if (!bLand.get(i).isTapped()) { - // prefer untapped lands - return bLand.get(i); - } + + for( Card ut : Iterables.filter(bLand, CardPredicates.Presets.UNTAPPED) ) + { + return ut; } - final Random r = MyRandom.getRandom(); - return bLand.get(r.nextInt(bLand.size())); // random tapped land of - // least represented type + + return Aggregates.random(bLand); // random tapped land of least represented type } // The AI doesn't really pick the best enchantment, just the most expensive. @@ -293,8 +285,7 @@ public class CardFactoryUtil { * @return a {@link forge.Card} object. */ public static Card getBestEnchantmentAI(final CardList list, final SpellAbility spell, final boolean targeted) { - CardList all = list; - all = all.getType("Enchantment"); + CardList all = list.filter(CardPredicates.Presets.ENCHANTMENTS); if (targeted) { all = all.filter(new Predicate() { @@ -304,25 +295,9 @@ public class CardFactoryUtil { } }); } - if (all.size() == 0) { - return null; - } - + // get biggest Enchantment - Card biggest = null; - biggest = all.get(0); - - int bigCMC = 0; - for (int i = 0; i < all.size(); i++) { - final int curCMC = all.get(i).getManaCost().getCMC(); - - if (curCMC > bigCMC) { - bigCMC = curCMC; - biggest = all.get(i); - } - } - - return biggest; + return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc); } // The AI doesn't really pick the best artifact, just the most expensive. @@ -336,27 +311,12 @@ public class CardFactoryUtil { * @return a {@link forge.Card} object. */ public static Card getBestArtifactAI(final CardList list) { - CardList all = list; - all = all.getType("Artifact"); + CardList all = list.filter(CardPredicates.Presets.ARTIFACTS); if (all.size() == 0) { return null; } - // get biggest Artifact - Card biggest = null; - biggest = all.get(0); - - int bigCMC = 0; - for (int i = 0; i < all.size(); i++) { - final int curCMC = all.get(i).getManaCost().getCMC(); - - if (curCMC > bigCMC) { - bigCMC = curCMC; - biggest = all.get(i); - } - } - - return biggest; + return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc); } /** @@ -650,20 +610,8 @@ public class CardFactoryUtil { * @return the card */ public static Card getBestCreatureAI(final CardList list) { - CardList all = list; - all = all.getType("Creature"); - Card biggest = null; - - if (all.size() != 0) { - biggest = all.get(0); - - for (int i = 0; i < all.size(); i++) { - if (CardFactoryUtil.evaluateCreature(biggest) < CardFactoryUtil.evaluateCreature(all.get(i))) { - biggest = all.get(i); - } - } - } - return biggest; + CardList all = list.filter(CardPredicates.Presets.CREATURES); + return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnEvaluateCreature); } // This selection rates tokens higher @@ -678,8 +626,7 @@ public class CardFactoryUtil { */ public static Card getBestCreatureToBounceAI(final CardList list) { final int tokenBonus = 40; - CardList all = list; - all = all.getType("Creature"); + CardList all = list.filter(CardPredicates.Presets.CREATURES); Card biggest = null; // returns null if list.size() == 0 int biggestvalue = 0; int newvalue = 0; @@ -728,21 +675,9 @@ public class CardFactoryUtil { * @return a {@link forge.Card} object. */ public static Card getWorstCreatureAI(final CardList list) { - CardList all = list; - all = all.getType("Creature"); + CardList all = list.filter(CardPredicates.Presets.CREATURES); // get smallest creature - Card smallest = null; - - if (all.size() != 0) { - smallest = all.get(0); - - for (int i = 0; i < all.size(); i++) { - if (CardFactoryUtil.evaluateCreature(smallest) > CardFactoryUtil.evaluateCreature(all.get(i))) { - smallest = all.get(i); - } - } - } - return smallest; + return Aggregates.itemWithMin(all, CardPredicates.Accessors.fnEvaluateCreature); } /** @@ -769,24 +704,25 @@ public class CardFactoryUtil { } System.out.println("getWorstPermanentAI: " + list); - if (biasEnch && (list.getType("Enchantment").size() > 0)) { - return CardFactoryUtil.getCheapestPermanentAI(list.getType("Enchantment"), null, false); + if (biasEnch && Iterables.any(list, CardPredicates.Presets.ENCHANTMENTS)) { + return CardFactoryUtil.getCheapestPermanentAI(list.filter(CardPredicates.Presets.ENCHANTMENTS), null, false); } - if (biasArt && (list.getType("Artifact").size() > 0)) { - return CardFactoryUtil.getCheapestPermanentAI(list.getType("Artifact"), null, false); + if (biasArt && Iterables.any(list, CardPredicates.Presets.ARTIFACTS)) { + return CardFactoryUtil.getCheapestPermanentAI(list.filter(CardPredicates.Presets.ARTIFACTS), null, false); } - if (biasLand && (list.getType("Land").size() > 0)) { - return CardFactoryUtil.getWorstLand(list.getType("Land")); + if (biasLand && Iterables.any(list, CardPredicates.Presets.LANDS)) { + return CardFactoryUtil.getWorstLand(list.filter(CardPredicates.Presets.LANDS)); } - if (biasCreature && (list.getType("Creature").size() > 0)) { - return CardFactoryUtil.getWorstCreatureAI(list.getType("Creature")); + if (biasCreature && Iterables.any(list, CardPredicates.Presets.CREATURES)) { + return CardFactoryUtil.getWorstCreatureAI(list.filter(CardPredicates.Presets.CREATURES)); } - if (list.getType("Land").size() > 6) { - return CardFactoryUtil.getWorstLand(list.getType("Land")); + CardList lands = list.filter(CardPredicates.Presets.LANDS); + if (lands.size() > 6) { + return CardFactoryUtil.getWorstLand(lands); } if ((list.getType("Artifact").size() > 0) || (list.getType("Enchantment").size() > 0)) { @@ -2540,10 +2476,8 @@ public class CardFactoryUtil { // Count$Domain if (sq[0].contains("Domain")) { someCards.addAll(cardController.getCardsIn(ZoneType.Battlefield)); - final String[] basic = { "Forest", "Plains", "Mountain", "Island", "Swamp" }; - - for (int i = 0; i < basic.length; i++) { - if (!someCards.getType(basic[i]).isEmpty()) { + for (String basic : Constant.Color.BASIC_LANDS) { + if (!someCards.getType(basic).isEmpty()) { n++; } } @@ -2553,10 +2487,8 @@ public class CardFactoryUtil { // Count$OpponentDom if (sq[0].contains("OpponentDom")) { someCards.addAll(cardController.getOpponent().getCardsIn(ZoneType.Battlefield)); - final String[] basic = { "Forest", "Plains", "Mountain", "Island", "Swamp" }; - - for (int i = 0; i < basic.length; i++) { - if (!someCards.getType(basic[i]).isEmpty()) { + for (String basic : Constant.Color.BASIC_LANDS) { + if (!someCards.getType(basic).isEmpty()) { n++; } } @@ -3702,38 +3634,14 @@ public class CardFactoryUtil { */ public static Card getWorstLand(final CardList lands) { Card worstLand = null; + int maxScore = 0; // first, check for tapped, basic lands - for (int i = 0; i < lands.size(); i++) { - final Card tmp = lands.get(i); - if (tmp.isTapped() && tmp.isBasicLand()) { + for (Card tmp : lands) { + int score = tmp.isTapped() ? 2 : 0; + score += tmp.isBasicLand() ? 1 : 0; + if( score >= maxScore ) { worstLand = tmp; - } - } - // next, check for tapped, non-basic lands - if (worstLand == null) { - for (int i = 0; i < lands.size(); i++) { - final Card tmp = lands.get(i); - if (tmp.isTapped()) { - worstLand = tmp; - } - } - } - // next, untapped, basic lands - if (worstLand == null) { - for (int i = 0; i < lands.size(); i++) { - final Card tmp = lands.get(i); - if (tmp.isUntapped() && tmp.isBasicLand()) { - worstLand = tmp; - } - } - } - // next, untapped, non-basic lands - if (worstLand == null) { - for (int i = 0; i < lands.size(); i++) { - final Card tmp = lands.get(i); - if (tmp.isUntapped()) { - worstLand = tmp; - } + maxScore = score; } } return worstLand; diff --git a/src/main/java/forge/card/mana/Mana.java b/src/main/java/forge/card/mana/Mana.java index 2bbc061998c..cd2238cef15 100644 --- a/src/main/java/forge/card/mana/Mana.java +++ b/src/main/java/forge/card/mana/Mana.java @@ -120,17 +120,6 @@ public class Mana { return this.pumpCounterMagic; } - /** - *

- * fromBasicLand. - *

- * - * @return a boolean. - */ - public final boolean fromBasicLand() { - return this.sourceCard.isBasicLand(); - } // for Imperiosaur - /** *

* isColor. diff --git a/src/main/java/forge/card/spellability/SpellPermanent.java b/src/main/java/forge/card/spellability/SpellPermanent.java index 6398708a1e9..007347955d1 100644 --- a/src/main/java/forge/card/spellability/SpellPermanent.java +++ b/src/main/java/forge/card/spellability/SpellPermanent.java @@ -18,6 +18,7 @@ package forge.card.spellability; import java.util.HashMap; +import java.util.List; import com.google.common.collect.Iterables; @@ -355,10 +356,11 @@ public class SpellPermanent extends Spell { } if (card.isPlaneswalker()) { CardList list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - list = list.getType("Planeswalker"); + list = list.filter(CardPredicates.Presets.PLANEWALKERS); for (int i = 0; i < list.size(); i++) { - final String subtype = card.getType().get(card.getType().size() - 1); + List type = card.getType(); + final String subtype = type.get(type.size() - 1); final CardList cl = list.getType(subtype); if (cl.size() > 0) { diff --git a/src/main/java/forge/control/input/InputAttack.java b/src/main/java/forge/control/input/InputAttack.java index 7c5ac816724..450cb459968 100644 --- a/src/main/java/forge/control/input/InputAttack.java +++ b/src/main/java/forge/control/input/InputAttack.java @@ -17,9 +17,12 @@ */ package forge.control.input; +import com.google.common.collect.Iterables; + import forge.AllZone; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.Singletons; import forge.game.phase.CombatUtil; import forge.game.zone.PlayerZone; @@ -62,9 +65,7 @@ public class InputAttack extends Input { if (AllZone.getCombat().getRemainingDefenders() == 0) { // Nothing left to attack, has to attack this defender CardList possibleAttackers = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); - possibleAttackers = possibleAttackers.getType("Creature"); - for (int i = 0; i < possibleAttackers.size(); i++) { - final Card c = possibleAttackers.get(i); + for (Card c : Iterables.filter(possibleAttackers, CardPredicates.Presets.CREATURES)) { if (c.hasKeyword("CARDNAME attacks each turn if able.") && CombatUtil.canAttack(c, AllZone.getCombat()) && !c.isAttacking()) { AllZone.getCombat().addAttacker(c); diff --git a/src/main/java/forge/game/GameNew.java b/src/main/java/forge/game/GameNew.java index bb13fe84b64..9b260909ae3 100644 --- a/src/main/java/forge/game/GameNew.java +++ b/src/main/java/forge/game/GameNew.java @@ -7,10 +7,15 @@ import java.util.Random; import javax.swing.JOptionPane; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; + import forge.AllZone; import forge.Card; import forge.CardList; import forge.CardPredicates.Presets; +import forge.CardPredicates; import forge.CardUtil; import forge.Constant; import forge.GameAction; @@ -31,6 +36,7 @@ import forge.item.CardPrinted; import forge.properties.ForgePreferences.FPref; import forge.properties.ForgeProps; import forge.properties.NewConstants.Lang.GameAction.GameActionText; +import forge.util.Aggregates; import forge.util.MyRandom; /** @@ -268,17 +274,14 @@ public class GameNew { final String nl = System.getProperty("line.separator"); final StringBuilder msg = new StringBuilder(); for (final Player p : AllZone.getPlayersInGame()) { - final CardList lib = p.getCardsIn(ZoneType.Library); - Card ante; - if ((lib.size() > 0) && (lib.getNotType("Basic").size() > 1)) { - ante = CardUtil.getRandom(lib); - while (ante.isBasicLand()) { - ante = CardUtil.getRandom(lib); - } - } else if (lib.size() > 1) { - ante = lib.get(0); - } else { - throw new RuntimeException(p + " library is empty."); + final List lib = p.getCardsIn(ZoneType.Library); + Predicate goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS); + Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte)); + if (ante == null ) { + if (!lib.isEmpty()) + ante = lib.get(0); + else + throw new RuntimeException(p + " library is empty."); } AllZone.getGameLog().add("Ante", p + " anted " + ante, 0); VAntes.SINGLETON_INSTANCE.addAnteCard(p, ante); @@ -375,10 +378,10 @@ public class GameNew { library.shuffle(); // remove all land, keep non-basicland in there, shuffled - CardList land = library.getType("Land"); - for (int i = 0; i < land.size(); i++) { - if (land.get(i).isLand()) { - library.remove(land.get(i)); + CardList land = library.filter(CardPredicates.Presets.LANDS); + for (Card c : land) { + if (c.isLand()) { + library.remove(c); } } @@ -444,10 +447,10 @@ public class GameNew { */ private static void seeWhoPlaysFirst() { final GameAction ga = Singletons.getModel().getGameAction(); - CardList hLibrary = AllZone.getHumanPlayer().getCardsIn(ZoneType.Library); - hLibrary = hLibrary.filter(Presets.NON_LANDS); - CardList cLibrary = AllZone.getComputerPlayer().getCardsIn(ZoneType.Library); - cLibrary = cLibrary.filter(Presets.NON_LANDS); + Predicate nonLand = Predicates.not(Presets.LANDS); + Iterable hLibrary = Iterables.filter(AllZone.getHumanPlayer().getCardsIn(ZoneType.Library), nonLand); + Iterable cLibrary = Iterables.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Library), nonLand); + final boolean starterDetermined = false; int cutCount = 0; @@ -457,8 +460,9 @@ public class GameNew { break; } - if (hLibrary.size() > 0) { - ga.setHumanCut(hLibrary.get(MyRandom.getRandom().nextInt(hLibrary.size()))); + Card hRandom = Aggregates.random(hLibrary); + if ( null != hRandom ) { + ga.setHumanCut(hRandom); } else { GameNew.computerStartsGame(); JOptionPane.showMessageDialog(null, ForgeProps.getLocalized(GameActionText.HUMAN_MANA_COST) + "\r\n" @@ -466,8 +470,9 @@ public class GameNew { return; } - if (cLibrary.size() > 0) { - ga.setComputerCut(cLibrary.get(MyRandom.getRandom().nextInt(cLibrary.size()))); + Card cRandom = Aggregates.random(cLibrary); + if (cRandom != null) { + ga.setComputerCut(cRandom); } else { JOptionPane.showMessageDialog(null, ForgeProps.getLocalized(GameActionText.COMPUTER_MANA_COST) + "\r\n" + ForgeProps.getLocalized(GameActionText.HUMAN_STARTS), "", JOptionPane.INFORMATION_MESSAGE); diff --git a/src/main/java/forge/game/phase/Combat.java b/src/main/java/forge/game/phase/Combat.java index e62d508f58b..7f10801c8b3 100644 --- a/src/main/java/forge/game/phase/Combat.java +++ b/src/main/java/forge/game/phase/Combat.java @@ -30,6 +30,7 @@ import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; +import forge.CardPredicates; import forge.GameActionUtil; import forge.GameEntity; import forge.Singletons; @@ -111,7 +112,7 @@ public class Combat { this.defenders.add((GameEntity) defender); this.defenderMap.put((GameEntity) defender, new CardList()); CardList planeswalkers = defender.getCardsIn(ZoneType.Battlefield); - planeswalkers = planeswalkers.getType("Planeswalker"); + planeswalkers = planeswalkers.filter(CardPredicates.Presets.PLANEWALKERS); for (final Card pw : planeswalkers) { this.defenders.add((GameEntity) pw); this.defenderMap.put((GameEntity) pw, new CardList()); diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index f578afb69f2..f6245ff6c3b 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -33,6 +33,7 @@ import forge.AllZoneUtil; import forge.Card; import forge.CardList; import forge.CardListUtil; +import forge.CardPredicates; import forge.Command; import forge.Constant; import forge.Counters; @@ -400,7 +401,7 @@ public class CombatUtil { boolean must = true; if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")) { final CardList possibleBlockers = combat.getDefendingPlayer().getCardsIn(ZoneType.Battlefield) - .getType("Creature"); + .filter(CardPredicates.Presets.CREATURES); possibleBlockers.remove(blocker); if (!CombatUtil.canBeBlocked(attacker, possibleBlockers)) { must = false; @@ -524,7 +525,7 @@ public class CombatUtil { boolean canBe = true; if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")) { final CardList blockers = combat.getDefendingPlayer().getCardsIn(ZoneType.Battlefield) - .getType("Creature"); + .filter(CardPredicates.Presets.CREATURES); blockers.remove(blocker); if (!CombatUtil.canBeBlocked(attacker, blockers)) { canBe = false; @@ -542,7 +543,7 @@ public class CombatUtil { boolean canBe = true; if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")) { final CardList blockers = combat.getDefendingPlayer().getCardsIn(ZoneType.Battlefield) - .getType("Creature"); + .filter(CardPredicates.Presets.CREATURES); blockers.remove(blocker); if (!CombatUtil.canBeBlocked(attacker, blockers)) { canBe = false; @@ -929,12 +930,7 @@ public class CombatUtil { return false; } } else if (keyword.equals("CARDNAME can't attack unless defending player controls a snow land.")) { - temp = list.filter(new Predicate() { - @Override - public boolean apply(final Card c) { - return c.isLand() && c.isSnow(); - } - }); + temp = list.filter(CardPredicates.Presets.SNOW_LANDS); if (temp.isEmpty()) { return false; } diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index f4575ec8527..dc833c15a52 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -831,7 +831,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { // resets the status of attacked/blocked this phase CardList list = player.getCardsIn(ZoneType.Battlefield); - list = list.getType("Creature"); + list = list.filter(CardPredicates.Presets.CREATURES); for (int i = 0; i < list.size(); i++) { final Card c = list.get(i); diff --git a/src/main/java/forge/game/phase/Upkeep.java b/src/main/java/forge/game/phase/Upkeep.java index acaa9e46b95..1963e8812da 100644 --- a/src/main/java/forge/game/phase/Upkeep.java +++ b/src/main/java/forge/game/phase/Upkeep.java @@ -1959,9 +1959,8 @@ public class Upkeep extends Phase implements java.io.Serializable { oathFlag = false; } } else { // if player == Computer - final CardList creaturesInLibrary = player.getCardsIn(ZoneType.Library).getType("Creature"); - final CardList creaturesInBattlefield = player.getCardsIn(ZoneType.Battlefield).getType( - "Creature"); + final CardList creaturesInLibrary = player.getCardsIn(ZoneType.Library).filter(CardPredicates.Presets.CREATURES); + final CardList creaturesInBattlefield = player.getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.CREATURES); // if there are at least 3 creatures in library, // or none in play with one in library, oath diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java index a0d85395708..eadae66fc5f 100644 --- a/src/main/java/forge/game/player/AIPlayer.java +++ b/src/main/java/forge/game/player/AIPlayer.java @@ -19,6 +19,8 @@ package forge.game.player; import java.util.Random; +import com.google.common.collect.Iterables; + import forge.AllZone; import forge.Card; import forge.CardList; @@ -201,9 +203,9 @@ public class AIPlayer extends Player { boolean bottom = false; if (topN.get(i).isBasicLand()) { CardList bl = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - bl = bl.filter(CardPredicates.Presets.BASIC_LANDS); + int nBasicLands = Iterables.size(Iterables.filter(bl, CardPredicates.Presets.BASIC_LANDS)); - bottom = bl.size() > 5; // if control more than 5 Basic land, + bottom = nBasicLands > 5; // if control more than 5 Basic land, // probably don't need more } else if (topN.get(i).isCreature()) { CardList cl = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index 22c28ac5845..de1f0d8b875 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -21,8 +21,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; +import java.util.List; import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import forge.AllZone; import forge.AllZoneUtil; @@ -32,6 +34,7 @@ import forge.CardListUtil; import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.CardUtil; +import forge.Constant; import forge.GameActionUtil; import forge.Singletons; import forge.card.abilityfactory.AbilityFactory; @@ -1386,15 +1389,14 @@ public class ComputerUtil { Card land = landList.get(ix); //play basic lands that are needed the most - if (landList.getNotType("Basic").isEmpty()) { + if (!Iterables.any(landList, CardPredicates.Presets.BASIC_LANDS)) { final CardList combined = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - final String[] names = "Plains,Island,Swamp,Mountain,Forest".split(","); final ArrayList basics = new ArrayList(); // what types can I go get? - for (final String name : names) { - if (landList.getType(name).size() != 0) { + for (final String name : Constant.CardTypes.BASIC_TYPES) { + if (!landList.getType(name).isEmpty()) { basics.add(name); } } @@ -1611,8 +1613,9 @@ public class ComputerUtil { if (hand.size() <= 0) { continue; } - final int numLandsInPlay = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield).getType("Land").size(); - final CardList landsInHand = hand.getType("Land"); + List aiCards = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + final int numLandsInPlay = Iterables.size(Iterables.filter(aiCards, CardPredicates.Presets.LANDS)); + final CardList landsInHand = hand.filter(CardPredicates.Presets.LANDS); final int numLandsInHand = landsInHand.size(); // Discard a land @@ -2257,8 +2260,8 @@ public class ComputerUtil { if (!discard.getSVar("DiscardMe").equals("")) { return true; } - final CardList landsInPlay = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield).getType("Land"); - final CardList landsInHand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand).getType("Land"); + final CardList landsInPlay = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.LANDS); + final CardList landsInHand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand).filter(CardPredicates.Presets.LANDS); final CardList nonLandsInHand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand).getNotType("Land"); final int highestCMC = Math.max(6, Aggregates.max(nonLandsInHand, CardPredicates.Accessors.fnGetCmc)); final int discardCMC = discard.getCMC(); diff --git a/src/main/java/forge/game/player/ComputerUtilAttack.java b/src/main/java/forge/game/player/ComputerUtilAttack.java index 9f0d96c1aa8..b7fdf6fdfff 100644 --- a/src/main/java/forge/game/player/ComputerUtilAttack.java +++ b/src/main/java/forge/game/player/ComputerUtilAttack.java @@ -27,6 +27,7 @@ import forge.AllZoneUtil; import forge.Card; import forge.CardList; import forge.CardListUtil; +import forge.CardPredicates; import forge.Counters; import forge.GameEntity; import forge.Singletons; @@ -75,10 +76,10 @@ public class ComputerUtilAttack { */ public ComputerUtilAttack(final CardList possibleAttackers, final CardList possibleBlockers) { this.humanList = new CardList(possibleBlockers); - this.humanList = this.humanList.getType("Creature"); + this.humanList = this.humanList.filter(CardPredicates.Presets.CREATURES); this.computerList = new CardList(possibleAttackers); - this.computerList = this.computerList.getType("Creature"); + this.computerList = this.computerList.filter(CardPredicates.Presets.CREATURES); this.attackers = this.getPossibleAttackers(possibleAttackers); this.blockers = this.getPossibleBlockers(possibleBlockers, this.attackers); diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 979e28125bf..10bd3178280 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -28,6 +28,8 @@ import java.util.Random; import javax.swing.JOptionPane; +import com.google.common.collect.Iterables; + import forge.AllZone; import forge.AllZoneUtil; import forge.Card; @@ -1886,7 +1888,7 @@ public abstract class Player extends GameEntity implements Comparable { * @return a {@link forge.Card} object. */ public final Card getPlaneswalker() { - final CardList c = this.getCardsIn(ZoneType.Battlefield).getType("Planeswalker"); + final CardList c = this.getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.PLANEWALKERS); if ((null != c) && (c.size() > 0)) { return c.get(0); } else { @@ -2284,7 +2286,7 @@ public abstract class Player extends GameEntity implements Comparable { * @return a boolean. */ public final boolean hasMetalcraft() { - final CardList list = this.getCardsIn(ZoneType.Battlefield).getType("Artifact"); + final CardList list = this.getCardsIn(ZoneType.Battlefield).filter(CardPredicates.Presets.ARTIFACTS); return list.size() >= 3; } @@ -2318,9 +2320,8 @@ public abstract class Player extends GameEntity implements Comparable { * @return a boolean. */ public final boolean hasLandfall() { - final CardList list = ((DefaultPlayerZone) this.getZone(ZoneType.Battlefield)).getCardsAddedThisTurn(null).getType( - "Land"); - return !list.isEmpty(); + final List list = ((DefaultPlayerZone) this.getZone(ZoneType.Battlefield)).getCardsAddedThisTurn(null); + return Iterables.any(list, CardPredicates.Presets.LANDS); } /** diff --git a/src/main/java/forge/util/Aggregates.java b/src/main/java/forge/util/Aggregates.java index 771f5d868a1..a040113adcb 100644 --- a/src/main/java/forge/util/Aggregates.java +++ b/src/main/java/forge/util/Aggregates.java @@ -26,6 +26,20 @@ public class Aggregates { return max; } + public final static T itemWithMax(final Iterable source, final Function valueAccessor) { + if (source == null) { return null; } + int max = Integer.MIN_VALUE; + T result = null; + for (final T c : source) { + int value = valueAccessor.apply(c); + if ( value > max ) { + max = value; + result = c; + } + } + return result; + } + public final static int sum(final Iterable source, final Function valueAccessor) { int result = 0; if (source != null) { @@ -58,15 +72,6 @@ public class Aggregates { // Get several random values // should improve to make 1 pass over source and track N candidates at once - /** - * Random. - * - * @param source - * the source - * @param count - * the count - * @return the list - */ public final static List random(final Iterable source, final int count) { final List result = new ArrayList(); for (int i = 0; i < count; ++i) { @@ -79,27 +84,27 @@ public class Aggregates { return result; } - /** - * Unique by last. - * - * @param - * the key type - * @param - * the generic type - * @param source - * the source - * @param fnUniqueKey - * the fn unique key - * @param accessor - * the accessor - * @return the iterable - */ public static final Iterable uniqueByLast(final Iterable source, final Function fnUniqueKey) { // this might be exotic final Map uniques = new Hashtable(); for (final U c : source) { uniques.put(fnUniqueKey.apply(c), c); } return uniques.values(); + } + + + public static T itemWithMin(final Iterable source, final Function valueAccessor) { + if (source == null) { return null; } + int max = Integer.MAX_VALUE; + T result = null; + for (final T c : source) { + int value = valueAccessor.apply(c); + if ( value < max ) { + max = value; + result = c; + } + } + return result; } }