+ *
* @author Forge
* @version $Id$
*/
public class ComputerUtil {
- //if return true, go to next phase
+ // if return true, go to next phase
/**
- *
playCards.
- *
+ *
+ * playCards.
+ *
+ *
* @return a boolean.
*/
- static public boolean playCards() {
+ public static boolean playCards() {
return playCards(getSpellAbility());
}
- //if return true, go to next phase
+ // if return true, go to next phase
/**
- *
playCards.
- *
- * @param all an array of {@link forge.card.spellability.SpellAbility} objects.
+ *
+ * playCards.
+ *
+ *
+ * @param all
+ * an array of {@link forge.card.spellability.SpellAbility}
+ * objects.
* @return a boolean.
*/
- static public boolean playCards(SpellAbility[] all) {
- //not sure "playing biggest spell" matters?
+ public static boolean playCards(final SpellAbility[] all) {
+ // not sure "playing biggest spell" matters?
sortSpellAbilityByCost(all);
- // MyRandom.shuffle(all);
+ // MyRandom.shuffle(all);
for (SpellAbility sa : all) {
// Don't add Counterspells to the "normal" playcard lookupss
AbilityFactory af = sa.getAbilityFactory();
- if (af != null && af.getAPI().equals("Counter"))
+ if (af != null && af.getAPI().equals("Counter")) {
continue;
+ }
sa.setActivatingPlayer(AllZone.getComputerPlayer());
- if (canBePlayedAndPayedByAI(sa)) //checks everything necessary
+ if (canBePlayedAndPayedByAI(sa)) // checks everything necessary
{
handlePlayingSpellAbility(sa);
@@ -63,33 +73,40 @@ public class ComputerUtil {
}
}
return true;
- }//playCards()
+ }// playCards()
/**
- *
playCards.
- *
- * @param all a {@link java.util.ArrayList} object.
+ *
+ * playCards.
+ *
+ *
+ * @param all
+ * a {@link java.util.ArrayList} object.
* @return a boolean.
*/
- static public boolean playCards(ArrayList all) {
+ public static boolean playCards(final ArrayList all) {
SpellAbility[] sas = new SpellAbility[all.size()];
for (int i = 0; i < sas.length; i++) {
sas[i] = all.get(i);
}
return playCards(sas);
- }//playCards()
+ } // playCards()
/**
- *
handlePlayingSpellAbility.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * handlePlayingSpellAbility.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
*/
- static public void handlePlayingSpellAbility(SpellAbility sa) {
+ public static void handlePlayingSpellAbility(final SpellAbility sa) {
AllZone.getStack().freezeStack();
Card source = sa.getSourceCard();
- if (sa.isSpell() && !source.isCopiedSpell())
+ if (sa.isSpell() && !source.isCopiedSpell()) {
AllZone.getGameAction().moveToStack(source);
+ }
Cost cost = sa.getPayCosts();
Target tgt = sa.getTarget();
@@ -100,22 +117,27 @@ public class ComputerUtil {
sa.getBeforePayManaAI().execute();
AllZone.getStack().addAndUnfreeze(sa);
} else {
- if (tgt != null && tgt.doesTarget())
+ if (tgt != null && tgt.doesTarget()) {
sa.chooseTargetAI();
+ }
Cost_Payment pay = new Cost_Payment(cost, sa);
- if (pay.payComputerCosts())
+ if (pay.payComputerCosts()) {
AllZone.getStack().addAndUnfreeze(sa);
+ }
}
}
/**
- *
counterSpellRestriction.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * counterSpellRestriction.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
* @return a int.
*/
- static public int counterSpellRestriction(SpellAbility sa) {
+ public static int counterSpellRestriction(final SpellAbility sa) {
// Move this to AF?
// Restriction Level is Based off a handful of factors
@@ -129,7 +151,7 @@ public class ComputerUtil {
// Play higher costing spells first?
Cost cost = sa.getPayCosts();
// Convert cost to CMC
- //String totalMana = source.getSVar("PayX"); // + cost.getCMC()
+ // String totalMana = source.getSVar("PayX"); // + cost.getCMC()
// Consider the costs here for relative "scoring"
if (CostUtil.hasDiscardHandCost(cost)) {
@@ -138,8 +160,9 @@ public class ComputerUtil {
}
// Abilities before Spells (card advantage)
- if (af.isAbility())
+ if (af.isAbility()) {
restrict += 40;
+ }
// TargetValidTargeting gets biggest bonus
if (tgt.getSAValidTargeting() != null) {
@@ -154,38 +177,44 @@ public class ComputerUtil {
int usableManaSources = CardFactoryUtil.getUsableManaSources(AllZone.getHumanPlayer());
// If the Unless isn't enough, this should be less likely to be used
- if (amount > usableManaSources)
+ if (amount > usableManaSources) {
restrict += 20 - (2 * amount);
- else
+ } else {
restrict -= (10 - (2 * amount));
+ }
}
// Then base on Targeting Restriction
String[] validTgts = tgt.getValidTgts();
- if (validTgts.length != 1 || !validTgts[0].equals("Card"))
+ if (validTgts.length != 1 || !validTgts[0].equals("Card")) {
restrict += 10;
+ }
- // And lastly give some bonus points to least restrictive TargetType (Spell,Ability,Triggered)
+ // And lastly give some bonus points to least restrictive TargetType
+ // (Spell,Ability,Triggered)
String tgtType = tgt.getTargetSpellAbilityType();
restrict -= (5 * tgtType.split(",").length);
return restrict;
}
- //if return true, go to next phase
+ // if return true, go to next phase
/**
- *
+ *
+ * @param possibleCounters
+ * a {@link java.util.ArrayList} object.
* @return a boolean.
*/
- static public boolean playCounterSpell(ArrayList possibleCounters) {
+ public static boolean playCounterSpell(final ArrayList possibleCounters) {
SpellAbility bestSA = null;
int bestRestriction = Integer.MIN_VALUE;
for (SpellAbility sa : possibleCounters) {
sa.setActivatingPlayer(AllZone.getComputerPlayer());
- if (canBePlayedAndPayedByAI(sa)) { //checks everything nescessary
+ if (canBePlayedAndPayedByAI(sa)) { // checks everything nescessary
if (bestSA == null) {
bestSA = sa;
bestRestriction = counterSpellRestriction(sa);
@@ -201,8 +230,9 @@ public class ComputerUtil {
}
}
- if (bestSA == null)
+ if (bestSA == null) {
return false;
+ }
// TODO
// "Look" at Targeted SA and "calculate" the threshold
@@ -211,8 +241,9 @@ public class ComputerUtil {
AllZone.getStack().freezeStack();
Card source = bestSA.getSourceCard();
- if (bestSA.isSpell() && !source.isCopiedSpell())
+ if (bestSA.isSpell() && !source.isCopiedSpell()) {
AllZone.getGameAction().moveToStack(source);
+ }
Cost cost = bestSA.getPayCosts();
@@ -224,25 +255,29 @@ public class ComputerUtil {
AllZone.getStack().addAndUnfreeze(bestSA);
} else {
Cost_Payment pay = new Cost_Payment(cost, bestSA);
- if (pay.payComputerCosts())
+ if (pay.payComputerCosts()) {
AllZone.getStack().addAndUnfreeze(bestSA);
+ }
}
return true;
- }//playCounterSpell()
+ }// playCounterSpell()
-
- //this is used for AI's counterspells
+ // this is used for AI's counterspells
/**
- *
playStack.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * playStack.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
*/
- final static public void playStack(SpellAbility sa) {
+ public static final void playStack(final SpellAbility sa) {
if (canPayCost(sa)) {
Card source = sa.getSourceCard();
- if (sa.isSpell() && !source.isCopiedSpell())
+ if (sa.isSpell() && !source.isCopiedSpell()) {
AllZone.getGameAction().moveToStack(source);
+ }
sa.setActivatingPlayer(AllZone.getComputerPlayer());
@@ -253,60 +288,69 @@ public class ComputerUtil {
}
/**
- *
playStackFree.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * playStackFree.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
*/
- final static public void playStackFree(SpellAbility sa) {
+ public static final void playStackFree(final SpellAbility sa) {
sa.setActivatingPlayer(AllZone.getComputerPlayer());
Card source = sa.getSourceCard();
- if (sa.isSpell() && !source.isCopiedSpell())
+ if (sa.isSpell() && !source.isCopiedSpell()) {
AllZone.getGameAction().moveToStack(source);
+ }
AllZone.getStack().add(sa);
}
/**
- *
playNoStack.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * playNoStack.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
*/
- final static public void playNoStack(SpellAbility sa) {
+ public static final void playNoStack(final SpellAbility sa) {
// TODO: We should really restrict what doesn't use the Stack
if (canPayCost(sa)) {
Card source = sa.getSourceCard();
- if (sa.isSpell() && !source.isCopiedSpell())
+ if (sa.isSpell() && !source.isCopiedSpell()) {
AllZone.getGameAction().moveToStack(source);
+ }
sa.setActivatingPlayer(AllZone.getComputerPlayer());
-
+
Cost cost = sa.getPayCosts();
- if (cost == null)
+ if (cost == null) {
payManaCost(sa);
- else {
- Cost_Payment pay = new Cost_Payment(cost, sa);
- pay.payComputerCosts();
+ } else {
+ Cost_Payment pay = new Cost_Payment(cost, sa);
+ pay.payComputerCosts();
}
AbilityFactory.resolve(sa, false);
- //destroys creatures if they have lethal damage, etc..
+ // destroys creatures if they have lethal damage, etc..
AllZone.getGameAction().checkStateEffects();
}
- }//play()
+ }// play()
-
- //gets Spells of cards in hand and Abilities of cards in play
- //checks to see
- //1. if canPlay() returns true, 2. can pay for mana
+ // gets Spells of cards in hand and Abilities of cards in play
+ // checks to see
+ // 1. if canPlay() returns true, 2. can pay for mana
/**
- *
getSpellAbility.
- *
+ *
+ * getSpellAbility.
+ *
+ *
* @return an array of {@link forge.card.spellability.SpellAbility} objects.
*/
- static public SpellAbility[] getSpellAbility() {
+ public static SpellAbility[] getSpellAbility() {
CardList all = new CardList();
all.addAll(AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield));
all.addAll(AllZone.getComputerPlayer().getCardsIn(Zone.Hand));
@@ -315,7 +359,7 @@ public class ComputerUtil {
CardList humanPlayable = new CardList();
humanPlayable.addAll(AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield));
humanPlayable = humanPlayable.filter(new CardListFilter() {
- public boolean addCard(Card c) {
+ public boolean addCard(final Card c) {
return (c.canAnyPlayerActivate());
}
});
@@ -326,7 +370,10 @@ public class ComputerUtil {
for (int outer = 0; outer < all.size(); outer++) {
SpellAbility[] sa = all.get(outer).getSpellAbility();
for (int i = 0; i < sa.length; i++)
- spellAbility.add(sa[i]);//this seems like it needs to be copied, not sure though
+ {
+ spellAbility.add(sa[i]);// this seems like it needs to be
+ // copied, not sure though
+ }
}
SpellAbility[] sa = new SpellAbility[spellAbility.size()];
@@ -334,121 +381,154 @@ public class ComputerUtil {
return sa;
}
- //This is for playing spells regularly (no Cascade/Ripple etc.)
+ // This is for playing spells regularly (no Cascade/Ripple etc.)
/**
- *
canBePlayedAndPayedByAI.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * canBePlayedAndPayedByAI.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
* @since 1.0.15
*/
- static public boolean canBePlayedAndPayedByAI(SpellAbility sa) {
+ public static boolean canBePlayedAndPayedByAI(final SpellAbility sa) {
return sa.canPlay() && sa.canPlayAI() && canPayCost(sa);
}
/**
- *
canPayCost.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * canPayCost.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
- static public boolean canPayCost(SpellAbility sa) {
+ public static boolean canPayCost(final SpellAbility sa) {
return canPayCost(sa, AllZone.getComputerPlayer());
- }//canPayCost()
-
+ }// canPayCost()
/**
- *
canPayCost.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
- * @param player a {@link forge.Player} object.
+ *
+ * canPayCost.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
+ * @param player
+ * a {@link forge.Player} object.
* @return a boolean.
*/
- static public boolean canPayCost(SpellAbility sa, Player player) {
- if (!payManaCost(sa, player, true, 0))
+ public static boolean canPayCost(final SpellAbility sa, final Player player) {
+ if (!payManaCost(sa, player, true, 0)) {
return false;
+ }
return canPayAdditionalCosts(sa, player);
- }//canPayCost()
-
+ }// canPayCost()
/**
- *
determineLeftoverMana.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * determineLeftoverMana.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
* @return a int.
*/
- static public int determineLeftoverMana(SpellAbility sa) {
+ public static int determineLeftoverMana(final SpellAbility sa) {
return determineLeftoverMana(sa, AllZone.getComputerPlayer());
}
/**
- *
determineLeftoverMana.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
- * @param player a {@link forge.Player} object.
+ *
+ * determineLeftoverMana.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
+ * @param player
+ * a {@link forge.Player} object.
* @return a int.
* @since 1.0.15
*/
- static public int determineLeftoverMana(SpellAbility sa, Player player) {
+ public static int determineLeftoverMana(final SpellAbility sa, final Player player) {
int xMana = 0;
for (int i = 1; i < 99; i++) {
- if (!payManaCost(sa, player, true, xMana))
+ if (!payManaCost(sa, player, true, xMana)) {
break;
+ }
xMana = i;
}
return xMana;
}
-
/**
- *
canPayAdditionalCosts.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * canPayAdditionalCosts.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
- static public boolean canPayAdditionalCosts(SpellAbility sa) {
+ public static boolean canPayAdditionalCosts(final SpellAbility sa) {
return canPayAdditionalCosts(sa, AllZone.getComputerPlayer());
}
/**
- *
canPayAdditionalCosts.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
- * @param player a {@link forge.Player} object.
+ *
+ * canPayAdditionalCosts.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
+ * @param player
+ * a {@link forge.Player} object.
* @return a boolean.
*/
- static public boolean canPayAdditionalCosts(SpellAbility sa, Player player) {
- if (sa.getActivatingPlayer() == null){
- System.out.println(sa.getSourceCard() + " in ComputerUtil.canPayAdditionalCosts() without an activating player");
+ public static boolean canPayAdditionalCosts(final SpellAbility sa, final Player player) {
+ if (sa.getActivatingPlayer() == null) {
+ System.out.println(sa.getSourceCard()
+ + " in ComputerUtil.canPayAdditionalCosts() without an activating player");
sa.setActivatingPlayer(player);
}
return Cost_Payment.canPayAdditionalCosts(sa.getPayCosts(), sa);
}
/**
- *
payManaCost.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * payManaCost.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
*/
- static public void payManaCost(SpellAbility sa) {
+ public static void payManaCost(final SpellAbility sa) {
payManaCost(sa, AllZone.getComputerPlayer(), false, 0);
}
/**
- *
payManaCost.
- *
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
- * @param player a {@link forge.Player} object.
- * @param test (is for canPayCost, if true does not change the game state)
- * @param extraMana a int.
+ *
+ * payManaCost.
+ *
+ *
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
+ * @param player
+ * a {@link forge.Player} object.
+ * @param test
+ * (is for canPayCost, if true does not change the game state)
+ * @param extraMana
+ * a int.
* @return a boolean.
* @since 1.0.15
*/
- static public boolean payManaCost(SpellAbility sa, Player player, boolean test, int extraMana) {
+ public static boolean payManaCost(final SpellAbility sa, final Player player, final boolean test, final int extraMana) {
String mana = sa.getPayCosts() != null ? sa.getPayCosts().getTotalMana() : sa.getManaCost();
ManaCost cost = new ManaCost(mana);
@@ -462,108 +542,140 @@ public class ComputerUtil {
if (sa.getPayCosts() != null && cost.getXcounter() > 0) {
int manaToAdd = 0;
- if (test && extraMana > 0)
+ if (test && extraMana > 0) {
manaToAdd = extraMana * cost.getXcounter();
- else {
+ } else {
// For Count$xPaid set PayX in the AFs then use that here
// Else calculate it as appropriate.
String xSvar = card.getSVar("X").equals("Count$xPaid") ? "PayX" : "X";
if (!card.getSVar(xSvar).equals("")) {
- if (xSvar.equals("PayX"))
- manaToAdd = Integer.parseInt(card.getSVar(xSvar)) * cost.getXcounter(); // X has already been decided
- else {
+ if (xSvar.equals("PayX")) {
+ manaToAdd = Integer.parseInt(card.getSVar(xSvar)) * cost.getXcounter(); // X
+ } else {
manaToAdd = AbilityFactory.calculateAmount(card, xSvar, sa) * cost.getXcounter();
}
}
}
cost.increaseColorlessMana(manaToAdd);
- if (!test)
+ if (!test) {
card.setXManaCostPaid(manaToAdd);
+ }
}
- if (cost.isPaid())
+ if (cost.isPaid()) {
return true;
+ }
ArrayList colors;
cost = ((ManaPool) manapool).subtractMana(sa, cost);
- if(card.getSVar("ManaNeededToAvoidNegativeEffect") != "") {
+ if (card.getSVar("ManaNeededToAvoidNegativeEffect") != "") {
cost.setManaNeededToAvoidNegativeEffect(card.getSVar("ManaNeededToAvoidNegativeEffect").split(","));
}
CardList manaSources = getAvailableMana();
- //this is to prevent errors for mana sources that have abilities that cost mana.
+ // this is to prevent errors for mana sources that have abilities that
+ // cost mana.
manaSources.remove(sa.getSourceCard());
for (int i = 0; i < manaSources.size(); i++) {
Card sourceCard = manaSources.get(i);
ArrayList manaAbilities = sourceCard.getAIPlayableMana();
- boolean used = false; //this is for testing paying mana only
+ boolean used = false; // this is for testing paying mana only
manaAbilities = sortForNeeded(cost, manaAbilities, player);
for (Ability_Mana m : manaAbilities) {
- if (used) break; //mana source already used in the test
+ if (used)
+ {
+ break; // mana source already used in the test
+ }
m.setActivatingPlayer(player);
- //if the AI can't pay the additional costs skip the mana ability
+ // if the AI can't pay the additional costs skip the mana
+ // ability
if (m.getPayCosts() != null) {
- if (!canPayAdditionalCosts(m, player))
+ if (!canPayAdditionalCosts(m, player)) {
continue;
- } else if (sourceCard.isTapped())
+ }
+ } else if (sourceCard.isTapped()) {
continue;
+ }
- //don't use abilities with dangerous drawbacks
- if (m.getSubAbility() != null)
- if (!m.getSubAbility().chkAI_Drawback())
+ // don't use abilities with dangerous drawbacks
+ if (m.getSubAbility() != null) {
+ if (!m.getSubAbility().chkAI_Drawback()) {
continue;
+ }
+ }
colors = getProduceableColors(m, player);
for (int j = 0; j < colors.size(); j++) {
- if (used) break; //mana source already used in the test
+ if (used)
+ {
+ break; // mana source already used in the test
+ }
if (cost.isNeeded(colors.get(j))) {
if (!test) {
- //Pay additional costs
+ // Pay additional costs
if (m.getPayCosts() != null) {
Cost_Payment pay = new Cost_Payment(m.getPayCosts(), m);
- if (!pay.payComputerCosts()) continue;
- } else
+ if (!pay.payComputerCosts()) {
+ continue;
+ }
+ } else {
sourceCard.tap();
- } else used = true; // mana source is now used in the test
+ }
+ }
+ else {
+ used = true; // mana source is now used in the test
+ }
cost.payMana(colors.get(j));
if (!test) {
- //resolve subabilities
+ // resolve subabilities
AbilityFactory af = m.getAbilityFactory();
- if (af != null)
+ if (af != null) {
AbilityFactory.resolveSubAbilities(m);
+ }
if (sourceCard.getName().equals("Undiscovered Paradise")) {
sourceCard.setBounceAtUntap(true);
}
if (sourceCard.getName().equals("Rainbow Vale")) {
- sourceCard.addExtrinsicKeyword("An opponent gains control of CARDNAME at the beginning of the next end step.");
+ sourceCard
+ .addExtrinsicKeyword("An opponent gains control of CARDNAME at the beginning of the next end step.");
}
- //System.out.println("just subtracted " + colors.get(j) + ", cost is now: " + cost.toString());
- //Run triggers
+ // System.out.println("just subtracted " +
+ // colors.get(j) + ", cost is now: " +
+ // cost.toString());
+ // Run triggers
HashMap runParams = new HashMap();
runParams.put("Card", sourceCard);
runParams.put("Player", player);
- runParams.put("Produced", colors.get(j)); //can't tell what mana the computer just paid?
+ runParams.put("Produced", colors.get(j)); // can't
+ // tell
+ // what
+ // mana
+ // the
+ // computer
+ // just
+ // paid?
AllZone.getTriggerHandler().runTrigger("TapsForMana", runParams);
- }//not a test
+ }// not a test
}
if (cost.isPaid()) {
- //if (sa instanceof Spell_Permanent) // should probably add this
- sa.getSourceCard().setColorsPaid(cost.getColorsPaid());
+ // if (sa instanceof Spell_Permanent) // should probably
+ // add this
+ sa.getSourceCard().setColorsPaid(cost.getColorsPaid());
sa.getSourceCard().setSunburstValue(cost.getSunburst());
manapool.clearPay(sa, test);
return true;
@@ -573,81 +685,105 @@ public class ComputerUtil {
}
- if (!test) // real payment should not arrive here
- throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for " + sa.getSourceCard().getName());
+ if (!test) {
+ throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for "
+ + sa.getSourceCard().getName());
+ }
return false;
- }//payManaCost()
-
+ }// payManaCost()
/**
- *
getProduceableColors.
- *
- * @param m a {@link forge.card.spellability.Ability_Mana} object.
- * @param player a {@link forge.Player} object.
+ *
+ * getProduceableColors.
+ *
+ *
+ * @param m
+ * a {@link forge.card.spellability.Ability_Mana} object.
+ * @param player
+ * a {@link forge.Player} object.
* @return a {@link java.util.ArrayList} object.
* @since 1.0.15
*/
- public static ArrayList getProduceableColors(Ability_Mana m, Player player) {
+ public static ArrayList getProduceableColors(final Ability_Mana m, final Player player) {
ArrayList colors = new ArrayList();
- //if the mana ability is not avaiable move to the next one
+ // if the mana ability is not avaiable move to the next one
m.setActivatingPlayer(player);
- if (!m.canPlay()) return colors;
+ if (!m.canPlay()) {
+ return colors;
+ }
- if (!colors.contains(Constant.Color.Black) && m.isBasic() && m.mana().equals("B"))
+ if (!colors.contains(Constant.Color.Black) && m.isBasic() && m.mana().equals("B")) {
colors.add(Constant.Color.Black);
- if (!colors.contains(Constant.Color.White) && m.isBasic() && m.mana().equals("W"))
+ }
+ if (!colors.contains(Constant.Color.White) && m.isBasic() && m.mana().equals("W")) {
colors.add(Constant.Color.White);
- if (!colors.contains(Constant.Color.Green) && m.isBasic() && m.mana().equals("G"))
+ }
+ if (!colors.contains(Constant.Color.Green) && m.isBasic() && m.mana().equals("G")) {
colors.add(Constant.Color.Green);
- if (!colors.contains(Constant.Color.Red) && m.isBasic() && m.mana().equals("R"))
+ }
+ if (!colors.contains(Constant.Color.Red) && m.isBasic() && m.mana().equals("R")) {
colors.add(Constant.Color.Red);
- if (!colors.contains(Constant.Color.Blue) && m.isBasic() && m.mana().equals("U"))
+ }
+ if (!colors.contains(Constant.Color.Blue) && m.isBasic() && m.mana().equals("U")) {
colors.add(Constant.Color.Blue);
- if (!colors.contains(Constant.Color.Colorless) && m.isBasic() && m.mana().equals("1"))
+ }
+ if (!colors.contains(Constant.Color.Colorless) && m.isBasic() && m.mana().equals("1")) {
colors.add(Constant.Color.Colorless);
+ }
return colors;
}
/**
- *
getAvailableMana.
- *
+ *
+ * getAvailableMana.
+ *
+ *
* @return a {@link forge.CardList} object.
*/
- static public CardList getAvailableMana() {
+ public static CardList getAvailableMana() {
return getAvailableMana(AllZone.getComputerPlayer());
- }//getAvailableMana()
+ }// getAvailableMana()
- //gets available mana sources and sorts them
+ // gets available mana sources and sorts them
/**
- *
getAvailableMana.
- *
- * @param player a {@link forge.Player} object.
+ *
+ * getAvailableMana.
+ *
+ *
+ * @param player
+ * a {@link forge.Player} object.
* @return a {@link forge.CardList} object.
*/
- static public CardList getAvailableMana(final Player player) {
+ public static CardList getAvailableMana(final Player player) {
CardList list = player.getCardsIn(Zone.Battlefield);
CardList manaSources = list.filter(new CardListFilter() {
- public boolean addCard(Card c) {
+ public boolean addCard(final Card c) {
for (Ability_Mana am : c.getAIPlayableMana()) {
am.setActivatingPlayer(player);
- if (am.canPlay()) return true;
+ if (am.canPlay()) {
+ return true;
+ }
}
return false;
}
- });//CardListFilter
+ });// CardListFilter
CardList sortedManaSources = new CardList();
-
- // 1. Use lands that can only produce colorless mana without drawback/cost first
+
+ // 1. Use lands that can only produce colorless mana without
+ // drawback/cost first
for (int i = 0; i < manaSources.size(); i++) {
Card card = manaSources.get(i);
- if (card.isCreature() || card.isEnchanted()) continue; //don't use creatures before other permanents
+ if (card.isCreature() || card.isEnchanted())
+ {
+ continue; // don't use creatures before other permanents
+ }
int usableManaAbilities = 0;
boolean needsLimitedResources = false;
@@ -658,33 +794,42 @@ public class ComputerUtil {
Cost cost = m.getPayCosts();
needsLimitedResources |= !cost.isReusuableResource();
- //if the AI can't pay the additional costs skip the mana ability
+ // if the AI can't pay the additional costs skip the mana
+ // ability
m.setActivatingPlayer(AllZone.getComputerPlayer());
if (cost != null) {
- if (!canPayAdditionalCosts(m, player))
+ if (!canPayAdditionalCosts(m, player)) {
continue;
+ }
}
- //don't use abilities with dangerous drawbacks
+ // don't use abilities with dangerous drawbacks
if (m.getSubAbility() != null) {
- if (!m.getSubAbility().chkAI_Drawback())
+ if (!m.getSubAbility().chkAI_Drawback()) {
continue;
- needsLimitedResources = true; //TODO: check for good drawbacks (gainLife)
+ }
+ needsLimitedResources = true; // TODO: check for good
+ // drawbacks (gainLife)
}
usableManaAbilities++;
}
-
- //use lands that can only produce colorless mana first
- if (usableManaAbilities == 1 && !needsLimitedResources && manaAbilities.get(0).mana().equals("1"))
- sortedManaSources.add(card);
+
+ // use lands that can only produce colorless mana first
+ if (usableManaAbilities == 1 && !needsLimitedResources && manaAbilities.get(0).mana().equals("1")) {
+ sortedManaSources.add(card);
+ }
}
- // 2. Search for mana sources that have a certain number of mana abilities (start with 1 and go up to 5) and no drawback/costs
- for (int number = 1; number < 6; number++)
+ // 2. Search for mana sources that have a certain number of mana
+ // abilities (start with 1 and go up to 5) and no drawback/costs
+ for (int number = 1; number < 6; number++) {
for (int i = 0; i < manaSources.size(); i++) {
Card card = manaSources.get(i);
- if (card.isCreature() || card.isEnchanted()) continue; //don't use creatures before other permanents
+ if (card.isCreature() || card.isEnchanted())
+ {
+ continue; // don't use creatures before other permanents
+ }
int usableManaAbilities = 0;
boolean needsLimitedResources = false;
@@ -694,48 +839,61 @@ public class ComputerUtil {
Cost cost = m.getPayCosts();
needsLimitedResources |= !cost.isReusuableResource();
- //if the AI can't pay the additional costs skip the mana ability
+ // if the AI can't pay the additional costs skip the mana
+ // ability
if (cost != null) {
- if (!canPayAdditionalCosts(m, player))
+ if (!canPayAdditionalCosts(m, player)) {
continue;
+ }
}
- //don't use abilities with dangerous drawbacks
+ // don't use abilities with dangerous drawbacks
if (m.getSubAbility() != null) {
- if (!m.getSubAbility().chkAI_Drawback())
+ if (!m.getSubAbility().chkAI_Drawback()) {
continue;
- needsLimitedResources = true; //TODO: check for good drawbacks (gainLife)
+ }
+ needsLimitedResources = true; // TODO: check for good
+ // drawbacks (gainLife)
}
usableManaAbilities++;
}
- if (usableManaAbilities == number && !needsLimitedResources && !sortedManaSources.contains(card))
+ if (usableManaAbilities == number && !needsLimitedResources && !sortedManaSources.contains(card)) {
sortedManaSources.add(card);
+ }
}
+ }
- //Add the rest
+ // Add the rest
for (int j = 0; j < manaSources.size(); j++) {
- if (!sortedManaSources.contains(manaSources.get(j)))
+ if (!sortedManaSources.contains(manaSources.get(j))) {
sortedManaSources.add(manaSources.get(j));
+ }
}
return sortedManaSources;
- }//getAvailableMana()
+ }// getAvailableMana()
// sorts the most needed mana abilities to come first
/**
- *
sortForNeeded.
- *
- * @param cost a {@link forge.card.mana.ManaCost} object.
- * @param manaAbilities a {@link java.util.ArrayList} object.
- * @param player a {@link forge.Player} object.
+ *
+ * sortForNeeded.
+ *
+ *
+ * @param cost
+ * a {@link forge.card.mana.ManaCost} object.
+ * @param manaAbilities
+ * a {@link java.util.ArrayList} object.
+ * @param player
+ * a {@link forge.Player} object.
* @return a {@link java.util.ArrayList} object.
* @since 1.0.15
*/
- static public ArrayList sortForNeeded(ManaCost cost, ArrayList manaAbilities, Player player) {
+ public static ArrayList sortForNeeded(final ManaCost cost, final ArrayList manaAbilities,
+ final Player player) {
ArrayList colors;
-
+
ArrayList colorsNeededToAvoidNegativeEffect = cost.getManaNeededToAvoidNegativeEffect();
ArrayList res = new ArrayList();
@@ -751,8 +909,8 @@ public class ComputerUtil {
res.add(am);
break;
}
- for(String col : colorsNeededToAvoidNegativeEffect) {
- if(col.equalsIgnoreCase(colors.get(j))
+ for (String col : colorsNeededToAvoidNegativeEffect) {
+ if (col.equalsIgnoreCase(colors.get(j))
|| CardUtil.getShortColor(col).equalsIgnoreCase(colors.get(j))) {
res.add(am);
}
@@ -762,7 +920,9 @@ public class ComputerUtil {
for (Ability_Mana am : manaAbilities) {
- if (res.contains(am)) break;
+ if (res.contains(am)) {
+ break;
+ }
colors = getProduceableColors(am, player);
for (int j = 0; j < colors.size(); j++) {
@@ -770,8 +930,8 @@ public class ComputerUtil {
res.add(am);
break;
}
- for(String col : colorsNeededToAvoidNegativeEffect) {
- if(col.equalsIgnoreCase(colors.get(j))
+ for (String col : colorsNeededToAvoidNegativeEffect) {
+ if (col.equalsIgnoreCase(colors.get(j))
|| CardUtil.getShortColor(col).equalsIgnoreCase(colors.get(j))) {
res.add(am);
}
@@ -782,55 +942,59 @@ public class ComputerUtil {
return res;
}
-
- //plays a land if one is available
+ // plays a land if one is available
/**
- *
chooseLandsToPlay.
- *
+ *
+ * chooseLandsToPlay.
+ *
+ *
* @return a boolean.
*/
- static public boolean chooseLandsToPlay() {
+ public static boolean chooseLandsToPlay() {
Player computer = AllZone.getComputerPlayer();
CardList landList = computer.getCardsIn(Zone.Hand);
landList = landList.filter(CardListFilter.lands);
-
CardList lands = computer.getCardsIn(Zone.Graveyard).getType("Land");
- for (Card crd : lands){
- if (crd.isLand() && crd.hasStartOfKeyword("May be played"))
- landList.add(crd);
+ for (Card crd : lands) {
+ if (crd.isLand() && crd.hasStartOfKeyword("May be played")) {
+ landList.add(crd);
+ }
}
landList = landList.filter(new CardListFilter() {
- public boolean addCard(Card c) {
+ public boolean addCard(final Card c) {
if (c.getSVar("NeedsToPlay").length() > 0) {
String needsToPlay = c.getSVar("NeedsToPlay");
CardList list = AllZoneUtil.getCardsIn(Zone.Battlefield);
list = list.getValidCards(needsToPlay.split(","), c.getController(), c);
- if (list.isEmpty()) return false;
- }
- if (c.isType("Legendary")
- && !c.getName().equals("Flagstones of Trokair")) {
- CardList list = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield);
- if (list.containsName(c.getName()))
+ if (list.isEmpty()) {
return false;
+ }
}
-
- //don't play the land if it has cycling and enough lands are available
+ if (c.isType("Legendary") && !c.getName().equals("Flagstones of Trokair")) {
+ CardList list = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield);
+ if (list.containsName(c.getName())) {
+ return false;
+ }
+ }
+
+ // don't play the land if it has cycling and enough lands are
+ // available
ArrayList spellAbilities = c.getSpellAbilities();
- for (SpellAbility sa : spellAbilities)
- if (sa.isCycling()) {
- CardList hand = AllZone.getComputerPlayer().getCardsIn(Zone.Hand);
+ for (SpellAbility sa : spellAbilities)
+ if (sa.isCycling()) {
+ CardList hand = AllZone.getComputerPlayer().getCardsIn(Zone.Hand);
CardList lands = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield);
lands.addAll(hand);
lands = lands.getType("Land");
- if (lands.size() >= Math.max(hand.getHighestConvertedManaCost(), 6))
+ if (lands.size() >= Math.max(hand.getHighestConvertedManaCost(), 6)) {
return false;
- }
-
-
+ }
+ }
+
return true;
}
});
@@ -839,30 +1003,37 @@ public class ComputerUtil {
// play as many lands as you can
int ix = 0;
while (landList.get(ix).isReflectedLand() && (ix + 1 < landList.size())) {
- // Skip through reflected lands. Choose last if they are all reflected.
+ // Skip through reflected lands. Choose last if they are all
+ // reflected.
ix++;
}
Card land = landList.get(ix);
landList.remove(ix);
computer.playLand(land);
-
- if (AllZone.getStack().size() != 0)
- return true;
+
+ if (AllZone.getStack().size() != 0) {
+ return true;
+ }
}
return false;
}
/**
- *
getCardPreference.
- *
- * @param activate a {@link forge.Card} object.
- * @param pref a {@link java.lang.String} object.
- * @param typeList a {@link forge.CardList} object.
+ *
+ * getCardPreference.
+ *
+ *
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param pref
+ * a {@link java.lang.String} object.
+ * @param typeList
+ * a {@link forge.CardList} object.
* @return a {@link forge.Card} object.
*/
- static public Card getCardPreference(Card activate, String pref, CardList typeList) {
-
+ public static Card getCardPreference(final Card activate, final String pref, final CardList typeList) {
+
if (activate != null) {
String[] prefValid = activate.getSVar("AIPreference").split("\\$");
if (prefValid[0].equals(pref)) {
@@ -874,10 +1045,11 @@ public class ComputerUtil {
}
}
if (pref.contains("SacCost")) { // search for permanents with SacMe
- for (int ip = 0; ip < 9; ip++) { // priority 0 is the lowest, priority 5 the highest
+ for (int ip = 0; ip < 9; ip++) { // priority 0 is the lowest,
+ // priority 5 the highest
final int priority = 9 - ip;
CardList SacMeList = typeList.filter(new CardListFilter() {
- public boolean addCard(Card c) {
+ public boolean addCard(final Card c) {
return (!c.getSVar("SacMe").equals("") && Integer.parseInt(c.getSVar("SacMe")) == priority);
}
});
@@ -887,12 +1059,14 @@ public class ComputerUtil {
}
}
}
-
- if (pref.contains("DiscardCost")) { // search for permanents with DiscardMe
- for (int ip = 0; ip < 9; ip++) { // priority 0 is the lowest, priority 5 the highest
+
+ if (pref.contains("DiscardCost")) { // search for permanents with
+ // DiscardMe
+ for (int ip = 0; ip < 9; ip++) { // priority 0 is the lowest,
+ // priority 5 the highest
final int priority = 9 - ip;
CardList SacMeList = typeList.filter(new CardListFilter() {
- public boolean addCard(Card c) {
+ public boolean addCard(final Card c) {
return (!c.getSVar("DiscardMe").equals("") && Integer.parseInt(c.getSVar("DiscardMe")) == priority);
}
});
@@ -902,27 +1076,36 @@ public class ComputerUtil {
}
}
}
-
+
return null;
}
/**
- *
chooseSacrificeType.
- *
- * @param type a {@link java.lang.String} object.
- * @param activate a {@link forge.Card} object.
- * @param target a {@link forge.Card} object.
- * @param amount a int.
+ *
+ * chooseSacrificeType.
+ *
+ *
+ * @param type
+ * a {@link java.lang.String} object.
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param target
+ * a {@link forge.Card} object.
+ * @param amount
+ * a int.
* @return a {@link forge.CardList} object.
*/
- static public CardList chooseSacrificeType(String type, Card activate, Card target, int amount) {
+ public static CardList chooseSacrificeType(final String type, final Card activate, final Card target, final int amount) {
CardList typeList = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield);
typeList = typeList.getValidCards(type.split(","), activate.getController(), activate);
if (target != null && target.getController().isComputer() && typeList.contains(target))
- typeList.remove(target); // don't sacrifice the card we're pumping
+ {
+ typeList.remove(target); // don't sacrifice the card we're pumping
+ }
- if (typeList.size() < amount)
+ if (typeList.size() < amount) {
return null;
+ }
CardList sacList = new CardList();
int count = 0;
@@ -933,30 +1116,37 @@ public class ComputerUtil {
sacList.add(prefCard);
typeList.remove(prefCard);
count++;
- } else
+ } else {
break;
+ }
}
CardListUtil.sortAttackLowFirst(typeList);
- for (int i = count; i < amount; i++) sacList.add(typeList.get(i));
+ for (int i = count; i < amount; i++) {
+ sacList.add(typeList.get(i));
+ }
return sacList;
}
-
-
/**
- *
AI_discardNumType.
- *
- * @param numDiscard a int.
- * @param uTypes an array of {@link java.lang.String} objects. May be null for no restrictions.
- * @param sa a {@link forge.card.spellability.SpellAbility} object.
+ *
+ * AI_discardNumType.
+ *
+ *
+ * @param numDiscard
+ * a int.
+ * @param uTypes
+ * an array of {@link java.lang.String} objects. May be null for
+ * no restrictions.
+ * @param sa
+ * a {@link forge.card.spellability.SpellAbility} object.
* @return a CardList of discarded cards.
*/
- static public CardList AI_discardNumType(int numDiscard, String[] uTypes, SpellAbility sa) {
+ public static CardList AI_discardNumType(final int numDiscard, final String[] uTypes, final SpellAbility sa) {
CardList hand = AllZone.getComputerPlayer().getCardsIn(Zone.Hand);
Card sourceCard = null;
-
+
if (uTypes != null && sa != null) {
hand = hand.getValidCards(uTypes, sa.getActivatingPlayer(), sa.getSourceCard());
}
@@ -964,13 +1154,13 @@ public class ComputerUtil {
sourceCard = sa.getSourceCard();
}
- if (hand.size() < numDiscard){
+ if (hand.size() < numDiscard) {
return null;
}
-
+
CardList discardList = new CardList();
int count = 0;
-
+
// look for good discards
while (count < numDiscard) {
Card prefCard = getCardPreference(sourceCard, "DiscardCost", hand);
@@ -978,13 +1168,14 @@ public class ComputerUtil {
discardList.add(prefCard);
hand.remove(prefCard);
count++;
- } else
+ } else {
break;
+ }
}
-
+
int discardsLeft = numDiscard - count;
-
- // chose rest
+
+ // chose rest
for (int i = 0; i < discardsLeft; i++) {
if (hand.size() <= 0) {
continue;
@@ -992,154 +1183,211 @@ public class ComputerUtil {
CardList landsInPlay = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield).getType("Land");
if (landsInPlay.size() > 5) {
CardList landsInHand = hand.getType("Land");
- if (landsInHand.size() > 0) { //discard lands
+ if (landsInHand.size() > 0) { // discard lands
discardList.add(landsInHand.get(0));
hand.remove(landsInHand.get(0));
- } else { //discard low costed stuff
- CardListUtil.sortCMC(hand);
+ } else { // discard low costed stuff
+ CardListUtil.sortCMC(hand);
hand.reverse();
discardList.add(hand.get(0));
hand.remove(hand.get(0));
}
- } else { //discard high costed stuff
+ } else { // discard high costed stuff
CardListUtil.sortCMC(hand);
discardList.add(hand.get(0));
hand.remove(hand.get(0));
}
}
-
+
return discardList;
}
/**
- *
chooseExileType.
- *
- * @param type a {@link java.lang.String} object.
- * @param activate a {@link forge.Card} object.
- * @param target a {@link forge.Card} object.
- * @param amount a int.
+ *
+ * chooseExileType.
+ *
+ *
+ * @param type
+ * a {@link java.lang.String} object.
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param target
+ * a {@link forge.Card} object.
+ * @param amount
+ * a int.
* @return a {@link forge.CardList} object.
*/
- static public CardList chooseExileType(String type, Card activate, Card target, int amount) {
+ public static CardList chooseExileType(final String type, final Card activate, final Card target, final int amount) {
return chooseExileFrom(Constant.Zone.Battlefield, type, activate, target, amount);
}
/**
- *
chooseExileFromHandType.
- *
- * @param type a {@link java.lang.String} object.
- * @param activate a {@link forge.Card} object.
- * @param target a {@link forge.Card} object.
- * @param amount a int.
+ *
+ * chooseExileFromHandType.
+ *
+ *
+ * @param type
+ * a {@link java.lang.String} object.
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param target
+ * a {@link forge.Card} object.
+ * @param amount
+ * a int.
* @return a {@link forge.CardList} object.
*/
- static public CardList chooseExileFromHandType(String type, Card activate, Card target, int amount) {
+ public static CardList chooseExileFromHandType(final String type, final Card activate, final Card target, final int amount) {
return chooseExileFrom(Constant.Zone.Hand, type, activate, target, amount);
}
/**
- *
chooseExileFromGraveType.
- *
- * @param type a {@link java.lang.String} object.
- * @param activate a {@link forge.Card} object.
- * @param target a {@link forge.Card} object.
- * @param amount a int.
+ *
+ * chooseExileFromGraveType.
+ *
+ *
+ * @param type
+ * a {@link java.lang.String} object.
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param target
+ * a {@link forge.Card} object.
+ * @param amount
+ * a int.
* @return a {@link forge.CardList} object.
*/
- static public CardList chooseExileFromGraveType(String type, Card activate, Card target, int amount) {
+ public static CardList chooseExileFromGraveType(final String type, final Card activate, final Card target, final int amount) {
return chooseExileFrom(Constant.Zone.Graveyard, type, activate, target, amount);
}
/**
- *
chooseExileFrom.
- *
- * @param zone a {@link java.lang.String} object.
- * @param type a {@link java.lang.String} object.
- * @param activate a {@link forge.Card} object.
- * @param target a {@link forge.Card} object.
- * @param amount a int.
+ *
+ * chooseExileFrom.
+ *
+ *
+ * @param zone
+ * a {@link java.lang.String} object.
+ * @param type
+ * a {@link java.lang.String} object.
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param target
+ * a {@link forge.Card} object.
+ * @param amount
+ * a int.
* @return a {@link forge.CardList} object.
*/
- static public CardList chooseExileFrom(Constant.Zone zone, String type, Card activate, Card target, int amount) {
+ public static CardList chooseExileFrom(final Constant.Zone zone, final String type, final Card activate, final Card target, final int amount) {
CardList typeList = AllZone.getComputerPlayer().getCardsIn(zone);
typeList = typeList.getValidCards(type.split(","), activate.getController(), activate);
if (target != null && target.getController().isComputer() && typeList.contains(target))
- typeList.remove(target); // don't exile the card we're pumping
+ {
+ typeList.remove(target); // don't exile the card we're pumping
+ }
- if (typeList.size() < amount)
+ if (typeList.size() < amount) {
return null;
+ }
CardListUtil.sortAttackLowFirst(typeList);
CardList exileList = new CardList();
- for (int i = 0; i < amount; i++) exileList.add(typeList.get(i));
+ for (int i = 0; i < amount; i++) {
+ exileList.add(typeList.get(i));
+ }
return exileList;
}
/**
- *
chooseTapType.
- *
- * @param type a {@link java.lang.String} object.
- * @param activate a {@link forge.Card} object.
- * @param tap a boolean.
- * @param amount a int.
+ *
+ * chooseTapType.
+ *
+ *
+ * @param type
+ * a {@link java.lang.String} object.
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param tap
+ * a boolean.
+ * @param amount
+ * a int.
* @return a {@link forge.CardList} object.
*/
- static public CardList chooseTapType(String type, Card activate, boolean tap, int amount) {
+ public static CardList chooseTapType(final String type, final Card activate, final boolean tap, final int amount) {
CardList typeList = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield);
typeList = typeList.getValidCards(type.split(","), activate.getController(), activate);
- //is this needed?
+ // is this needed?
typeList = typeList.filter(CardListFilter.untapped);
- if (tap)
+ if (tap) {
typeList.remove(activate);
+ }
- if (typeList.size() < amount)
+ if (typeList.size() < amount) {
return null;
+ }
CardListUtil.sortAttackLowFirst(typeList);
CardList tapList = new CardList();
- for (int i = 0; i < amount; i++) tapList.add(typeList.get(i));
+ for (int i = 0; i < amount; i++) {
+ tapList.add(typeList.get(i));
+ }
return tapList;
}
/**
- *
chooseReturnType.
- *
- * @param type a {@link java.lang.String} object.
- * @param activate a {@link forge.Card} object.
- * @param target a {@link forge.Card} object.
- * @param amount a int.
+ *
+ * chooseReturnType.
+ *
+ *
+ * @param type
+ * a {@link java.lang.String} object.
+ * @param activate
+ * a {@link forge.Card} object.
+ * @param target
+ * a {@link forge.Card} object.
+ * @param amount
+ * a int.
* @return a {@link forge.CardList} object.
*/
- static public CardList chooseReturnType(String type, Card activate, Card target, int amount) {
+ public static CardList chooseReturnType(final String type, final Card activate, final Card target, final int amount) {
CardList typeList = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield);
typeList = typeList.getValidCards(type.split(","), activate.getController(), activate);
- if (target != null && target.getController().isComputer() && typeList.contains(target)) // don't bounce the card we're pumping
+ if (target != null && target.getController().isComputer() && typeList.contains(target)) {
+ // bounce
+ // the
+ // card
+ // we're
+ // pumping
typeList.remove(target);
+ }
- if (typeList.size() < amount)
+ if (typeList.size() < amount) {
return null;
+ }
CardListUtil.sortAttackLowFirst(typeList);
CardList returnList = new CardList();
- for (int i = 0; i < amount; i++) returnList.add(typeList.get(i));
+ for (int i = 0; i < amount; i++) {
+ returnList.add(typeList.get(i));
+ }
return returnList;
}
/**
- *
getPossibleAttackers.
- *
+ *
+ * getPossibleAttackers.
+ *
+ *
* @return a {@link forge.CardList} object.
*/
- static public CardList getPossibleAttackers() {
+ public static CardList getPossibleAttackers() {
CardList list = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield);
list = list.filter(new CardListFilter() {
- public boolean addCard(Card c) {
+ public boolean addCard(final Card c) {
return CombatUtil.canAttack(c);
}
});
@@ -1147,11 +1395,13 @@ public class ComputerUtil {
}
/**
- *
getAttackers.
- *
+ *
+ * getAttackers.
+ *
+ *
* @return a {@link forge.Combat} object.
*/
- static public Combat getAttackers() {
+ public static Combat getAttackers() {
ComputerUtil_Attack2 att = new ComputerUtil_Attack2(AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield),
AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield), AllZone.getHumanPlayer().getLife());
@@ -1159,64 +1409,77 @@ public class ComputerUtil {
}
/**
- *
- *
- * @param sa an array of {@link forge.card.spellability.SpellAbility} objects.
+ *
+ * sortSpellAbilityByCost.
+ *
+ *
+ * @param sa
+ * an array of {@link forge.card.spellability.SpellAbility}
+ * objects.
*/
- static void sortSpellAbilityByCost(SpellAbility sa[]) {
- //sort from highest cost to lowest
- //we want the highest costs first
+ static void sortSpellAbilityByCost(final SpellAbility[] sa) {
+ // sort from highest cost to lowest
+ // we want the highest costs first
Comparator c = new Comparator() {
- public int compare(SpellAbility a, SpellAbility b) {
+ public int compare(final SpellAbility a, final SpellAbility b) {
int a1 = CardUtil.getConvertedManaCost(a);
int b1 = CardUtil.getConvertedManaCost(b);
- //puts creatures in front of spells
- if (a.getSourceCard().isCreature())
+ // puts creatures in front of spells
+ if (a.getSourceCard().isCreature()) {
a1 += 1;
+ }
- if (b.getSourceCard().isCreature())
+ if (b.getSourceCard().isCreature()) {
b1 += 1;
+ }
- //sort planeswalker abilities for ultimate
- if(a.getRestrictions().getPlaneswalker() && b.getRestrictions().getPlaneswalker()) {
- if(a.getAbilityFactory() != null && a.getAbilityFactory().getMapParams().containsKey("Ultimate")) {
+ // sort planeswalker abilities for ultimate
+ if (a.getRestrictions().getPlaneswalker() && b.getRestrictions().getPlaneswalker()) {
+ if (a.getAbilityFactory() != null && a.getAbilityFactory().getMapParams().containsKey("Ultimate")) {
a1 += 1;
- }
- else if(b.getAbilityFactory() != null && b.getAbilityFactory().getMapParams().containsKey("Ultimate")) {
+ } else if (b.getAbilityFactory() != null
+ && b.getAbilityFactory().getMapParams().containsKey("Ultimate")) {
b1 += 1;
}
}
return b1 - a1;
}
- };//Comparator
+ };// Comparator
Arrays.sort(sa, c);
- }//sortSpellAbilityByCost()
+ }// sortSpellAbilityByCost()
/**
- *
sacrificePermanents.
- *
- * @param amount a int.
- * @param list a {@link forge.CardList} object.
+ *
+ * sacrificePermanents.
+ *
+ *
+ * @param amount
+ * a int.
+ * @param list
+ * a {@link forge.CardList} object.
*/
- static public CardList sacrificePermanents(int amount, CardList list) {
+ public static CardList sacrificePermanents(final int amount, final CardList list) {
CardList sacList = new CardList();
// used in Annihilator and AF_Sacrifice
int max = list.size();
- if (max > amount)
+ if (max > amount) {
max = amount;
+ }
CardListUtil.sortCMC(list);
list.reverse();
@@ -1254,42 +1517,53 @@ public class ComputerUtil {
}
/**
- *
+ *
+ * @param card
+ * a {@link forge.Card} object.
* @return a int.
*/
- public static int possibleDamagePrevention(Card card) {
+ public static int possibleDamagePrevention(final Card card) {
int prevented = 0;
@@ -1312,19 +1589,25 @@ public class ComputerUtil {
for (Card c : l)
for (SpellAbility sa : c.getSpellAbility())
// if SA is from AF_Counter don't add to getPlayable
- //This try/catch should fix the "computer is thinking" bug
+ // This try/catch should fix the "computer is thinking" bug
try {
if (sa.getAbilityFactory() != null && sa.isAbility()) {
AbilityFactory af = sa.getAbilityFactory();
HashMap mapParams = af.getMapParams();
- if (mapParams.get("AB").equals("PreventDamage") && sa.canPlay() && ComputerUtil.canPayCost(sa, controller)) {
- if (AbilityFactory.getDefinedCards(sa.getSourceCard(), mapParams.get("Defined"), sa).contains(card))
- prevented += AbilityFactory.calculateAmount(af.getHostCard(), mapParams.get("Amount"), sa);
+ if (mapParams.get("AB").equals("PreventDamage") && sa.canPlay()
+ && ComputerUtil.canPayCost(sa, controller)) {
+ if (AbilityFactory.getDefinedCards(sa.getSourceCard(), mapParams.get("Defined"), sa)
+ .contains(card)) {
+ prevented += AbilityFactory.calculateAmount(af.getHostCard(), mapParams.get("Amount"),
+ sa);
+ }
Target tgt = sa.getTarget();
if (tgt != null) {
- if (AllZoneUtil.getCardsIn(Zone.Battlefield).getValidCards(tgt.getValidTgts(), controller, af.getHostCard())
- .contains(card))
- prevented += AbilityFactory.calculateAmount(af.getHostCard(), mapParams.get("Amount"), sa);
+ if (AllZoneUtil.getCardsIn(Zone.Battlefield)
+ .getValidCards(tgt.getValidTgts(), controller, af.getHostCard()).contains(card)) {
+ prevented += AbilityFactory.calculateAmount(af.getHostCard(),
+ mapParams.get("Amount"), sa);
+ }
}
}
diff --git a/src/main/java/forge/ComputerUtil_Attack2.java b/src/main/java/forge/ComputerUtil_Attack2.java
index 0da0e98272d..12a2516b596 100644
--- a/src/main/java/forge/ComputerUtil_Attack2.java
+++ b/src/main/java/forge/ComputerUtil_Attack2.java
@@ -1,23 +1,25 @@
package forge;
-import forge.Constant.Zone;
-import forge.card.cardFactory.CardFactoryUtil;
-import forge.card.trigger.Trigger;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
+import forge.Constant.Zone;
+import forge.card.cardFactory.CardFactoryUtil;
+import forge.card.trigger.Trigger;
+
//doesHumanAttackAndWin() uses the global variable AllZone.getComputerPlayer()
/**
- *
ComputerUtil_Attack2 class.
- *
+ *
+ * ComputerUtil_Attack2 class.
+ *
+ *
* @author Forge
* @version $Id$
*/
public class ComputerUtil_Attack2 {
- //possible attackers and blockers
+ // possible attackers and blockers
private CardList attackers;
private CardList blockers;
private CardList playerCreatures;
@@ -26,30 +28,42 @@ public class ComputerUtil_Attack2 {
private Random random = MyRandom.random;
private final int randomInt = random.nextInt();
- private CardList humanList; //holds human player creatures
- private CardList computerList; //holds computer creatures
+ private CardList humanList; // holds human player creatures
+ private CardList computerList; // holds computer creatures
- private int aiAggression = 0; // added by Masher, how aggressive the ai attack will be depending on circumstances
+ private int aiAggression = 0; // added by Masher, how aggressive the ai
+ // attack will be depending on circumstances
/**
- *
Constructor for ComputerUtil_Attack2.
- *
- * @param possibleAttackers an array of {@link forge.Card} objects.
- * @param possibleBlockers an array of {@link forge.Card} objects.
- * @param blockerLife a int.
+ *
+ * Constructor for ComputerUtil_Attack2.
+ *
+ *
+ * @param possibleAttackers
+ * an array of {@link forge.Card} objects.
+ * @param possibleBlockers
+ * an array of {@link forge.Card} objects.
+ * @param blockerLife
+ * a int.
*/
- public ComputerUtil_Attack2(Card[] possibleAttackers, Card[] possibleBlockers, int blockerLife) {
+ public ComputerUtil_Attack2(final Card[] possibleAttackers, final Card[] possibleBlockers, final int blockerLife) {
this(new CardList(possibleAttackers), new CardList(possibleBlockers), blockerLife);
}
/**
- *
Constructor for ComputerUtil_Attack2.
- *
- * @param possibleAttackers a {@link forge.CardList} object.
- * @param possibleBlockers a {@link forge.CardList} object.
- * @param blockerLife a int.
+ *
+ * Constructor for ComputerUtil_Attack2.
+ *
+ *
+ * @param possibleAttackers
+ * a {@link forge.CardList} object.
+ * @param possibleBlockers
+ * a {@link forge.CardList} object.
+ * @param blockerLife
+ * a int.
*/
- public ComputerUtil_Attack2(final CardList possibleAttackers, CardList possibleBlockers, int blockerLife) {
+ public ComputerUtil_Attack2(final CardList possibleAttackers,
+ final CardList possibleBlockers, final int blockerLife) {
humanList = new CardList(possibleBlockers.toArray());
humanList = humanList.getType("Creature");
@@ -61,18 +75,21 @@ public class ComputerUtil_Attack2 {
attackers = getPossibleAttackers(possibleAttackers);
blockers = getPossibleBlockers(possibleBlockers, attackers);
this.blockerLife = blockerLife;
- } //constructor
+ } // constructor
/**
- *
sortAttackers.
- *
- * @param in a {@link forge.CardList} object.
+ *
+ * sortAttackers.
+ *
+ *
+ * @param in
+ * a {@link forge.CardList} object.
* @return a {@link forge.CardList} object.
*/
public final CardList sortAttackers(final CardList in) {
CardList list = new CardList();
- //Cards with triggers should come first (for Battle Cry)
+ // Cards with triggers should come first (for Battle Cry)
for (Card attacker : in) {
ArrayList registeredTriggers = attacker.getTriggers();
for (Trigger trigger : registeredTriggers) {
@@ -90,19 +107,23 @@ public class ComputerUtil_Attack2 {
}
return list;
- } //sortAttackers()
+ } // sortAttackers()
- //Is there any reward for attacking? (for 0/1 creatures there is not)
+ // Is there any reward for attacking? (for 0/1 creatures there is not)
/**
- *
isEffectiveAttacker.
- *
- * @param attacker a {@link forge.Card} object.
- * @param combat a {@link forge.Combat} object.
+ *
+ * isEffectiveAttacker.
+ *
+ *
+ * @param attacker
+ * a {@link forge.Card} object.
+ * @param combat
+ * a {@link forge.Combat} object.
* @return a boolean.
*/
- public final boolean isEffectiveAttacker(final Card attacker, Combat combat) {
+ public final boolean isEffectiveAttacker(final Card attacker, final Combat combat) {
- //if the attacker will die when attacking don't attack
+ // if the attacker will die when attacking don't attack
if (attacker.getNetDefense() + CombatUtil.predictToughnessBonusOfAttacker(attacker, null, combat) <= 0) {
return false;
}
@@ -113,10 +134,10 @@ public class ComputerUtil_Attack2 {
if (CombatUtil.poisonIfUnblocked(attacker, AllZone.getHumanPlayer(), combat) > 0) {
return true;
}
-
+
CardList controlledByCompy = AllZone.getComputerPlayer().getAllCards();
- for(Card c : controlledByCompy) {
+ for (Card c : controlledByCompy) {
for (Trigger trigger : c.getTriggers()) {
if (CombatUtil.combatTriggerWillTrigger(attacker, null, trigger, combat)) {
return true;
@@ -128,12 +149,15 @@ public class ComputerUtil_Attack2 {
}
/**
- *
getPossibleAttackers.
- *
- * @param in a {@link forge.CardList} object.
+ *
+ * getPossibleAttackers.
+ *
+ *
+ * @param in
+ * a {@link forge.CardList} object.
* @return a {@link forge.CardList} object.
*/
- public CardList getPossibleAttackers(CardList in) {
+ public final CardList getPossibleAttackers(final CardList in) {
CardList list = new CardList(in.toArray());
list = list.filter(new CardListFilter() {
public boolean addCard(final Card c) {
@@ -141,16 +165,20 @@ public class ComputerUtil_Attack2 {
}
});
return list;
- } //getPossibleAttackers()
+ } // getPossibleAttackers()
/**
- *
getPossibleBlockers.
- *
- * @param blockers a {@link forge.CardList} object.
- * @param attackers a {@link forge.CardList} object.
+ *
+ * getPossibleBlockers.
+ *
+ *
+ * @param blockers
+ * a {@link forge.CardList} object.
+ * @param attackers
+ * a {@link forge.CardList} object.
* @return a {@link forge.CardList} object.
*/
- public final CardList getPossibleBlockers(CardList blockers, CardList attackers) {
+ public final CardList getPossibleBlockers(final CardList blockers, CardList attackers) {
CardList possibleBlockers = new CardList(blockers.toArray());
final CardList attackerList = new CardList(attackers.toArray());
possibleBlockers = possibleBlockers.filter(new CardListFilter() {
@@ -167,24 +195,28 @@ public class ComputerUtil_Attack2 {
}
});
return possibleBlockers;
- }//getPossibleBlockers()
+ } // getPossibleBlockers()
- //this checks to make sure that the computer player
- //doesn't lose when the human player attacks
- //this method is used by getAttackers()
+ // this checks to make sure that the computer player
+ // doesn't lose when the human player attacks
+ // this method is used by getAttackers()
/**
- *
notNeededAsBlockers.
- *
- * @param attackers a {@link forge.CardList} object.
- * @param combat a {@link forge.Combat} object.
+ *
+ * notNeededAsBlockers.
+ *
+ *
+ * @param attackers
+ * a {@link forge.CardList} object.
+ * @param combat
+ * a {@link forge.Combat} object.
* @return a {@link forge.CardList} object.
*/
- public final CardList notNeededAsBlockers(CardList attackers, Combat combat) {
+ public final CardList notNeededAsBlockers(final CardList attackers, Combat combat) {
CardList notNeededAsBlockers = new CardList(attackers.toArray());
CardListUtil.sortAttackLowFirst(attackers);
int blockersNeeded = attackers.size();
- //don't hold back creatures that can't block any of the human creatures
+ // don't hold back creatures that can't block any of the human creatures
CardList list = getPossibleBlockers(attackers, humanList);
for (int i = 0; i < list.size(); i++) {
@@ -201,9 +233,11 @@ public class ComputerUtil_Attack2 {
return notNeededAsBlockers;
}
- // Increase the total number of blockers needed by 1 if Finest Hour in play
+ // 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)
- // In addition, if the computer guesses it needs no blockers, make sure that
+ // In addition, if the computer guesses it needs no blockers, make sure
+ // that
// it won't be surprised by Exalted
int humanExaltedBonus = countExaltedBonus(AllZone.getHumanPlayer());
@@ -212,134 +246,153 @@ public class ComputerUtil_Attack2 {
if ((blockersNeeded == 0 || nFinestHours > 0) && humanList.size() > 0) {
//
- // total attack = biggest creature + exalted, *2 if Rafiq is in play
+ // total attack = biggest creature + exalted, *2 if Rafiq is in
+ // play
int humanBaseAttack = getAttack(humanList.get(0)) + humanExaltedBonus;
if (nFinestHours > 0) {
- // For Finest Hour, one creature could attack and get the bonus TWICE
+ // For Finest Hour, one creature could attack and get the
+ // bonus TWICE
humanBaseAttack = humanBaseAttack + humanExaltedBonus;
}
- int totalExaltedAttack = AllZoneUtil.isCardInPlay("Rafiq of the Many", AllZone.getHumanPlayer()) ?
- 2 * humanBaseAttack : humanBaseAttack;
+ int totalExaltedAttack = AllZoneUtil.isCardInPlay("Rafiq of the Many",
+ AllZone.getHumanPlayer()) ? 2 * humanBaseAttack : humanBaseAttack;
if ((AllZone.getComputerPlayer().getLife() - 3) <= totalExaltedAttack) {
- // We will lose if there is an Exalted attack -- keep one blocker
- if (blockersNeeded == 0 && notNeededAsBlockers.size() > 0)
+ // We will lose if there is an Exalted attack -- keep one
+ // blocker
+ if (blockersNeeded == 0 && notNeededAsBlockers.size() > 0) {
notNeededAsBlockers.remove(0);
+ }
- // Finest Hour allows a second Exalted attack: keep a blocker for that too
- if (nFinestHours > 0 && notNeededAsBlockers.size() > 0)
+ // Finest Hour allows a second Exalted attack: keep a
+ // blocker for that too
+ if (nFinestHours > 0 && notNeededAsBlockers.size() > 0) {
notNeededAsBlockers.remove(0);
+ }
}
}
}
- //re-add creatures with vigilance
+ // re-add creatures with vigilance
for (Card c : attackers) {
- if (c.hasKeyword("Vigilance"))
+ if (c.hasKeyword("Vigilance")) {
notNeededAsBlockers.add(c);
+ }
}
return notNeededAsBlockers;
}
- //this uses a global variable, which isn't perfect
+ // this uses a global variable, which isn't perfect
/**
- *
doesHumanAttackAndWin.
- *
- * @param nBlockingCreatures a int.
+ *
+ * doesHumanAttackAndWin.
+ *
+ *
+ * @param nBlockingCreatures
+ * a int.
* @return a boolean.
*/
- public boolean doesHumanAttackAndWin(int nBlockingCreatures) {
+ public final boolean doesHumanAttackAndWin(final int nBlockingCreatures) {
int totalAttack = 0;
int stop = humanList.size() - nBlockingCreatures;
- for (int i = 0; i < stop; i++)
+ for (int i = 0; i < stop; i++) {
totalAttack += getAttack(humanList.get(i));
+ }
- //originally -3 so the computer will try to stay at 3 life
- //0 now to prevent the AI from not attacking when it's got low life
- //(seems to happen too often)
+ // originally -3 so the computer will try to stay at 3 life
+ // 0 now to prevent the AI from not attacking when it's got low life
+ // (seems to happen too often)
return AllZone.getComputerPlayer().getLife() <= totalAttack;
}
/**
- *
doAssault.
- *
+ *
+ * doAssault.
+ *
+ *
* @return a boolean.
*/
private boolean doAssault() {
- //Beastmaster Ascension
+ // Beastmaster Ascension
if (AllZoneUtil.isCardInPlay("Beastmaster Ascension", AllZone.getComputerPlayer()) && attackers.size() > 1) {
- CardList beastions = AllZone.getComputerPlayer().getCardsIn(Constant.Zone.Battlefield).
- getName("Beastmaster Ascension");
+ CardList beastions = AllZone.getComputerPlayer().getCardsIn(Constant.Zone.Battlefield)
+ .getName("Beastmaster Ascension");
int minCreatures = 7;
for (Card beastion : beastions) {
int counters = beastion.getCounters(Counters.QUEST);
minCreatures = Math.min(minCreatures, 7 - counters);
}
- if (attackers.size() >= minCreatures)
+ if (attackers.size() >= minCreatures) {
return true;
+ }
}
- //I think this is right but the assault code may still be a little off
+ // I think this is right but the assault code may still be a little off
CardListUtil.sortAttackLowFirst(attackers);
int totalAttack = 0;
- //presumes the Human will block
- for (int i = 0; i < (attackers.size() - blockers.size()); i++)
+ // presumes the Human will block
+ for (int i = 0; i < (attackers.size() - blockers.size()); i++) {
totalAttack += getAttack(attackers.get(i));
+ }
return blockerLife <= totalAttack;
- }//doAssault()
+ } // doAssault()
/**
- *
chooseDefender.
- *
- * @param c a {@link forge.Combat} object.
- * @param bAssault a boolean.
+ *
+ * chooseDefender.
+ *
+ *
+ * @param c
+ * a {@link forge.Combat} object.
+ * @param bAssault
+ * a boolean.
*/
- public void chooseDefender(Combat c, boolean bAssault) {
- // TODO: split attackers to different planeswalker/human
+ public final void chooseDefender(final Combat c, final boolean bAssault) {
+ // TODO split attackers to different planeswalker/human
// AI will only attack one Defender per combat for now
ArrayList