diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java index f6f3d422cf1..e8e6f7a645e 100644 --- a/src/main/java/forge/game/player/AIPlayer.java +++ b/src/main/java/forge/game/player/AIPlayer.java @@ -46,7 +46,7 @@ public class AIPlayer extends Player { *

* Constructor for AIPlayer. *

- * @param computerAIGeneral + * @param computerAIGeneral * * @param myName * a {@link java.lang.String} object. @@ -56,7 +56,7 @@ public class AIPlayer extends Player { getController().setAiInput(new ComputerAIInput(new ComputerAIGeneral(this, game))); } - + // ////////////// // / // / Methods to ease transition to Abstract Player class @@ -74,7 +74,7 @@ public class AIPlayer extends Player { return false; } - + /** *

* isComputer. diff --git a/src/main/java/forge/game/player/ComputerAIGeneral.java b/src/main/java/forge/game/player/ComputerAIGeneral.java index e70fd4ac69c..2f10983be59 100644 --- a/src/main/java/forge/game/player/ComputerAIGeneral.java +++ b/src/main/java/forge/game/player/ComputerAIGeneral.java @@ -46,8 +46,8 @@ import forge.game.zone.ZoneType; */ public class ComputerAIGeneral implements Computer { - final private Player player; - private final GameState game; + private final Player player; + private final GameState game; /** *

* Constructor for ComputerAI_General. @@ -102,20 +102,20 @@ public class ComputerAIGeneral implements Computer { for (final Card c : all) { for (final SpellAbility sa : c.getSpellAbility()) { - + if (sa.getApi() == null) { continue; } /// ???? - // if ( sa.isAbility() || sa.isSpell() && sa.getApi() != ApiType.Pump ) continue + // if ( sa.isAbility() || sa.isSpell() && sa.getApi() != ApiType.Pump ) continue if (sa.hasParam("AB") && !sa.getParam("AB").equals("Pump")) { continue; } if (sa.hasParam("SP") && !sa.getParam("SP").equals("Pump")) { continue; } - + if (sa.hasParam("KW") && sa.getParam("KW").contains("Haste")) { return true; } @@ -174,7 +174,7 @@ public class ComputerAIGeneral implements Computer { } return false; } - + /** *

* hasETBTrigger. @@ -304,10 +304,11 @@ public class ComputerAIGeneral implements Computer { player.getZone(ZoneType.Battlefield).updateObservers(); game.getPhaseHandler().setPlayerMayHavePriority(false); - + // ai is about to attack, cancel all phase skipping - for (Player p : game.getPlayers()) + for (Player p : game.getPlayers()) { p.getController().autoPassCancel(); + } } /** @@ -320,7 +321,7 @@ public class ComputerAIGeneral implements Computer { final List blockers = player.getCreaturesInPlay(); game.setCombat(ComputerUtilBlock.getBlockers(player, game.getCombat(), blockers)); - + CombatUtil.orderMultipleCombatants(game.getCombat()); game.getPhaseHandler().setPlayerMayHavePriority(false); diff --git a/src/main/java/forge/game/player/ComputerAIInput.java b/src/main/java/forge/game/player/ComputerAIInput.java index 05b901ee87b..f98f613d8f3 100644 --- a/src/main/java/forge/game/player/ComputerAIInput.java +++ b/src/main/java/forge/game/player/ComputerAIInput.java @@ -64,8 +64,9 @@ public class ComputerAIInput extends Input { @Override public final void showMessage() { // should not think when the game is over - if( Singletons.getModel().getGame().isGameOver() ) + if (Singletons.getModel().getGame().isGameOver()) { return; + } /* * //put this back in ButtonUtil.disableAll(); @@ -124,5 +125,5 @@ public class ComputerAIInput extends Input { /* (non-Javadoc) * @see forge.control.input.Input#isClassUpdated() */ - @Override public void isClassUpdated() {} + @Override public void isClassUpdated() { } } diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index e35e244372d..c2d297777ae 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -1171,10 +1171,10 @@ public class ComputerUtil { final StringBuilder choiceString = new StringBuilder(); - - final Card source = manaAb.getSourceCard(); + + final Card source = manaAb.getSourceCard(); final AbilityManaPart abMana = manaAb.getManaPart(); - + if (abMana.isComboMana()) { int amount = manaAb.hasParam("Amount") ? AbilityFactory.calculateAmount(source, manaAb.getParam("Amount"), saRoot) : 1; final ManaCost testCost = new ManaCost(cost.toString().replace("X ", "")); @@ -1466,7 +1466,7 @@ public class ComputerUtil { */ public static List chooseSacrificeType(final Player ai, final String type, final Card activate, final Card target, final int amount) { - List typeList = + List typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate); if (ai.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { typeList = CardLists.getNotType(typeList, "Creature"); @@ -1539,8 +1539,8 @@ public class ComputerUtil { Card prefCard = null; if (sa != null && sa.getActivatingPlayer() != null && sa.getActivatingPlayer().isHuman()) { for (Card c : hand) { - if (c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME," + - " put it onto the battlefield instead of putting it into your graveyard.")) { + if (c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME," + + " put it onto the battlefield instead of putting it into your graveyard.")) { prefCard = c; break; } @@ -1660,7 +1660,7 @@ public class ComputerUtil { * @return a {@link forge.CardList} object. */ public static List chooseTapType(final Player ai, final String type, final Card activate, final boolean tap, final int amount) { - List typeList = + List typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), activate.getController(), activate); // is this needed? @@ -1700,7 +1700,7 @@ public class ComputerUtil { * @return a {@link forge.CardList} object. */ public static List chooseUntapType(final Player ai, final String type, final Card activate, final boolean untap, final int amount) { - List typeList = + List typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), activate.getController(), activate); // is this needed? @@ -1740,7 +1740,7 @@ public class ComputerUtil { * @return a {@link forge.CardList} object. */ public static List chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount) { - final List typeList = + final List typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), activate.getController(), activate); if ((target != null) && target.getController().isComputer() && typeList.contains(target)) { // don't bounce the card we're pumping @@ -1804,7 +1804,7 @@ public class ComputerUtil { public int compare(final SpellAbility a, final SpellAbility b) { int a1 = CardUtil.getConvertedManaCost(a.getManaCost()); int b1 = CardUtil.getConvertedManaCost(b.getManaCost()); - + // cast 0 mana cost spells first (might be a Mox) if (a1 == 0) { b1 = -2; @@ -1999,7 +1999,7 @@ public class ComputerUtil { if (sa.getApi() == null || !sa.isAbility()) { continue; } - + if (sa.getApi() == ApiType.PreventDamage && sa.canPlay() && ComputerUtil.canPayCost(sa, controller)) { if (AbilityFactory.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa).contains(card)) { @@ -2160,8 +2160,8 @@ public class ComputerUtil { } return false; } - - + + public static boolean targetHumanAI(final SpellAbility sa) { if (sa == null || sa.getActivatingPlayer() == null) { return false; @@ -2187,12 +2187,12 @@ public class ComputerUtil { public static boolean waitForBlocking(final SpellAbility sa) { final PhaseHandler ph = Singletons.getModel().getGame().getPhaseHandler(); - return (sa.getSourceCard().isCreature() - && sa.getPayCosts().getTap() - && (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) + return (sa.getSourceCard().isCreature() + && sa.getPayCosts().getTap() + && (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) || !ph.getNextTurn().equals(sa.getActivatingPlayer()))); } - + // returns true if the AI should stop using the ability /** *

@@ -2209,7 +2209,7 @@ public class ComputerUtil { return false; } final Random r = MyRandom.getRandom(); - + return r.nextFloat() <= Math.pow(.95, activations); } } diff --git a/src/main/java/forge/game/player/ComputerUtilAttack.java b/src/main/java/forge/game/player/ComputerUtilAttack.java index 0484da26725..d09c3f2a96d 100644 --- a/src/main/java/forge/game/player/ComputerUtilAttack.java +++ b/src/main/java/forge/game/player/ComputerUtilAttack.java @@ -78,10 +78,11 @@ public class ComputerUtilAttack { this.computerList = ai.getCreaturesInPlay(); this.attackers = new ArrayList(); - for(Card c : computerList) - if (CombatUtil.canAttack(c, human)) + for (Card c : computerList) { + if (CombatUtil.canAttack(c, human)) { attackers.add(c); - + } + } this.blockers = this.getPossibleBlockers(humanList, this.attackers); } // constructor @@ -271,7 +272,7 @@ public class ComputerUtilAttack { } final Player opp = ai.getOpponent(); - + // Increase the total number of blockers needed by 1 if Finest Hour in // play // (human will get an extra first attack with a creature that untaps) @@ -478,7 +479,7 @@ public class ComputerUtilAttack { // do the same thing on turn 3 if he had the same creatures in play // I know this is a little confusing GameState game = Singletons.getModel().getGame(); - + this.random.setSeed(game.getPhaseHandler().getTurn() + this.randomInt); final Combat combat = new Combat(); @@ -739,7 +740,7 @@ public class ComputerUtilAttack { // totals and other considerations // some bad "magic numbers" here, TODO replace with nice descriptive // variable names - if (ratioDiff > 0 && doAttritionalAttack) { + if (ratioDiff > 0 && doAttritionalAttack) { this.aiAggression = 5; // attack at all costs } else if (ratioDiff >= 1 && (humanLifeToDamageRatio < 2 || outNumber > 0)) { this.aiAggression = 4; // attack expecting to trade or damage player. @@ -783,7 +784,7 @@ public class ComputerUtilAttack { if (this.shouldAttack(ai, attacker, this.blockers, combat) && CombatUtil.canAttack(attacker, combat)) { combat.addAttacker(attacker); - // check if attackers are enough to finish the attacked planeswalker + // check if attackers are enough to finish the attacked planeswalker if (combat.getCurrentDefenderNumber() > 0) { Card pw = (Card) combat.getDefender(); final int blockNum = this.blockers.size(); @@ -875,7 +876,7 @@ public class ComputerUtilAttack { boolean hasCombatEffect = attacker.getSVar("HasCombatEffect").equals("TRUE"); if (!hasCombatEffect) { for (String keyword : attacker.getKeyword()) { - if (keyword.equals("Wither") || keyword.equals("Infect") || keyword.equals("Lifelink") ) { + if (keyword.equals("Wither") || keyword.equals("Infect") || keyword.equals("Lifelink")) { hasCombatEffect = true; break; } @@ -888,8 +889,8 @@ public class ComputerUtilAttack { // the selected strategy for (final Card defender : defenders) { // if both isWorthLessThanAllKillers and canKillAllDangerous are false there's nothing more to check - if ((isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2) - && CombatUtil.canBlock(attacker, defender)) { + if ((isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2) + && CombatUtil.canBlock(attacker, defender)) { numberOfPossibleBlockers += 1; if (isWorthLessThanAllKillers && CombatUtil.canDestroyAttacker(attacker, defender, combat, false) && !(attacker.hasKeyword("Undying") && attacker.getCounters(CounterType.P1P1) == 0)) { @@ -898,7 +899,7 @@ public class ComputerUtilAttack { // the creature // see if the defending creature is of higher or lower // value. We don't want to attack only to lose value - if (isWorthLessThanAllKillers && attacker.getSVar("SacMe").equals("") + if (isWorthLessThanAllKillers && attacker.getSVar("SacMe").equals("") && CardFactoryUtil.evaluateCreature(defender) <= CardFactoryUtil.evaluateCreature(attacker)) { isWorthLessThanAllKillers = false; } @@ -914,10 +915,10 @@ public class ComputerUtilAttack { canKillAllDangerous = false; } else { for (String keyword : defender.getKeyword()) { - if (keyword.equals("Wither") || keyword.equals("Infect") || keyword.equals("Lifelink") ) { + if (keyword.equals("Wither") || keyword.equals("Infect") || keyword.equals("Lifelink")) { canKillAllDangerous = false; break; - // there is a creature that can survive an attack from this creature + // there is a creature that can survive an attack from this creature // and combat will have negative effects } } @@ -935,7 +936,7 @@ public class ComputerUtilAttack { } if (numberOfPossibleBlockers > 1 - || (numberOfPossibleBlockers == 1 + || (numberOfPossibleBlockers == 1 && !attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures."))) { canBeBlocked = true; } @@ -961,7 +962,7 @@ public class ComputerUtilAttack { break; case 3: // expecting to at least kill a creature of equal value, not be // blocked - if ((canKillAll && isWorthLessThanAllKillers) + if ((canKillAll && isWorthLessThanAllKillers) || ((canKillAllDangerous || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne) || !canBeBlocked) { System.out.println(attacker.getName() diff --git a/src/main/java/forge/game/player/ComputerUtilBlock.java b/src/main/java/forge/game/player/ComputerUtilBlock.java index 05fd2135023..7e4b033ab1b 100644 --- a/src/main/java/forge/game/player/ComputerUtilBlock.java +++ b/src/main/java/forge/game/player/ComputerUtilBlock.java @@ -63,7 +63,7 @@ public class ComputerUtilBlock { // blockers /** Constant diff=0. */ private static int diff = 0; - + private static boolean lifeInDanger = false; /** @@ -279,10 +279,10 @@ public class ComputerUtilBlock { final List> attackerLists = combat.sortAttackerByDefender(); final List sortedAttackers = new ArrayList(); final List firstAttacker = attackerLists.get(0); - + final List defenders = combat.getDefenders(); - + // Begin with the attackers that pose the biggest threat CardLists.sortByEvaluateCreature(firstAttacker); CardLists.sortAttack(firstAttacker); @@ -404,7 +404,7 @@ public class ComputerUtilBlock { * a {@link forge.game.phase.Combat} object. * @return a {@link forge.game.phase.Combat} object. */ - final static Predicate rampagesOrNeedsManyToBlock = Predicates.or( CardPredicates.containsKeyword("Rampage"), CardPredicates.containsKeyword("CARDNAME can't be blocked by more than one creature.")); + static final Predicate rampagesOrNeedsManyToBlock = Predicates.or(CardPredicates.containsKeyword("Rampage"), CardPredicates.containsKeyword("CARDNAME can't be blocked by more than one creature.")); private static Combat makeGangBlocks(final Player ai, final Combat combat) { List currentAttackers = CardLists.filter(ComputerUtilBlock.getAttackersLeft(), Predicates.not(rampagesOrNeedsManyToBlock)); @@ -606,7 +606,7 @@ public class ComputerUtilBlock { List tramplingAttackers = CardLists.getKeyword(ComputerUtilBlock.getAttackers(), "Trample"); tramplingAttackers = CardLists.filter(tramplingAttackers, Predicates.not(rampagesOrNeedsManyToBlock)); - + // TODO - should check here for a "rampage-like" trigger that replaced // the keyword: // "Whenever CARDNAME becomes blocked, it gets +1/+1 until end of turn for each creature blocking it." @@ -651,9 +651,9 @@ public class ComputerUtilBlock { List safeBlockers; List blockers; - + List targetAttackers = CardLists.filter(ComputerUtilBlock.getBlockedButUnkilled(), Predicates.not(rampagesOrNeedsManyToBlock)); - + // TODO - should check here for a "rampage-like" trigger that replaced // the keyword: // "Whenever CARDNAME becomes blocked, it gets +1/+1 until end of turn for each creature blocking it." @@ -769,9 +769,9 @@ public class ComputerUtilBlock { } // keeps track of all currently unblocked attackers - ComputerUtilBlock.setAttackersLeft(new ArrayList(ComputerUtilBlock.getAttackers())); + ComputerUtilBlock.setAttackersLeft(new ArrayList(ComputerUtilBlock.getAttackers())); // keeps track of all unassigned blockers - ComputerUtilBlock.setBlockersLeft(new ArrayList(possibleBlockers)); + ComputerUtilBlock.setBlockersLeft(new ArrayList(possibleBlockers)); // keeps track of all blocked attackers that currently wouldn't be destroyed ComputerUtilBlock.setBlockedButUnkilled(new ArrayList()); List blockers; @@ -875,7 +875,7 @@ public class ComputerUtilBlock { // necessary // trade } - + if (!CombatUtil.lifeInDanger(ai, combat)) { combat = ComputerUtilBlock.makeGoodBlocks(combat); } @@ -915,29 +915,29 @@ public class ComputerUtilBlock { return combat; } - + public static List orderBlockers(Card attacker, List blockers) { // very very simple ordering of blockers, sort by evaluate, then sort by attack //final int damage = attacker.getNetCombatDamage(); CardLists.sortByEvaluateCreature(blockers); CardLists.sortAttack(blockers); - + // TODO: Take total damage, and attempt to maximize killing the greatest evaluation of creatures // It's probably generally better to kill the largest creature, but sometimes its better to kill a few smaller ones - + return blockers; } - + public static List orderAttackers(Card attacker, List blockers) { // This shouldn't really take trample into account, but otherwise should be pretty similar to orderBlockers // very very simple ordering of attackers, sort by evaluate, then sort by attack //final int damage = attacker.getNetCombatDamage(); CardLists.sortByEvaluateCreature(blockers); CardLists.sortAttack(blockers); - + // TODO: Take total damage, and attempt to maximize killing the greatest evaluation of creatures // It's probably generally better to kill the largest creature, but sometimes its better to kill a few smaller ones - + return blockers; } } diff --git a/src/main/java/forge/game/player/LobbyPlayer.java b/src/main/java/forge/game/player/LobbyPlayer.java index e790843fc08..65fe938ad43 100644 --- a/src/main/java/forge/game/player/LobbyPlayer.java +++ b/src/main/java/forge/game/player/LobbyPlayer.java @@ -7,22 +7,22 @@ package forge.game.player; * */ public class LobbyPlayer { - - final protected PlayerType type; + + protected final PlayerType type; public final PlayerType getType() { return type; } - - final protected String name; + + protected final String name; // string with picture is more important than avatar index protected String picture; private int avatarIndex = -1; - - public LobbyPlayer(PlayerType type, String name) - { - this.type = type; + + public LobbyPlayer(PlayerType type, String name) { + + this.type = type; this.name = name; } @@ -53,20 +53,26 @@ public class LobbyPlayer { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } LobbyPlayer other = (LobbyPlayer) obj; if (name == null) { - if (other.name != null) + if (other.name != null) { return false; - } else if (!name.equals(other.name)) + } + } else if (!name.equals(other.name)) { return false; - if (type != other.type) + } + if (type != other.type) { return false; + } return true; } @@ -75,6 +81,6 @@ public class LobbyPlayer { } public void setAvatarIndex(int avatarIndex) { - this.avatarIndex = avatarIndex; + this.avatarIndex = avatarIndex; } }