diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index f290ddc815c..98b1ac8c783 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -55,7 +55,8 @@ import org.apache.commons.lang3.tuple.Pair; import java.security.InvalidParameterException; import java.util.*; -/** + +/** * A prototype for player controller class * * Handles phase skips for now. @@ -68,11 +69,11 @@ public class PlayerControllerAi extends PlayerController { brains = new AiController(p, game); } - - public void allowCheatShuffle(boolean value) { + + public void allowCheatShuffle(boolean value){ brains.allowCheatShuffle(value); } - + public void setUseSimulation(boolean value) { brains.setUseSimulation(value); } @@ -80,7 +81,8 @@ public class PlayerControllerAi extends PlayerController { public SpellAbility getAbilityToPlay(Card hostCard, List abilities, ITriggerEvent triggerEvent) { if (abilities.size() == 0) { return null; - } else { + } + else { return abilities.get(0); } } @@ -101,60 +103,51 @@ public class PlayerControllerAi extends PlayerController { } @Override - public Map assignCombatDamage(Card attacker, CardCollectionView blockers, int damageDealt, - GameEntity defender, boolean overrideOrder) { + public Map assignCombatDamage(Card attacker, CardCollectionView blockers, int damageDealt, GameEntity defender, boolean overrideOrder) { return ComputerUtilCombat.distributeAIDamage(attacker, blockers, damageDealt, defender, overrideOrder); } @Override public Integer announceRequirements(SpellAbility ability, String announce, boolean allowZero) { - // For now, these "announcements" are made within the AI classes of the - // appropriate SA effects + // For now, these "announcements" are made within the AI classes of the appropriate SA effects if (ability.getApi() != null) { switch (ability.getApi()) { - case ChooseNumber: - return ability.getActivatingPlayer().isOpponentOf(player) ? 0 - : ComputerUtilMana.determineLeftoverMana(ability, player); - case BidLife: - return 0; - default: - return null; + case ChooseNumber: + return ability.getActivatingPlayer().isOpponentOf(player) ? 0 : ComputerUtilMana.determineLeftoverMana(ability, player); + case BidLife: + return 0; + default: + return null; } } return null; // return incorrect value to indicate that } @Override - public CardCollectionView choosePermanentsToSacrifice(SpellAbility sa, int min, int max, - CardCollectionView validTargets, String message) { + public CardCollectionView choosePermanentsToSacrifice(SpellAbility sa, int min, int max, CardCollectionView validTargets, String message) { return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, false, min == 0); } @Override - public CardCollectionView choosePermanentsToDestroy(SpellAbility sa, int min, int max, - CardCollectionView validTargets, String message) { + public CardCollectionView choosePermanentsToDestroy(SpellAbility sa, int min, int max, CardCollectionView validTargets, String message) { return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, true, min == 0); } @Override - public CardCollectionView chooseCardsForEffect(CardCollectionView sourceList, SpellAbility sa, String title, - int min, int max, boolean isOptional) { + public CardCollectionView chooseCardsForEffect(CardCollectionView sourceList, SpellAbility sa, String title, int min, int max, boolean isOptional) { return brains.chooseCardsForEffect(sourceList, sa, min, max, isOptional); } @Override - public T chooseSingleEntityForEffect(FCollectionView optionList, - DelayedReveal delayedReveal, SpellAbility sa, String title, boolean isOptional, Player targetedPlayer) { + public T chooseSingleEntityForEffect(FCollectionView optionList, DelayedReveal delayedReveal, SpellAbility sa, String title, boolean isOptional, Player targetedPlayer) { if (delayedReveal != null) { - reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(), - delayedReveal.getMessagePrefix()); + reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(), delayedReveal.getMessagePrefix()); } ApiType api = sa.getApi(); if (null == api) { throw new InvalidParameterException("SA is not api-based, this is not supported yet"); } - return SpellApiToAi.Converter.get(api).chooseSingleEntity(player, sa, (FCollection) optionList, isOptional, - targetedPlayer); + return SpellApiToAi.Converter.get(api).chooseSingleEntity(player, sa, (FCollection)optionList, isOptional, targetedPlayer); } @Override @@ -170,10 +163,10 @@ public class PlayerControllerAi extends PlayerController { public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) { return getAi().confirmAction(sa, mode, message); } - + @Override - public boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode mode, String string, int bid, - Player winner) { + public boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode mode, String string, + int bid, Player winner) { return getAi().confirmBidAction(sa, mode, string, bid, winner); } @@ -183,15 +176,13 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map triggerParams, - boolean isMandatory) { + public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map triggerParams, boolean isMandatory) { if (sa.getHostCard().getName().equals("Deathmist Raptor")) { return true; } if (triggerParams.containsKey("DelayedTrigger") || isMandatory) { - // TODO: The only card with an optional delayed trigger is Shirei, - // Shizo's Caretaker, - // needs to be expanded when a more difficult cards comes up + //TODO: The only card with an optional delayed trigger is Shirei, Shizo's Caretaker, + // needs to be expanded when a more difficult cards comes up return true; } // Store/replace target choices more properly to get this SA cleared. @@ -210,10 +201,8 @@ public class PlayerControllerAi extends PlayerController { subtc = sub.getTargets(); sub.resetTargets(); } - // There is no way this doTrigger here will have the same target as - // stored above - // So it's possible it's making a different decision here than will - // actually happen + // There is no way this doTrigger here will have the same target as stored above + // So it's possible it's making a different decision here than will actually happen if (!brains.doTrigger(sa, false)) { ret = false; } @@ -238,10 +227,10 @@ public class PlayerControllerAi extends PlayerController { public CardCollection orderBlockers(Card attacker, CardCollection blockers) { return AiBlockController.orderBlockers(attacker, blockers); } - + @Override public CardCollection orderBlocker(Card attacker, Card blocker, CardCollection oldBlockers) { - return AiBlockController.orderBlocker(attacker, blocker, oldBlockers); + return AiBlockController.orderBlocker(attacker, blocker, oldBlockers); }; @Override @@ -264,10 +253,11 @@ public class PlayerControllerAi extends PlayerController { CardCollection toBottom = new CardCollection(); CardCollection toTop = new CardCollection(); - for (Card c : topN) { + for (Card c: topN) { if (ComputerUtil.scryWillMoveCardToBottomOfLibrary(player, c)) { toBottom.add(c); - } else { + } + else { toTop.add(c); } } @@ -279,38 +269,37 @@ public class PlayerControllerAi extends PlayerController { @Override public boolean willPutCardOnTop(Card c) { - return true; // AI does not know what will happen next (another clash or - // that would become his topdeck) + return true; // AI does not know what will happen next (another clash or that would become his topdeck) } @Override public CardCollectionView orderMoveToZoneList(CardCollectionView cards, ZoneType destinationZone) { - // TODO Add logic for AI ordering here + //TODO Add logic for AI ordering here return cards; } @Override - public CardCollection chooseCardsToDiscardFrom(Player p, SpellAbility sa, CardCollection validCards, int min, - int max) { + public CardCollection chooseCardsToDiscardFrom(Player p, SpellAbility sa, CardCollection validCards, int min, int max) { if (p == player) { return brains.getCardsToDiscard(min, max, validCards, sa); } boolean isTargetFriendly = !p.isOpponentOf(player); - return isTargetFriendly ? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min, max) - : ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min, max); + return isTargetFriendly + ? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min, max) + : ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min, max); } @Override public void playSpellAbilityForFree(SpellAbility copySA, boolean mayChooseNewTargets) { - // Ai is known to set targets in doTrigger, so if it cannot choose new - // targets, we won't call canPlays + // Ai is known to set targets in doTrigger, so if it cannot choose new targets, we won't call canPlays if (mayChooseNewTargets) { if (copySA instanceof Spell) { Spell spell = (Spell) copySA; ((PlayerControllerAi) player.getController()).getAi().canPlayFromEffectAI(spell, true, true); - } else { + } + else { getAi().canPlaySa(copySA); } } @@ -320,9 +309,7 @@ public class PlayerControllerAi extends PlayerController { @Override public void playSpellAbilityNoStack(SpellAbility effectSA, boolean canSetupTargets) { if (canSetupTargets) - brains.doTrigger(effectSA, true); // first parameter does not - // matter, since return value - // won't be used + brains.doTrigger(effectSA, true); // first parameter does not matter, since return value won't be used ComputerUtil.playNoStack(player, effectSA, game); } @@ -338,34 +325,33 @@ public class PlayerControllerAi extends PlayerController { @Override public TargetChoices chooseNewTargetsFor(SpellAbility ability) { - // AI currently can't do this. But when it can it will need to be based - // on Ability API + // AI currently can't do this. But when it can it will need to be based on Ability API return null; } @Override - public CardCollectionView chooseCardsToDiscardUnlessType(int num, CardCollectionView hand, String uType, - SpellAbility sa) { + public CardCollectionView chooseCardsToDiscardUnlessType(int num, CardCollectionView hand, String uType, SpellAbility sa) { final CardCollectionView cardsOfType = CardLists.getType(hand, uType); if (!cardsOfType.isEmpty()) { Card toDiscard = Aggregates.itemWithMin(cardsOfType, CardPredicates.Accessors.fnGetCmc); return new CardCollection(toDiscard); } - return getAi().getCardsToDiscard(num, (String[]) null, sa); + return getAi().getCardsToDiscard(num, (String[])null, sa); } + @Override public Mana chooseManaFromPool(List manaChoices) { return manaChoices.get(0); // no brains used } @Override - public String chooseSomeType(String kindOfType, SpellAbility sa, List validTypes, List invalidTypes, - boolean isOptional) { + public String chooseSomeType(String kindOfType, SpellAbility sa, List validTypes, List invalidTypes, boolean isOptional) { String chosen = ComputerUtil.chooseSomeType(player, kindOfType, sa.getParam("AILogic"), invalidTypes); - if (StringUtils.isBlank(chosen) && !validTypes.isEmpty()) { + if (StringUtils.isBlank(chosen) && !validTypes.isEmpty()) + { chosen = validTypes.get(0); - Log.warn("AI has no idea how to choose " + kindOfType + ", defaulting to 1st element: chosen"); + Log.warn("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen"); } game.getAction().nofityOfValue(sa, null, "Computer picked: " + chosen, player); return chosen; @@ -377,13 +363,12 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, - String question) { + public boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question) { return brains.aiShouldRun(replacementEffect, effectSA); } @Override - public CardCollectionView getCardsToMulligan(Player firstPlayer) { + public CardCollectionView getCardsToMulligan(Player firstPlayer) { if (!ComputerUtil.wantMulligan(player)) { return null; } @@ -405,7 +390,7 @@ public class PlayerControllerAi extends PlayerController { public List chooseSpellAbilityToPlay() { return brains.chooseSpellAbilityToPlay(); } - + @Override public void playChosenSpellAbility(SpellAbility sa) { // System.out.println("Playing sa: " + sa); @@ -414,26 +399,22 @@ public class PlayerControllerAi extends PlayerController { } else { ComputerUtil.handlePlayingSpellAbility(player, sa, game); } - } + } @Override public CardCollection chooseCardsToDiscardToMaximumHandSize(int numDiscard) { - return brains.getCardsToDiscard(numDiscard, (String[]) null, null); + return brains.getCardsToDiscard(numDiscard, (String[])null, null); } @Override public CardCollection chooseCardsToRevealFromHand(int min, int max, CardCollectionView valid) { int numCardsToReveal = Math.min(max, valid.size()); - return numCardsToReveal == 0 ? new CardCollection() : (CardCollection) valid.subList(0, numCardsToReveal); + return numCardsToReveal == 0 ? new CardCollection() : (CardCollection)valid.subList(0, numCardsToReveal); } @Override public boolean payManaOptional(Card c, Cost cost, SpellAbility sa, String prompt, ManaPaymentPurpose purpose) { - final Ability ability = new AbilityStatic(c, cost, null) { - @Override - public void resolve() { - } - }; + final Ability ability = new AbilityStatic(c, cost, null) { @Override public void resolve() {} }; ability.setActivatingPlayer(c.getController()); if (ComputerUtilCost.canPayCost(ability, c.getController())) { @@ -445,8 +426,7 @@ public class PlayerControllerAi extends PlayerController { @Override public List chooseSaToActivateFromOpeningHand(List usableFromOpeningHand) { - // AI would play everything. But limits to one copy of (Leyline of - // Singularity) and (Gemstone Caverns) + // AI would play everything. But limits to one copy of (Leyline of Singularity) and (Gemstone Caverns) return brains.chooseSaToActivateFromOpeningHand(usableFromOpeningHand); } @@ -454,16 +434,13 @@ public class PlayerControllerAi extends PlayerController { public int chooseNumber(SpellAbility sa, String title, int min, int max) { return brains.chooseNumber(sa, title, min, max); } - + public int chooseNumber(SpellAbility sa, String title, List options, Player relatedPlayer) { return brains.chooseNumber(sa, title, options, relatedPlayer); } - /* - * (non-Javadoc) - * - * @see forge.game.player.PlayerController#chooseFlipResult(forge.Card, - * forge.game.player.Player, java.lang.String[], boolean) + /* (non-Javadoc) + * @see forge.game.player.PlayerController#chooseFlipResult(forge.Card, forge.game.player.Player, java.lang.String[], boolean) */ @Override public boolean chooseFlipResult(SpellAbility sa, Player flipper, boolean[] results, boolean call) { @@ -485,37 +462,31 @@ public class PlayerControllerAi extends PlayerController { } @Override - public Pair chooseTarget(SpellAbility saSrc, - List> allTargets) { + public Pair chooseTarget(SpellAbility saSrc, List> allTargets) { // TODO Teach AI how to use Spellskite return allTargets.get(0); } + @Override public void notifyOfValue(SpellAbility saSource, GameObject realtedTarget, String value) { - // AI should take into consideration creature types, numbers and other - // information (mostly choices) arriving through this channel + // AI should take into consideration creature types, numbers and other information (mostly choices) arriving through this channel } @Override public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, Boolean defaultVal) { - switch (kindOfChoice) { - case TapOrUntap: - return true; - case UntapOrLeaveTapped: - return defaultVal != null && defaultVal.booleanValue(); - case UntapTimeVault: - return false; // TODO Should AI skip his turn for time vault? - case LeftOrRight: - return brains.chooseDirection(sa); - default: - return MyRandom.getRandom().nextBoolean(); + switch(kindOfChoice) { + case TapOrUntap: return true; + case UntapOrLeaveTapped: return defaultVal != null && defaultVal.booleanValue(); + case UntapTimeVault: return false; // TODO Should AI skip his turn for time vault? + case LeftOrRight: return brains.chooseDirection(sa); + default: + return MyRandom.getRandom().nextBoolean(); } } @Override - public Card chooseProtectionShield(GameEntity entityBeingDamaged, List options, - Map choiceMap) { + public Card chooseProtectionShield(GameEntity entityBeingDamaged, List options, Map choiceMap) { int i = MyRandom.getRandom().nextInt(options.size()); return choiceMap.get(options.get(i)); } @@ -537,10 +508,9 @@ public class PlayerControllerAi extends PlayerController { } @Override - public Pair chooseAndRemoveOrPutCounter(Card cardWithCounter) { + public Pair chooseAndRemoveOrPutCounter(Card cardWithCounter) { if (!cardWithCounter.hasCounters()) { - System.out.println( - "chooseCounterType was reached with a card with no counters on it. Consider filtering this card out earlier"); + System.out.println("chooseCounterType was reached with a card with no counters on it. Consider filtering this card out earlier"); return null; } @@ -554,7 +524,7 @@ public class PlayerControllerAi extends PlayerController { for (final CounterType counter : cardWithCounter.getCounters().keySet()) { if ((!ComputerUtil.isNegativeCounter(counter, cardWithCounter) && allies.contains(controller)) - || (ComputerUtil.isNegativeCounter(counter, cardWithCounter) && enemies.contains(controller))) { + || (ComputerUtil.isNegativeCounter(counter, cardWithCounter) && enemies.contains(controller))) { countersToIncrease.add(counter); } else { countersToDecrease.add(counter); @@ -563,18 +533,20 @@ public class PlayerControllerAi extends PlayerController { if (!countersToIncrease.isEmpty()) { int random = MyRandom.getRandom().nextInt(countersToIncrease.size()); - return new ImmutablePair(countersToIncrease.get(random), "Put"); - } else if (!countersToDecrease.isEmpty()) { + return new ImmutablePair(countersToIncrease.get(random),"Put"); + } + else if (!countersToDecrease.isEmpty()) { int random = MyRandom.getRandom().nextInt(countersToDecrease.size()); - return new ImmutablePair(countersToDecrease.get(random), "Remove"); + return new ImmutablePair(countersToDecrease.get(random),"Remove"); } // shouldn't reach here but just in case, remove random counter List countersOnCard = new ArrayList(); int random = MyRandom.getRandom().nextInt(countersOnCard.size()); - return new ImmutablePair(countersOnCard.get(random), "Remove"); + return new ImmutablePair(countersOnCard.get(random),"Remove"); } + @Override public byte chooseColorAllowColorless(String message, Card card, ColorSet colors) { final String c = ComputerUtilCard.getMostProminentColor(player.getCardsIn(ZoneType.Hand)); @@ -582,7 +554,7 @@ public class PlayerControllerAi extends PlayerController { if ((colors.getColor() & chosenColorMask) != 0) { return chosenColorMask; } else { - return Iterables.getFirst(colors, (byte) 0); + return Iterables.getFirst(colors, (byte)0); } } @@ -598,20 +570,16 @@ public class PlayerControllerAi extends PlayerController { if ((colors.getColor() & chosenColorMask) != 0) { return chosenColorMask; - } else { + } + else { return Iterables.getFirst(colors, MagicColor.WHITE); } } @Override - public PaperCard chooseSinglePaperCard(SpellAbility sa, String message, Predicate cpp, String name) { - throw new UnsupportedOperationException("Should not be called for AI"); // or - // implement - // it - // if - // you - // know - // how + public PaperCard chooseSinglePaperCard(SpellAbility sa, String message, + Predicate cpp, String name) { + throw new UnsupportedOperationException("Should not be called for AI"); // or implement it if you know how } @Override @@ -621,8 +589,7 @@ public class PlayerControllerAi extends PlayerController { @Override public CounterType chooseCounterType(List options, SpellAbility sa, String prompt) { - // may write a smarter AI if you need to (with calls to AI-clas for - // given API ability) + // may write a smarter AI if you need to (with calls to AI-clas for given API ability) // TODO: ArsenalNut (06 Feb 12)computer needs // better logic to pick a counter type and probably @@ -633,15 +600,11 @@ public class PlayerControllerAi extends PlayerController { @Override public boolean confirmPayment(CostPart costPart, String prompt) { - return brains.confirmPayment(costPart); // AI is expected to know what - // it is paying for at the - // moment (otherwise add another - // parameter to this method) + return brains.confirmPayment(costPart); // AI is expected to know what it is paying for at the moment (otherwise add another parameter to this method) } @Override - public ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers, - Map runParams) { + public ReplacementEffect chooseSingleReplacementEffect(String prompt, List possibleReplacers, Map runParams) { // AI logic for choosing which replacement effect to apply // happens here. return possibleReplacers.get(0); @@ -650,7 +613,7 @@ public class PlayerControllerAi extends PlayerController { @Override public String chooseProtectionType(String string, SpellAbility sa, List choices) { String choice = choices.get(0); - SpellAbility hostsa = null; // for Protect sub-ability + SpellAbility hostsa = null; //for Protect sub-ability if (game.stack.size() > 1) { for (SpellAbilityStackInstance si : game.getStack()) { SpellAbility spell = si.getSpellAbility(true); @@ -690,8 +653,7 @@ public class PlayerControllerAi extends PlayerController { } } final PhaseHandler ph = game.getPhaseHandler(); - if (ph.getPlayerTurn() == sa.getActivatingPlayer() && ph.getPhase() == PhaseType.MAIN1 - && sa.getTargetCard() != null) { + if (ph.getPlayerTurn() == sa.getActivatingPlayer() && ph.getPhase() == PhaseType.MAIN1 && sa.getTargetCard() != null) { AiAttackController aiAtk = new AiAttackController(sa.getActivatingPlayer(), sa.getTargetCard()); String s = aiAtk.toProtectAttacker(sa); if (s != null) { @@ -715,22 +677,12 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, - FCollectionView allPayers) { + public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, FCollectionView allPayers) { final Card source = sa.getHostCard(); - final Ability emptyAbility = new AbilityStatic(source, cost, sa.getTargetRestrictions()) { - @Override - public void resolve() { - } - }; + final Ability emptyAbility = new AbilityStatic(source, cost, sa.getTargetRestrictions()) { @Override public void resolve() { } }; emptyAbility.setActivatingPlayer(player); - if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers) - && ComputerUtilCost.canPayCost(emptyAbility, player)) { - ComputerUtil.playNoStack(player, emptyAbility, game); // AI needs - // something - // to resolve - // to pay that - // cost + if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers) && ComputerUtilCost.canPayCost(emptyAbility, player)) { + ComputerUtil.playNoStack(player, emptyAbility, game); // AI needs something to resolve to pay that cost return true; } return false; @@ -739,12 +691,12 @@ public class PlayerControllerAi extends PlayerController { @Override public void orderAndPlaySimultaneousSa(List activePlayerSAs) { for (final SpellAbility sa : activePlayerSAs) { - prepareSingleSa(sa.getHostCard(), sa, true); + prepareSingleSa(sa.getHostCard(),sa,true); ComputerUtil.playStack(sa, player, game); } } - - private void prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory) { + + private void prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory){ if (sa.hasParam("TargetingPlayer")) { Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, sa.getParam("TargetingPlayer"), sa).get(0); sa.setTargetingPlayer(targetingPlayer); @@ -772,7 +724,7 @@ public class PlayerControllerAi extends PlayerController { } else { ComputerUtil.playStack(tgtSA, player, game); } - } else + } else return false; // didn't play spell } return true; @@ -789,19 +741,15 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean chooseCardsPile(SpellAbility sa, CardCollectionView pile1, CardCollectionView pile2, - boolean faceUp) { + public boolean chooseCardsPile(SpellAbility sa, CardCollectionView pile1, CardCollectionView pile2, boolean faceUp) { if (!faceUp) { // AI will choose the first pile if it is larger or the same - // TODO Improve this to be slightly more random to not be so - // predictable + // TODO Improve this to be slightly more random to not be so predictable return pile1.size() >= pile2.size(); } else { boolean allCreatures = Iterables.all(Iterables.concat(pile1, pile2), CardPredicates.Presets.CREATURES); - int cmc1 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile1) - : ComputerUtilCard.evaluatePermanentList(pile1); - int cmc2 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile2) - : ComputerUtilCard.evaluatePermanentList(pile2); + int cmc1 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile1) : ComputerUtilCard.evaluatePermanentList(pile1); + int cmc2 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile2) : ComputerUtilCard.evaluatePermanentList(pile2); System.out.println("value:" + cmc1 + " " + cmc2); // for now, this assumes that the outcome will be bad @@ -815,7 +763,7 @@ public class PlayerControllerAi extends PlayerController { public void revealAnte(String message, Multimap removedAnteCards) { // Ai won't understand that anyway } - + @Override public Collection complainCardsCantPlayWell(Deck myDeck) { return brains.complainCardsCantPlayWell(myDeck); @@ -826,10 +774,10 @@ public class PlayerControllerAi extends PlayerController { return brains.getBooleanProperty(AiProps.CHEAT_WITH_MANA_ON_SHUFFLE) ? brains.cheatShuffle(list) : list; } - @Override - public CardShields chooseRegenerationShield(Card c) { - return Iterables.getFirst(c.getShields(), null); - } + @Override + public CardShields chooseRegenerationShield(Card c) { + return Iterables.getFirst(c.getShields(), null); + } @Override public List chooseCardsYouWonToAddToDeck(List losses) { @@ -838,38 +786,35 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, - String prompt /* ai needs hints as well */, boolean isActivatedSa) { + public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, boolean isActivatedSa) { // TODO Auto-generated method stub - ManaCostBeingPaid cost = isActivatedSa ? ComputerUtilMana.calculateManaCost(sa, false, 0) - : new ManaCostBeingPaid(toPay); + ManaCostBeingPaid cost = isActivatedSa ? ComputerUtilMana.calculateManaCost(sa, false, 0) : new ManaCostBeingPaid(toPay); return ComputerUtilMana.payManaCost(cost, sa, player); } @Override - public Map chooseCardsForConvoke(SpellAbility sa, ManaCost manaCost, - CardCollectionView untappedCreats0) { + public Map chooseCardsForConvoke(SpellAbility sa, ManaCost manaCost, CardCollectionView untappedCreats0) { final Player ai = sa.getActivatingPlayer(); final PhaseHandler ph = ai.getGame().getPhaseHandler(); - // Filter out mana sources that will interfere with payManaCost() + //Filter out mana sources that will interfere with payManaCost() CardCollection untappedCreats = CardLists.filter(untappedCreats0, new Predicate() { @Override public boolean apply(final Card c) { return c.getManaAbilities().isEmpty(); } }); - - // Only convoke after attackers have been declared + + //Only convoke after attackers have been declared if (ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) { return new HashMap(); } - - // Do not convoke potential blockers until after opponent's attack + + //Do not convoke potential blockers until after opponent's attack final CardCollectionView blockers = ComputerUtilCard.getLikelyBlockers(ai, null); - if ((ph.isPlayerTurn(ai) && ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN)) - || (!ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS))) { - untappedCreats.removeAll((List) blockers); - // Add threatened creatures + if ((ph.isPlayerTurn(ai) && ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN)) || + (!ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS))) { + untappedCreats.removeAll((List)blockers); + //Add threatened creatures if (!ai.getGame().getStack().isEmpty()) { final List objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), null); for (Card c : blockers) { @@ -891,16 +836,14 @@ public class PlayerControllerAi extends PlayerController { } else if (logic.equals("MostProminentInHumanDeck")) { return ComputerUtilCard.getMostProminentCardName(player.getOpponent().getCardsIn(ZoneType.Library)); } else if (logic.equals("MostProminentCreatureInComputerDeck")) { - CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library), "Creature", - player, sa.getHostCard()); + CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library), "Creature", player, sa.getHostCard()); return ComputerUtilCard.getMostProminentCardName(cards); } else if (logic.equals("BestCreatureInComputerDeck")) { return ComputerUtilCard.getBestCreatureAI(player.getCardsIn(ZoneType.Library)).getName(); } else if (logic.equals("RandomInComputerDeck")) { return Aggregates.random(player.getCardsIn(ZoneType.Library)).getName(); } else if (logic.equals("MostProminentSpellInComputerDeck")) { - CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library), - "Card.Instant,Card.Sorcery", player, sa.getHostCard()); + CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library), "Card.Instant,Card.Sorcery", player, sa.getHostCard()); return ComputerUtilCard.getMostProminentCardName(cards); } } else { @@ -914,21 +857,19 @@ public class PlayerControllerAi extends PlayerController { } @Override - public Card chooseSingleCardForZoneChange(ZoneType destination, List origin, SpellAbility sa, - CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, boolean isOptional, - Player decider) { + public Card chooseSingleCardForZoneChange(ZoneType destination, + List origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal, + String selectPrompt, boolean isOptional, Player decider) { if (delayedReveal != null) { - reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(), - delayedReveal.getMessagePrefix()); + reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(), delayedReveal.getMessagePrefix()); } return ChangeZoneAi.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player, decider); } @Override public void resetAtEndOfTurn() { - // TODO - if card memory is ever used to remember something for longer - // than a turn, make sure it's not reset here. + // TODO - if card memory is ever used to remember something for longer than a turn, make sure it's not reset here. getAi().getCardMemory().clearAllRemembered(); } @@ -941,7 +882,6 @@ public class PlayerControllerAi extends PlayerController { public void awaitNextInput() { // Do nothing } - @Override public void cancelAwaitNextInput() { // Do nothing