mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
moved a lot of AI-used methods from CardFactoryUtil to ComputerUtilCard.java
switched Encode to getSingleCardForEffect
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -14096,6 +14096,7 @@ src/main/java/forge/game/ai/AiInputBlock.java -text
|
|||||||
src/main/java/forge/game/ai/AiInputCommon.java svneol=native#text/plain
|
src/main/java/forge/game/ai/AiInputCommon.java svneol=native#text/plain
|
||||||
src/main/java/forge/game/ai/ComputerUtil.java svneol=native#text/plain
|
src/main/java/forge/game/ai/ComputerUtil.java svneol=native#text/plain
|
||||||
src/main/java/forge/game/ai/ComputerUtilBlock.java svneol=native#text/plain
|
src/main/java/forge/game/ai/ComputerUtilBlock.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/game/ai/ComputerUtilCard.java -text
|
||||||
src/main/java/forge/game/ai/ComputerUtilCombat.java -text
|
src/main/java/forge/game/ai/ComputerUtilCombat.java -text
|
||||||
src/main/java/forge/game/ai/ComputerUtilCost.java -text
|
src/main/java/forge/game/ai/ComputerUtilCost.java -text
|
||||||
src/main/java/forge/game/ai/ComputerUtilMana.java -text
|
src/main/java/forge/game/ai/ComputerUtilMana.java -text
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import com.google.common.base.Predicates;
|
|||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
@@ -74,13 +74,6 @@ public class CardLists {
|
|||||||
return b.getNetCombatDamage() - a.getNetCombatDamage();
|
return b.getNetCombatDamage() - a.getNetCombatDamage();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public static final Comparator<Card> EvaluateCreatureComparator = new Comparator<Card>() {
|
|
||||||
@Override
|
|
||||||
public int compare(final Card a, final Card b) {
|
|
||||||
return CardFactoryUtil.evaluateCreature(b) - CardFactoryUtil.evaluateCreature(a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final Comparator<Card> CmcComparator = new Comparator<Card>() {
|
public static final Comparator<Card> CmcComparator = new Comparator<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final Card a, final Card b) {
|
public int compare(final Card a, final Card b) {
|
||||||
@@ -131,7 +124,7 @@ public class CardLists {
|
|||||||
* a {@link forge.CardList} object.
|
* a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
public static void sortByEvaluateCreature(final List<Card> list) {
|
public static void sortByEvaluateCreature(final List<Card> list) {
|
||||||
Collections.sort(list, EvaluateCreatureComparator);
|
Collections.sort(list, ComputerUtilCard.EvaluateCreatureComparator);
|
||||||
} // sortByEvaluateCreature()
|
} // sortByEvaluateCreature()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import com.google.common.base.Function;
|
|||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.phase.Untap;
|
import forge.game.phase.Untap;
|
||||||
@@ -393,12 +392,5 @@ public final class CardPredicates {
|
|||||||
return a.getCMC();
|
return a.getCMC();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Function<Card, Integer> fnEvaluateCreature = new Function<Card, Integer>() {
|
|
||||||
@Override
|
|
||||||
public Integer apply(Card a) {
|
|
||||||
return CardFactoryUtil.evaluateCreature(a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import forge.card.CardSplitType;
|
|||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
import forge.card.mana.ManaCostBeingPaid;
|
|
||||||
import forge.card.spellability.AbilityManaPart;
|
import forge.card.spellability.AbilityManaPart;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -99,29 +98,6 @@ public final class CardUtil {
|
|||||||
return c.determineColor().toStringList();
|
return c.determineColor().toStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this function checks, if duplicates of a keyword are not necessary (like
|
|
||||||
// flying, trample, etc.)
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* isNonStackingKeyword.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param keyword
|
|
||||||
* a {@link java.lang.String} object.
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public static boolean isNonStackingKeyword(final String keyword) {
|
|
||||||
String kw = new String(keyword);
|
|
||||||
if (kw.startsWith("HIDDEN")) {
|
|
||||||
kw = kw.substring(7);
|
|
||||||
}
|
|
||||||
if (kw.startsWith("Protection")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return Constant.Keywords.NON_STACKING_LIST.contains(kw);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* isStackingKeyword.
|
* isStackingKeyword.
|
||||||
@@ -132,25 +108,12 @@ public final class CardUtil {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean isStackingKeyword(final String keyword) {
|
public static boolean isStackingKeyword(final String keyword) {
|
||||||
return !CardUtil.isNonStackingKeyword(keyword);
|
String kw = new String(keyword);
|
||||||
|
if (kw.startsWith("HIDDEN")) {
|
||||||
|
kw = kw.substring(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return !kw.startsWith("Protection") && !Constant.Keywords.NON_STACKING_LIST.contains(kw);
|
||||||
* Builds the ideal filename.
|
|
||||||
*
|
|
||||||
* @param cardName
|
|
||||||
* the card name
|
|
||||||
* @param artIndex
|
|
||||||
* the art index
|
|
||||||
* @param artIndexMax
|
|
||||||
* the art index max
|
|
||||||
* @return the string
|
|
||||||
*/
|
|
||||||
public static String buildIdealFilename(final String cardName, final int artIndex, final int artIndexMax) {
|
|
||||||
final String nn = artIndexMax > 1 ? Integer.toString(artIndex + 1) : "";
|
|
||||||
final String mwsCardName = GuiDisplayUtil.cleanStringMWS(cardName);
|
|
||||||
// 3 letter set code with MWS filename format
|
|
||||||
return String.format("%s%s.full.jpg", mwsCardName, nn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -432,35 +395,6 @@ public final class CardUtil {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the convokable colors.
|
|
||||||
*
|
|
||||||
* @param cardToConvoke
|
|
||||||
* the card to convoke
|
|
||||||
* @param cost
|
|
||||||
* the cost
|
|
||||||
* @return the convokable colors
|
|
||||||
*/
|
|
||||||
public static ArrayList<String> getConvokableColors(final Card cardToConvoke, final ManaCostBeingPaid cost) {
|
|
||||||
final ArrayList<String> usableColors = new ArrayList<String>();
|
|
||||||
|
|
||||||
if (cost.getColorlessManaAmount() > 0) {
|
|
||||||
usableColors.add("colorless");
|
|
||||||
}
|
|
||||||
for (final CardColor col : cardToConvoke.getColor()) {
|
|
||||||
for (final String strCol : col.toStringList()) {
|
|
||||||
if (strCol.equals("colorless")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (cost.toString().contains(MagicColor.toShortString(strCol))) {
|
|
||||||
usableColors.add(strCol.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return usableColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the face down characteristic.
|
* Gets the face down characteristic.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import forge.card.cost.Cost;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.card.staticability.StaticAbility;
|
import forge.card.staticability.StaticAbility;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
@@ -96,7 +97,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
// TODO If Not Mandatory, make sure the card is "good enough"
|
// TODO If Not Mandatory, make sure the card is "good enough"
|
||||||
if (c.isCreature()) {
|
if (c.isCreature()) {
|
||||||
final int eval = CardFactoryUtil.evaluateCreature(c);
|
final int eval = ComputerUtilCard.evaluateCreature(c);
|
||||||
if (eval < 130) {
|
if (eval < 130) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -119,7 +120,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CardFactoryUtil.getWorstPermanentAI(list, true, true, true, false);
|
return ComputerUtilCard.getWorstPermanentAI(list, true, true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,7 +137,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CardFactoryUtil.getBestAI(list);
|
return ComputerUtilCard.getBestAI(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,7 +175,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
list = CardLists.getNotType(list, type); // Filter out Basic Lands that have the
|
list = CardLists.getNotType(list, type); // Filter out Basic Lands that have the
|
||||||
// same type as the changing type
|
// same type as the changing type
|
||||||
|
|
||||||
final Card c = CardFactoryUtil.getBestAI(list);
|
final Card c = ComputerUtilCard.getBestAI(list);
|
||||||
|
|
||||||
// TODO Port over some of the existing code, but rewrite most of it.
|
// TODO Port over some of the existing code, but rewrite most of it.
|
||||||
// Ultimately, these spells need to be used to reduce mana base of a
|
// Ultimately, these spells need to be used to reduce mana base of a
|
||||||
@@ -234,7 +235,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final Card c = CardFactoryUtil.getBestAI(prefList);
|
final Card c = ComputerUtilCard.getBestAI(prefList);
|
||||||
|
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
return chooseLessPreferred(mandatory, list);
|
return chooseLessPreferred(mandatory, list);
|
||||||
@@ -333,7 +334,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final Card c = CardFactoryUtil.getMostExpensivePermanentAI(betterList);
|
final Card c = ComputerUtilCard.getMostExpensivePermanentAI(betterList);
|
||||||
|
|
||||||
// If Mandatory (brought directly into play without casting) gotta
|
// If Mandatory (brought directly into play without casting) gotta
|
||||||
// choose something
|
// choose something
|
||||||
@@ -361,7 +362,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
final Card attachSource) {
|
final Card attachSource) {
|
||||||
// AI For choosing a Card to Animate.
|
// AI For choosing a Card to Animate.
|
||||||
// TODO Add some more restrictions for Reanimation Auras
|
// TODO Add some more restrictions for Reanimation Auras
|
||||||
final Card c = CardFactoryUtil.getBestCreatureAI(list);
|
final Card c = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
|
|
||||||
// If Mandatory (brought directly into play without casting) gotta
|
// If Mandatory (brought directly into play without casting) gotta
|
||||||
// choose something
|
// choose something
|
||||||
@@ -406,7 +407,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
chosen = CardFactoryUtil.getBestCreatureAI(creatures);
|
chosen = ComputerUtilCard.getBestCreatureAI(creatures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +446,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Card c = CardFactoryUtil.getBestAI(list);
|
final Card c = ComputerUtilCard.getBestAI(list);
|
||||||
|
|
||||||
// If Mandatory (brought directly into play without casting) gotta
|
// If Mandatory (brought directly into play without casting) gotta
|
||||||
// choose something
|
// choose something
|
||||||
@@ -537,7 +538,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
if ((prefList == null) || prefList.isEmpty()) {
|
if ((prefList == null) || prefList.isEmpty()) {
|
||||||
prefList = new ArrayList<Card>(list);
|
prefList = new ArrayList<Card>(list);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getBestAI(prefList);
|
c = ComputerUtilCard.getBestAI(prefList);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -559,7 +560,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
c = CardFactoryUtil.getBestAI(prefList);
|
c = ComputerUtilCard.getBestAI(prefList);
|
||||||
|
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
return chooseLessPreferred(mandatory, list);
|
return chooseLessPreferred(mandatory, list);
|
||||||
@@ -602,7 +603,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
//don't equip a worse creature
|
//don't equip a worse creature
|
||||||
if (card.isEquipping()) {
|
if (card.isEquipping()) {
|
||||||
Card oldTarget = card.getEquipping().get(0);
|
Card oldTarget = card.getEquipping().get(0);
|
||||||
if (CardFactoryUtil.evaluateCreature(oldTarget) > CardFactoryUtil.evaluateCreature(newTarget)) {
|
if (ComputerUtilCard.evaluateCreature(oldTarget) > ComputerUtilCard.evaluateCreature(newTarget)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -723,7 +724,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return CardFactoryUtil.getBestAI(magnetList);
|
return ComputerUtilCard.getBestAI(magnetList);
|
||||||
}
|
}
|
||||||
|
|
||||||
int totToughness = 0;
|
int totToughness = 0;
|
||||||
@@ -809,11 +810,11 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
return !c.isCreature() || CombatUtil.canAttackNextTurn(c);
|
return !c.isCreature() || CombatUtil.canAttackNextTurn(c);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
c = CardFactoryUtil.getBestAI(prefList);
|
c = ComputerUtilCard.getBestAI(prefList);
|
||||||
} else {
|
} else {
|
||||||
// If we grant abilities, we may want to put it on something Weak?
|
// If we grant abilities, we may want to put it on something Weak?
|
||||||
// Possibly more defensive?
|
// Possibly more defensive?
|
||||||
c = CardFactoryUtil.getWorstPermanentAI(prefList, false, false, false, false);
|
c = ComputerUtilCard.getWorstPermanentAI(prefList, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import forge.card.ability.AbilityUtils;
|
|||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.ability.effects.AttachEffect;
|
import forge.card.ability.effects.AttachEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.cost.CostDiscard;
|
import forge.card.cost.CostDiscard;
|
||||||
import forge.card.cost.CostPart;
|
import forge.card.cost.CostPart;
|
||||||
@@ -29,6 +28,7 @@ import forge.card.spellability.SpellAbility;
|
|||||||
import forge.card.spellability.SpellPermanent;
|
import forge.card.spellability.SpellPermanent;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.GlobalRuleChange;
|
import forge.game.GlobalRuleChange;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
import forge.game.ai.ComputerUtilBlock;
|
import forge.game.ai.ComputerUtilBlock;
|
||||||
@@ -507,7 +507,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// not urgent, get the largest creature possible
|
// not urgent, get the largest creature possible
|
||||||
card = CardFactoryUtil.getBestCreatureAI(list);
|
card = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
}
|
}
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
@@ -730,7 +730,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
if (!threatenedTargets.isEmpty()) {
|
if (!threatenedTargets.isEmpty()) {
|
||||||
// Choose "best" of the remaining to save
|
// Choose "best" of the remaining to save
|
||||||
tgt.addTarget(CardFactoryUtil.getBestAI(threatenedTargets));
|
tgt.addTarget(ComputerUtilCard.getBestAI(threatenedTargets));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -762,7 +762,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
});
|
});
|
||||||
if (!aiPermanents.isEmpty()) {
|
if (!aiPermanents.isEmpty()) {
|
||||||
// Choose "best" of the remaining to save
|
// Choose "best" of the remaining to save
|
||||||
tgt.addTarget(CardFactoryUtil.getBestAI(aiPermanents));
|
tgt.addTarget(ComputerUtilCard.getBestAI(aiPermanents));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -839,15 +839,15 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
Card choice = null;
|
Card choice = null;
|
||||||
|
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
final Card mostExpensive = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, false);
|
final Card mostExpensive = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, false);
|
||||||
if (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield)) {
|
if (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield)) {
|
||||||
if (mostExpensive.isCreature()) {
|
if (mostExpensive.isCreature()) {
|
||||||
// if a creature is most expensive take the best one
|
// if a creature is most expensive take the best one
|
||||||
if (destination.equals(ZoneType.Exile)) {
|
if (destination.equals(ZoneType.Exile)) {
|
||||||
// If Exiling things, don't give bonus to Tokens
|
// If Exiling things, don't give bonus to Tokens
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getBestCreatureToBounceAI(list);
|
choice = ComputerUtilCard.getBestCreatureToBounceAI(list);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
choice = mostExpensive;
|
choice = mostExpensive;
|
||||||
@@ -870,7 +870,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
} else {
|
} else {
|
||||||
// Get the best card in there.
|
// Get the best card in there.
|
||||||
System.out.println("No creature and lots of life, finding something good.");
|
System.out.println("No creature and lots of life, finding something good.");
|
||||||
choice = CardFactoryUtil.getBestAI(nonLands);
|
choice = ComputerUtilCard.getBestAI(nonLands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (choice == null) {
|
if (choice == null) {
|
||||||
@@ -879,7 +879,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
choice = list.get(0);
|
choice = list.get(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getBestAI(list);
|
choice = ComputerUtilCard.getBestAI(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
@@ -957,12 +957,12 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
Card choice = null;
|
Card choice = null;
|
||||||
|
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
if (CardFactoryUtil.getMostExpensivePermanentAI(list, sa, false).isCreature()
|
if (ComputerUtilCard.getMostExpensivePermanentAI(list, sa, false).isCreature()
|
||||||
&& (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield))) {
|
&& (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield))) {
|
||||||
// if a creature is most expensive take the best
|
// if a creature is most expensive take the best
|
||||||
choice = CardFactoryUtil.getBestCreatureToBounceAI(list);
|
choice = ComputerUtilCard.getBestCreatureToBounceAI(list);
|
||||||
} else if (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield)) {
|
} else if (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield)) {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, false);
|
||||||
} else if (destination.equals(ZoneType.Hand) || destination.equals(ZoneType.Library)) {
|
} else if (destination.equals(ZoneType.Hand) || destination.equals(ZoneType.Library)) {
|
||||||
List<Card> nonLands = CardLists.getNotType(list, "Land");
|
List<Card> nonLands = CardLists.getNotType(list, "Land");
|
||||||
// Prefer to pull a creature, generally more useful for AI.
|
// Prefer to pull a creature, generally more useful for AI.
|
||||||
@@ -981,7 +981,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
} else {
|
} else {
|
||||||
// Get the best card in there.
|
// Get the best card in there.
|
||||||
System.out.println("No creature and lots of life, finding something good.");
|
System.out.println("No creature and lots of life, finding something good.");
|
||||||
choice = CardFactoryUtil.getBestAI(nonLands);
|
choice = ComputerUtilCard.getBestAI(nonLands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (choice == null) {
|
if (choice == null) {
|
||||||
@@ -990,7 +990,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
choice = list.get(0);
|
choice = list.get(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getBestAI(list);
|
choice = ComputerUtilCard.getBestAI(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
@@ -1168,9 +1168,9 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)) {
|
if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)) {
|
||||||
// Exiling or bouncing stuff
|
// Exiling or bouncing stuff
|
||||||
if (player.isOpponentOf(ai)) {
|
if (player.isOpponentOf(ai)) {
|
||||||
c = CardFactoryUtil.getBestAI(fetchList);
|
c = ComputerUtilCard.getBestAI(fetchList);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getWorstAI(fetchList);
|
c = ComputerUtilCard.getWorstAI(fetchList);
|
||||||
}
|
}
|
||||||
} else if (origin.contains(ZoneType.Library)
|
} else if (origin.contains(ZoneType.Library)
|
||||||
&& (type.contains("Basic") || areAllBasics(type))) {
|
&& (type.contains("Basic") || areAllBasics(type))) {
|
||||||
@@ -1179,9 +1179,9 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
c = chooseCreature(ai, fetchList);
|
c = chooseCreature(ai, fetchList);
|
||||||
} else if (ZoneType.Battlefield.equals(destination) || ZoneType.Graveyard.equals(destination)) {
|
} else if (ZoneType.Battlefield.equals(destination) || ZoneType.Graveyard.equals(destination)) {
|
||||||
if (!activator.equals(ai) && sa.hasParam("GainControl")) {
|
if (!activator.equals(ai) && sa.hasParam("GainControl")) {
|
||||||
c = CardFactoryUtil.getWorstAI(fetchList);
|
c = ComputerUtilCard.getWorstAI(fetchList);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getBestAI(fetchList);
|
c = ComputerUtilCard.getBestAI(fetchList);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Don't fetch another tutor with the same name
|
// Don't fetch another tutor with the same name
|
||||||
@@ -1222,7 +1222,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
} else {
|
} else {
|
||||||
// Get the best card in there.
|
// Get the best card in there.
|
||||||
System.out.println("No creature and lots of life, finding something good.");
|
System.out.println("No creature and lots of life, finding something good.");
|
||||||
c = CardFactoryUtil.getBestAI(fetchList);
|
c = ComputerUtilCard.getBestAI(fetchList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1263,7 +1263,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), c.getController(), c);
|
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), c.getController(), c);
|
||||||
}
|
}
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
final Card attachedTo = CardFactoryUtil.getBestAI(list);
|
final Card attachedTo = ComputerUtilCard.getBestAI(list);
|
||||||
if (c.isEnchanting()) {
|
if (c.isEnchanting()) {
|
||||||
// If this Card is already Enchanting something, need
|
// If this Card is already Enchanting something, need
|
||||||
// to unenchant it, then clear out the commands
|
// to unenchant it, then clear out the commands
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
@@ -89,13 +89,13 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
|||||||
computerType.clear();
|
computerType.clear();
|
||||||
}
|
}
|
||||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||||
if ((CardFactoryUtil.evaluateCreatureList(computerType) + 200) >= CardFactoryUtil
|
if ((ComputerUtilCard.evaluateCreatureList(computerType) + 200) >= ComputerUtilCard
|
||||||
.evaluateCreatureList(humanType)) {
|
.evaluateCreatureList(humanType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are more valuable
|
// permanents are more valuable
|
||||||
else if ((CardFactoryUtil.evaluatePermanentList(computerType) + 3) >= CardFactoryUtil
|
else if ((ComputerUtilCard.evaluatePermanentList(computerType) + 3) >= ComputerUtilCard
|
||||||
.evaluatePermanentList(humanType)) {
|
.evaluatePermanentList(humanType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -127,26 +127,26 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
|||||||
if (sa.getParam("GainControl") != null) {
|
if (sa.getParam("GainControl") != null) {
|
||||||
// Check if the cards are valuable enough
|
// Check if the cards are valuable enough
|
||||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||||
if ((CardFactoryUtil.evaluateCreatureList(computerType) + CardFactoryUtil
|
if ((ComputerUtilCard.evaluateCreatureList(computerType) + ComputerUtilCard
|
||||||
.evaluateCreatureList(humanType)) < 400) {
|
.evaluateCreatureList(humanType)) < 400) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are less valuable
|
// permanents are less valuable
|
||||||
else if ((CardFactoryUtil.evaluatePermanentList(computerType) + CardFactoryUtil
|
else if ((ComputerUtilCard.evaluatePermanentList(computerType) + ComputerUtilCard
|
||||||
.evaluatePermanentList(humanType)) < 6) {
|
.evaluatePermanentList(humanType)) < 6) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// don't activate if human gets more back than AI does
|
// don't activate if human gets more back than AI does
|
||||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||||
if (CardFactoryUtil.evaluateCreatureList(computerType) <= (CardFactoryUtil
|
if (ComputerUtilCard.evaluateCreatureList(computerType) <= (ComputerUtilCard
|
||||||
.evaluateCreatureList(humanType) + 100)) {
|
.evaluateCreatureList(humanType) + 100)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are less valuable
|
// permanents are less valuable
|
||||||
else if (CardFactoryUtil.evaluatePermanentList(computerType) <= (CardFactoryUtil
|
else if (ComputerUtilCard.evaluatePermanentList(computerType) <= (ComputerUtilCard
|
||||||
.evaluatePermanentList(humanType) + 2)) {
|
.evaluatePermanentList(humanType) + 2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -206,13 +206,13 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
|||||||
// if only creatures are affected evaluate both lists and pass only
|
// if only creatures are affected evaluate both lists and pass only
|
||||||
// if human creatures are more valuable
|
// if human creatures are more valuable
|
||||||
if ((CardLists.getNotType(humanType, "Creature").isEmpty()) && (CardLists.getNotType(computerType, "Creature").isEmpty())) {
|
if ((CardLists.getNotType(humanType, "Creature").isEmpty()) && (CardLists.getNotType(computerType, "Creature").isEmpty())) {
|
||||||
if (CardFactoryUtil.evaluateCreatureList(computerType) >= CardFactoryUtil
|
if (ComputerUtilCard.evaluateCreatureList(computerType) >= ComputerUtilCard
|
||||||
.evaluateCreatureList(humanType)) {
|
.evaluateCreatureList(humanType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are more valuable
|
// permanents are more valuable
|
||||||
else if (CardFactoryUtil.evaluatePermanentList(computerType) >= CardFactoryUtil
|
else if (ComputerUtilCard.evaluatePermanentList(computerType) >= ComputerUtilCard
|
||||||
.evaluatePermanentList(humanType)) {
|
.evaluatePermanentList(humanType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -240,26 +240,26 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
|||||||
if (sa.getParam("GainControl") != null) {
|
if (sa.getParam("GainControl") != null) {
|
||||||
// Check if the cards are valuable enough
|
// Check if the cards are valuable enough
|
||||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||||
if ((CardFactoryUtil.evaluateCreatureList(computerType) + CardFactoryUtil
|
if ((ComputerUtilCard.evaluateCreatureList(computerType) + ComputerUtilCard
|
||||||
.evaluateCreatureList(humanType)) < 1) {
|
.evaluateCreatureList(humanType)) < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are less valuable
|
// permanents are less valuable
|
||||||
else if ((CardFactoryUtil.evaluatePermanentList(computerType) + CardFactoryUtil
|
else if ((ComputerUtilCard.evaluatePermanentList(computerType) + ComputerUtilCard
|
||||||
.evaluatePermanentList(humanType)) < 1) {
|
.evaluatePermanentList(humanType)) < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// don't activate if human gets more back than AI does
|
// don't activate if human gets more back than AI does
|
||||||
if ((CardLists.getNotType(humanType, "Creature").isEmpty()) && (CardLists.getNotType(computerType, "Creature").isEmpty())) {
|
if ((CardLists.getNotType(humanType, "Creature").isEmpty()) && (CardLists.getNotType(computerType, "Creature").isEmpty())) {
|
||||||
if (CardFactoryUtil.evaluateCreatureList(computerType) <= CardFactoryUtil
|
if (ComputerUtilCard.evaluateCreatureList(computerType) <= ComputerUtilCard
|
||||||
.evaluateCreatureList(humanType)) {
|
.evaluateCreatureList(humanType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are less valuable
|
// permanents are less valuable
|
||||||
else if (CardFactoryUtil.evaluatePermanentList(computerType) <= CardFactoryUtil
|
else if (ComputerUtilCard.evaluatePermanentList(computerType) <= ComputerUtilCard
|
||||||
.evaluatePermanentList(humanType)) {
|
.evaluatePermanentList(humanType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import forge.Card;
|
|||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
@@ -39,19 +39,19 @@ public class ControlExchangeAi extends SpellAbilityAi {
|
|||||||
return !vars.containsKey("RemAIDeck") && c.canBeTargetedBy(sa);
|
return !vars.containsKey("RemAIDeck") && c.canBeTargetedBy(sa);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
object1 = CardFactoryUtil.getBestAI(list);
|
object1 = ComputerUtilCard.getBestAI(list);
|
||||||
if (sa.hasParam("Defined")) {
|
if (sa.hasParam("Defined")) {
|
||||||
object2 = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa).get(0);
|
object2 = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa).get(0);
|
||||||
} else if (tgt.getMinTargets(sa.getSourceCard(), sa) > 1) {
|
} else if (tgt.getMinTargets(sa.getSourceCard(), sa) > 1) {
|
||||||
List<Card> list2 = ai.getCardsIn(ZoneType.Battlefield);
|
List<Card> list2 = ai.getCardsIn(ZoneType.Battlefield);
|
||||||
list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getSourceCard());
|
list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getSourceCard());
|
||||||
object2 = CardFactoryUtil.getWorstAI(list2);
|
object2 = ComputerUtilCard.getWorstAI(list2);
|
||||||
tgt.addTarget(object2);
|
tgt.addTarget(object2);
|
||||||
}
|
}
|
||||||
if (object1 == null || object2 == null) {
|
if (object1 == null || object2 == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (CardFactoryUtil.evaluateCreature(object1) > CardFactoryUtil.evaluateCreature(object2) + 40) {
|
if (ComputerUtilCard.evaluateCreature(object1) > ComputerUtilCard.evaluateCreature(object2) + 40) {
|
||||||
tgt.addTarget(object1);
|
tgt.addTarget(object1);
|
||||||
return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
|
return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -139,15 +139,15 @@ public class ControlGainAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasCreature) {
|
if (hasCreature) {
|
||||||
t = CardFactoryUtil.getBestCreatureAI(list);
|
t = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
} else if (hasArtifact) {
|
} else if (hasArtifact) {
|
||||||
t = CardFactoryUtil.getBestArtifactAI(list);
|
t = ComputerUtilCard.getBestArtifactAI(list);
|
||||||
} else if (hasLand) {
|
} else if (hasLand) {
|
||||||
t = CardFactoryUtil.getBestLandAI(list);
|
t = ComputerUtilCard.getBestLandAI(list);
|
||||||
} else if (hasEnchantment) {
|
} else if (hasEnchantment) {
|
||||||
t = CardFactoryUtil.getBestEnchantmentAI(list, sa, true);
|
t = ComputerUtilCard.getBestEnchantmentAI(list, sa, true);
|
||||||
} else {
|
} else {
|
||||||
t = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, true);
|
t = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
tgt.addTarget(t);
|
tgt.addTarget(t);
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -82,9 +82,9 @@ public class CopyPermanentAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
Card choice;
|
Card choice;
|
||||||
if (!CardLists.filter(list, Presets.CREATURES).isEmpty()) {
|
if (!CardLists.filter(list, Presets.CREATURES).isEmpty()) {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, true);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import forge.card.cost.Cost;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.card.spellability.TargetSelection;
|
import forge.card.spellability.TargetSelection;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
@@ -62,7 +63,7 @@ public class CounterAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
if (unlessCost != null && !unlessCost.endsWith(">")) {
|
if (unlessCost != null && !unlessCost.endsWith(">")) {
|
||||||
// Is this Usable Mana Sources? Or Total Available Mana?
|
// Is this Usable Mana Sources? Or Total Available Mana?
|
||||||
final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent());
|
final int usableManaSources = ComputerUtilCard.getUsableManaSources(ai.getOpponent());
|
||||||
int toPay = 0;
|
int toPay = 0;
|
||||||
boolean setPayX = false;
|
boolean setPayX = false;
|
||||||
if (unlessCost.equals("X") && source.getSVar(unlessCost).equals("Count$xPaid")) {
|
if (unlessCost.equals("X") && source.getSVar(unlessCost).equals("Count$xPaid")) {
|
||||||
@@ -130,7 +131,7 @@ public class CounterAi extends SpellAbilityAi {
|
|||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
if (unlessCost != null) {
|
if (unlessCost != null) {
|
||||||
// Is this Usable Mana Sources? Or Total Available Mana?
|
// Is this Usable Mana Sources? Or Total Available Mana?
|
||||||
final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent());
|
final int usableManaSources = ComputerUtilCard.getUsableManaSources(ai.getOpponent());
|
||||||
int toPay = 0;
|
int toPay = 0;
|
||||||
boolean setPayX = false;
|
boolean setPayX = false;
|
||||||
if (unlessCost.equals("X") && source.getSVar(unlessCost).equals("Count$xPaid")) {
|
if (unlessCost.equals("X") && source.getSVar(unlessCost).equals("Count$xPaid")) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import forge.Card;
|
|||||||
|
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.game.ai.ComputerUtilCard;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,13 +63,13 @@ public abstract class CountersAi {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (killable.size() > 0) {
|
if (killable.size() > 0) {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(killable);
|
choice = ComputerUtilCard.getBestCreatureAI(killable);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// improve random choice here
|
// improve random choice here
|
||||||
choice = CardFactoryUtil.getRandomCard(list);
|
choice = ComputerUtilCard.getRandomCard(list);
|
||||||
}
|
}
|
||||||
return choice;
|
return choice;
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ public abstract class CountersAi {
|
|||||||
public static Card chooseBoonTarget(final List<Card> list, final String type) {
|
public static Card chooseBoonTarget(final List<Card> list, final String type) {
|
||||||
Card choice;
|
Card choice;
|
||||||
if (type.equals("P1P1")) {
|
if (type.equals("P1P1")) {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
} else if (type.equals("DIVINITY")) {
|
} else if (type.equals("DIVINITY")) {
|
||||||
final List<Card> boon = CardLists.filter(list, new Predicate<Card>() {
|
final List<Card> boon = CardLists.filter(list, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -96,12 +96,12 @@ public abstract class CountersAi {
|
|||||||
return c.getCounters(CounterType.DIVINITY) == 0;
|
return c.getCounters(CounterType.DIVINITY) == 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(boon, null, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(boon, null, false);
|
||||||
} else {
|
} else {
|
||||||
// The AI really should put counters on cards that can use it.
|
// The AI really should put counters on cards that can use it.
|
||||||
// Charge counters on things with Charge abilities, etc. Expand
|
// Charge counters on things with Charge abilities, etc. Expand
|
||||||
// these above
|
// these above
|
||||||
choice = CardFactoryUtil.getRandomCard(list);
|
choice = ComputerUtilCard.getRandomCard(list);
|
||||||
}
|
}
|
||||||
return choice;
|
return choice;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import forge.CardLists;
|
|||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -103,9 +103,9 @@ public class CountersMoveAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
if (type.equals("M1M1")) {
|
if (type.equals("M1M1")) {
|
||||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getRandomCard(list);
|
choice = ComputerUtilCard.getRandomCard(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -115,9 +115,9 @@ public class CountersMoveAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
if (type.equals("P1P1")) {
|
if (type.equals("P1P1")) {
|
||||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getRandomCard(list);
|
choice = ComputerUtilCard.getRandomCard(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import forge.CounterType;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -279,9 +279,9 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
if (type.equals("M1M1")) {
|
if (type.equals("M1M1")) {
|
||||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getRandomCard(list);
|
choice = ComputerUtilCard.getRandomCard(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -291,9 +291,9 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
if (type.equals("P1P1")) {
|
if (type.equals("P1P1")) {
|
||||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getRandomCard(list);
|
choice = ComputerUtilCard.getRandomCard(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
@@ -96,7 +96,7 @@ public class DamageAllAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// evaluate both lists and pass only if human creatures are more valuable
|
// evaluate both lists and pass only if human creatures are more valuable
|
||||||
if ((CardFactoryUtil.evaluateCreatureList(computerList) + minGain) >= CardFactoryUtil
|
if ((ComputerUtilCard.evaluateCreatureList(computerList) + minGain) >= ComputerUtilCard
|
||||||
.evaluateCreatureList(humanList)) {
|
.evaluateCreatureList(humanList)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ public class DamageAllAi extends SpellAbilityAi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!computerList.isEmpty() && CardFactoryUtil.evaluateCreatureList(computerList) > CardFactoryUtil
|
if (!computerList.isEmpty() && ComputerUtilCard.evaluateCreatureList(computerList) > ComputerUtilCard
|
||||||
.evaluateCreatureList(humanList)) {
|
.evaluateCreatureList(humanList)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -233,7 +233,7 @@ public class DamageAllAi extends SpellAbilityAi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!computerList.isEmpty() && CardFactoryUtil.evaluateCreatureList(computerList) + 50 >= CardFactoryUtil
|
if (!computerList.isEmpty() && ComputerUtilCard.evaluateCreatureList(computerList) + 50 >= ComputerUtilCard
|
||||||
.evaluateCreatureList(humanList)) {
|
.evaluateCreatureList(humanList)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.card.spellability.TargetSelection;
|
import forge.card.spellability.TargetSelection;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
@@ -165,7 +165,7 @@ public class DamageDealAi extends DamageAiBase {
|
|||||||
|
|
||||||
Card targetCard;
|
Card targetCard;
|
||||||
if (pl.isOpponentOf(ai) && (killables.size() > 0)) {
|
if (pl.isOpponentOf(ai) && (killables.size() > 0)) {
|
||||||
targetCard = CardFactoryUtil.getBestCreatureAI(killables);
|
targetCard = ComputerUtilCard.getBestCreatureAI(killables);
|
||||||
|
|
||||||
return targetCard;
|
return targetCard;
|
||||||
}
|
}
|
||||||
@@ -176,9 +176,9 @@ public class DamageDealAi extends DamageAiBase {
|
|||||||
|
|
||||||
if (hPlay.size() > 0) {
|
if (hPlay.size() > 0) {
|
||||||
if (pl.isOpponentOf(ai)) {
|
if (pl.isOpponentOf(ai)) {
|
||||||
targetCard = CardFactoryUtil.getBestCreatureAI(hPlay);
|
targetCard = ComputerUtilCard.getBestCreatureAI(hPlay);
|
||||||
} else {
|
} else {
|
||||||
targetCard = CardFactoryUtil.getWorstCreatureAI(hPlay);
|
targetCard = ComputerUtilCard.getWorstCreatureAI(hPlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetCard;
|
return targetCard;
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import forge.CardPredicates;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
@@ -113,7 +113,7 @@ public class DamagePreventAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
if (!threatenedTargets.isEmpty()) {
|
if (!threatenedTargets.isEmpty()) {
|
||||||
// Choose "best" of the remaining to save
|
// Choose "best" of the remaining to save
|
||||||
tgt.addTarget(CardFactoryUtil.getBestCreatureAI(threatenedTargets));
|
tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets));
|
||||||
chance = true;
|
chance = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ public class DamagePreventAi extends SpellAbilityAi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tgt.addTarget(CardFactoryUtil.getCheapestPermanentAI(targetables, sa, true));
|
tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.SpellAbilityRestriction;
|
import forge.card.spellability.SpellAbilityRestriction;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -164,7 +164,7 @@ public class DebuffAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t = CardFactoryUtil.getBestCreatureAI(list);
|
t = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
tgt.addTarget(t);
|
tgt.addTarget(t);
|
||||||
list.remove(t);
|
list.remove(t);
|
||||||
}
|
}
|
||||||
@@ -242,9 +242,9 @@ public class DebuffAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getBestCreatureAI(pref);
|
c = ComputerUtilCard.getBestCreatureAI(pref);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref, sa, true);
|
c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pref.remove(c);
|
pref.remove(c);
|
||||||
@@ -261,9 +261,9 @@ public class DebuffAi extends SpellAbilityAi {
|
|||||||
// keyword
|
// keyword
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getWorstCreatureAI(forced);
|
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getCheapestPermanentAI(forced, sa, true);
|
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
forced.remove(c);
|
forced.remove(c);
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ import forge.CounterType;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.cost.CostPart;
|
import forge.card.cost.CostPart;
|
||||||
import forge.card.cost.CostSacrifice;
|
import forge.card.cost.CostSacrifice;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -130,11 +130,11 @@ public class DestroyAi extends SpellAbilityAi {
|
|||||||
Card choice = null;
|
Card choice = null;
|
||||||
// If the targets are only of one type, take the best
|
// If the targets are only of one type, take the best
|
||||||
if (CardLists.getNotType(list, "Creature").isEmpty()) {
|
if (CardLists.getNotType(list, "Creature").isEmpty()) {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
} else if (CardLists.getNotType(list, "Land").isEmpty()) {
|
} else if (CardLists.getNotType(list, "Land").isEmpty()) {
|
||||||
choice = CardFactoryUtil.getBestLandAI(list);
|
choice = ComputerUtilCard.getBestLandAI(list);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, true);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
@@ -218,11 +218,11 @@ public class DestroyAi extends SpellAbilityAi {
|
|||||||
} else {
|
} else {
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(preferred, "Creature").size() == 0) {
|
if (CardLists.getNotType(preferred, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getBestCreatureAI(preferred);
|
c = ComputerUtilCard.getBestCreatureAI(preferred);
|
||||||
} else if (CardLists.getNotType(preferred, "Land").size() == 0) {
|
} else if (CardLists.getNotType(preferred, "Land").size() == 0) {
|
||||||
c = CardFactoryUtil.getBestLandAI(preferred);
|
c = ComputerUtilCard.getBestLandAI(preferred);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getMostExpensivePermanentAI(preferred, sa, false);
|
c = ComputerUtilCard.getMostExpensivePermanentAI(preferred, sa, false);
|
||||||
}
|
}
|
||||||
tgt.addTarget(c);
|
tgt.addTarget(c);
|
||||||
preferred.remove(c);
|
preferred.remove(c);
|
||||||
@@ -235,9 +235,9 @@ public class DestroyAi extends SpellAbilityAi {
|
|||||||
} else {
|
} else {
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(list, "Creature").size() == 0) {
|
if (CardLists.getNotType(list, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getWorstCreatureAI(list);
|
c = ComputerUtilCard.getWorstCreatureAI(list);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getCheapestPermanentAI(list, sa, false);
|
c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false);
|
||||||
}
|
}
|
||||||
tgt.addTarget(c);
|
tgt.addTarget(c);
|
||||||
list.remove(c);
|
list.remove(c);
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import com.google.common.base.Predicate;
|
|||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
@@ -60,13 +60,13 @@ public class DestroyAllAi extends SpellAbilityAi {
|
|||||||
// if only creatures are affected evaluate both lists and pass only if
|
// if only creatures are affected evaluate both lists and pass only if
|
||||||
// human creatures are more valuable
|
// human creatures are more valuable
|
||||||
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
||||||
if (CardFactoryUtil.evaluateCreatureList(computerlist) >= CardFactoryUtil.evaluateCreatureList(humanlist)
|
if (ComputerUtilCard.evaluateCreatureList(computerlist) >= ComputerUtilCard.evaluateCreatureList(humanlist)
|
||||||
&& !computerlist.isEmpty()) {
|
&& !computerlist.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are more valuable
|
// permanents are more valuable
|
||||||
else if (CardFactoryUtil.evaluatePermanentList(computerlist) >= CardFactoryUtil.evaluatePermanentList(humanlist)) {
|
else if (ComputerUtilCard.evaluatePermanentList(computerlist) >= ComputerUtilCard.evaluatePermanentList(humanlist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -127,19 +127,19 @@ public class DestroyAllAi extends SpellAbilityAi {
|
|||||||
// if only creatures are affected evaluate both lists and pass only if
|
// if only creatures are affected evaluate both lists and pass only if
|
||||||
// human creatures are more valuable
|
// human creatures are more valuable
|
||||||
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
||||||
if ((CardFactoryUtil.evaluateCreatureList(computerlist) + 200) >= CardFactoryUtil
|
if ((ComputerUtilCard.evaluateCreatureList(computerlist) + 200) >= ComputerUtilCard
|
||||||
.evaluateCreatureList(humanlist)) {
|
.evaluateCreatureList(humanlist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // only lands involved
|
} // only lands involved
|
||||||
else if ((CardLists.getNotType(humanlist, "Land").size() == 0) && (CardLists.getNotType(computerlist, "Land").size() == 0)) {
|
else if ((CardLists.getNotType(humanlist, "Land").size() == 0) && (CardLists.getNotType(computerlist, "Land").size() == 0)) {
|
||||||
if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 1) >= CardFactoryUtil
|
if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 1) >= ComputerUtilCard
|
||||||
.evaluatePermanentList(humanlist)) {
|
.evaluatePermanentList(humanlist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are more valuable
|
// permanents are more valuable
|
||||||
else if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 3) >= CardFactoryUtil
|
else if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 3) >= ComputerUtilCard
|
||||||
.evaluatePermanentList(humanlist)) {
|
.evaluatePermanentList(humanlist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import forge.Card;
|
|||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
@@ -61,7 +61,7 @@ public class EffectAi extends SpellAbilityAi {
|
|||||||
List<Card> list = game.getCombat().getAttackerList();
|
List<Card> list = game.getCombat().getAttackerList();
|
||||||
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
|
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
|
||||||
list = CardLists.getTargetableCards(list, sa);
|
list = CardLists.getTargetableCards(list, sa);
|
||||||
Card target = CardFactoryUtil.getBestCreatureAI(list);
|
Card target = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import forge.CardPredicates;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -86,7 +86,7 @@ public class MustBlockAi extends SpellAbilityAi {
|
|||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Card blocker = CardFactoryUtil.getBestCreatureAI(list);
|
final Card blocker = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
if (blocker == null) {
|
if (blocker == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -62,7 +62,7 @@ public class PlayAi extends SpellAbilityAi {
|
|||||||
if (cards.isEmpty()) {
|
if (cards.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
tgt.addTarget(CardFactoryUtil.getBestAI(cards));
|
tgt.addTarget(ComputerUtilCard.getBestAI(cards));
|
||||||
} else if (!sa.hasParam("Valid")) {
|
} else if (!sa.hasParam("Valid")) {
|
||||||
cards = new ArrayList<Card>(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa));
|
cards = new ArrayList<Card>(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa));
|
||||||
if (cards.isEmpty()) {
|
if (cards.isEmpty()) {
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import forge.Constant;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -86,7 +86,7 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
// will the creature attack (only relevant for sorcery speed)?
|
// will the creature attack (only relevant for sorcery speed)?
|
||||||
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
&& game.getPhaseHandler().isPlayerTurn(ai)
|
&& game.getPhaseHandler().isPlayerTurn(ai)
|
||||||
&& CardFactoryUtil.doesCreatureAttackAI(ai, c)) {
|
&& ComputerUtilCard.doesCreatureAttackAI(ai, c)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t = CardFactoryUtil.getBestCreatureAI(list);
|
t = ComputerUtilCard.getBestCreatureAI(list);
|
||||||
tgt.addTarget(t);
|
tgt.addTarget(t);
|
||||||
list.remove(t);
|
list.remove(t);
|
||||||
}
|
}
|
||||||
@@ -290,9 +290,9 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getBestCreatureAI(pref);
|
c = ComputerUtilCard.getBestCreatureAI(pref);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref, sa, true);
|
c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pref.remove(c);
|
pref.remove(c);
|
||||||
@@ -307,9 +307,9 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(pref2, "Creature").size() == 0) {
|
if (CardLists.getNotType(pref2, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getBestCreatureAI(pref2);
|
c = ComputerUtilCard.getBestCreatureAI(pref2);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref2, sa, true);
|
c = ComputerUtilCard.getMostExpensivePermanentAI(pref2, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pref2.remove(c);
|
pref2.remove(c);
|
||||||
@@ -324,9 +324,9 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getWorstCreatureAI(forced);
|
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getCheapestPermanentAI(forced, sa, true);
|
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
forced.remove(c);
|
forced.remove(c);
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ import forge.Singletons;
|
|||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.cost.CostUtil;
|
import forge.card.cost.CostUtil;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.SpellAbilityRestriction;
|
import forge.card.spellability.SpellAbilityRestriction;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
@@ -259,7 +259,7 @@ public class PumpAi extends PumpAiBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t = CardFactoryUtil.getBestAI(list);
|
t = ComputerUtilCard.getBestAI(list);
|
||||||
tgt.addTarget(t);
|
tgt.addTarget(t);
|
||||||
list.remove(t);
|
list.remove(t);
|
||||||
}
|
}
|
||||||
@@ -303,9 +303,9 @@ public class PumpAi extends PumpAiBase {
|
|||||||
|
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getBestCreatureAI(pref);
|
c = ComputerUtilCard.getBestCreatureAI(pref);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref, sa, true);
|
c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pref.remove(c);
|
pref.remove(c);
|
||||||
@@ -320,9 +320,9 @@ public class PumpAi extends PumpAiBase {
|
|||||||
|
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getWorstCreatureAI(forced);
|
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getCheapestPermanentAI(forced, sa, true);
|
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
forced.remove(c);
|
forced.remove(c);
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import forge.CardPredicates;
|
|||||||
import forge.CardUtil;
|
import forge.CardUtil;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.phase.Combat;
|
import forge.game.phase.Combat;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
@@ -403,7 +403,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
&& phase.isPlayerTurn(ai)
|
&& phase.isPlayerTurn(ai)
|
||||||
&& SpellAbilityAi.isSorcerySpeed(sa)
|
&& SpellAbilityAi.isSorcerySpeed(sa)
|
||||||
&& attack > 0
|
&& attack > 0
|
||||||
&& CardFactoryUtil.doesCreatureAttackAI(ai, c)) {
|
&& ComputerUtilCard.doesCreatureAttackAI(ai, c)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import forge.Card;
|
|||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
@@ -106,7 +106,7 @@ public class PumpAllAi extends PumpAiBase {
|
|||||||
|
|
||||||
// evaluate both lists and pass only if human creatures are more
|
// evaluate both lists and pass only if human creatures are more
|
||||||
// valuable
|
// valuable
|
||||||
if ((CardFactoryUtil.evaluateCreatureList(comp) + 200) >= CardFactoryUtil.evaluateCreatureList(human)) {
|
if ((ComputerUtilCard.evaluateCreatureList(comp) + 200) >= ComputerUtilCard.evaluateCreatureList(human)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ import forge.CardPredicates;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -132,7 +132,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
if (!threatenedTargets.isEmpty()) {
|
if (!threatenedTargets.isEmpty()) {
|
||||||
// Choose "best" of the remaining to regenerate
|
// Choose "best" of the remaining to regenerate
|
||||||
tgt.addTarget(CardFactoryUtil.getBestCreatureAI(threatenedTargets));
|
tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets));
|
||||||
chance = true;
|
chance = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -225,7 +225,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tgt.addTarget(CardFactoryUtil.getCheapestPermanentAI(targetables, sa, true));
|
tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import forge.Card;
|
|||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -128,7 +128,7 @@ public class SacrificeAi extends SpellAbilityAi {
|
|||||||
List<Card> computerList =
|
List<Card> computerList =
|
||||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
||||||
for (Card c : computerList) {
|
for (Card c : computerList) {
|
||||||
if (!c.getSVar("SacMe").equals("") || CardFactoryUtil.evaluateCreature(c) <= 135) {
|
if (!c.getSVar("SacMe").equals("") || ComputerUtilCard.evaluateCreature(c) <= 135) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import java.util.Random;
|
|||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
@@ -55,19 +55,19 @@ public class SacrificeAllAi extends SpellAbilityAi {
|
|||||||
// if only creatures are affected evaluate both lists and pass only if
|
// if only creatures are affected evaluate both lists and pass only if
|
||||||
// human creatures are more valuable
|
// human creatures are more valuable
|
||||||
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
||||||
if ((CardFactoryUtil.evaluateCreatureList(computerlist) + 200) >= CardFactoryUtil
|
if ((ComputerUtilCard.evaluateCreatureList(computerlist) + 200) >= ComputerUtilCard
|
||||||
.evaluateCreatureList(humanlist)) {
|
.evaluateCreatureList(humanlist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // only lands involved
|
} // only lands involved
|
||||||
else if ((CardLists.getNotType(humanlist, "Land").size() == 0) && (CardLists.getNotType(computerlist, "Land").size() == 0)) {
|
else if ((CardLists.getNotType(humanlist, "Land").size() == 0) && (CardLists.getNotType(computerlist, "Land").size() == 0)) {
|
||||||
if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 1) >= CardFactoryUtil
|
if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 1) >= ComputerUtilCard
|
||||||
.evaluatePermanentList(humanlist)) {
|
.evaluatePermanentList(humanlist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // otherwise evaluate both lists by CMC and pass only if human
|
} // otherwise evaluate both lists by CMC and pass only if human
|
||||||
// permanents are more valuable
|
// permanents are more valuable
|
||||||
else if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 3) >= CardFactoryUtil
|
else if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 3) >= ComputerUtilCard
|
||||||
.evaluatePermanentList(humanlist)) {
|
.evaluatePermanentList(humanlist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import forge.CardPredicates;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -69,9 +69,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
|
|
||||||
if (CardLists.getNotType(tapList, "Creature").size() == 0) {
|
if (CardLists.getNotType(tapList, "Creature").size() == 0) {
|
||||||
// if only creatures take the best
|
// if only creatures take the best
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(tapList);
|
choice = ComputerUtilCard.getBestCreatureAI(tapList);
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
@@ -179,9 +179,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
Predicate<Card> findBlockers = CardPredicates.possibleBlockerForAtLeastOne(attackers);
|
Predicate<Card> findBlockers = CardPredicates.possibleBlockerForAtLeastOne(attackers);
|
||||||
List<Card> creatureList = CardLists.filter(tapList, findBlockers);
|
List<Card> creatureList = CardLists.filter(tapList, findBlockers);
|
||||||
if (!attackers.isEmpty() && !creatureList.isEmpty()) {
|
if (!attackers.isEmpty() && !creatureList.isEmpty()) {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(creatureList);
|
choice = ComputerUtilCard.getBestCreatureAI(creatureList);
|
||||||
} else if (sa.isTrigger()) {
|
} else if (sa.isTrigger()) {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (phase.isPlayerTurn(opp)
|
} else if (phase.isPlayerTurn(opp)
|
||||||
@@ -194,12 +194,12 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
return c.isCreature() && CombatUtil.canAttack(c, opp);
|
return c.isCreature() && CombatUtil.canAttack(c, opp);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(creatureList);
|
choice = ComputerUtilCard.getBestCreatureAI(creatureList);
|
||||||
} else { // no creatures available
|
} else { // no creatures available
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import forge.Card;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
@@ -84,7 +84,7 @@ public class UnattachAllAi extends SpellAbilityAi {
|
|||||||
//don't equip a worse creature
|
//don't equip a worse creature
|
||||||
if (card.isEquipping()) {
|
if (card.isEquipping()) {
|
||||||
Card oldTarget = card.getEquipping().get(0);
|
Card oldTarget = card.getEquipping().get(0);
|
||||||
if (CardFactoryUtil.evaluateCreature(oldTarget) > CardFactoryUtil.evaluateCreature(newTarget)) {
|
if (ComputerUtilCard.evaluateCreature(oldTarget) > ComputerUtilCard.evaluateCreature(newTarget)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import forge.Singletons;
|
|||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -148,14 +148,14 @@ public class UntapAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CardLists.getNotType(untapList, "Creature").size() == 0) {
|
if (CardLists.getNotType(untapList, "Creature").size() == 0) {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(untapList); // if
|
choice = ComputerUtilCard.getBestCreatureAI(untapList); // if
|
||||||
// only
|
// only
|
||||||
// creatures
|
// creatures
|
||||||
// take
|
// take
|
||||||
// the
|
// the
|
||||||
// best
|
// best
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(untapList, sa, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(untapList, sa, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
@@ -267,13 +267,13 @@ public class UntapAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CardLists.getNotType(tapList, "Creature").size() == 0) {
|
if (CardLists.getNotType(tapList, "Creature").size() == 0) {
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(tapList); // if only
|
choice = ComputerUtilCard.getBestCreatureAI(tapList); // if only
|
||||||
// creatures
|
// creatures
|
||||||
// take
|
// take
|
||||||
// the
|
// the
|
||||||
// best
|
// best
|
||||||
} else {
|
} else {
|
||||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choice == null) { // can't find anything left
|
if (choice == null) { // can't find anything left
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import forge.Singletons;
|
|||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.ability.ai.ChangeZoneAi;
|
import forge.card.ability.ai.ChangeZoneAi;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.AbilitySub;
|
import forge.card.spellability.AbilitySub;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.SpellAbilityStackInstance;
|
import forge.card.spellability.SpellAbilityStackInstance;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.Zone;
|
import forge.game.zone.Zone;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -403,7 +403,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
attachedTo = list.get(0);
|
attachedTo = list.get(0);
|
||||||
}
|
}
|
||||||
} else { // AI player
|
} else { // AI player
|
||||||
attachedTo = CardFactoryUtil.getBestAI(list);
|
attachedTo = ComputerUtilCard.getBestAI(list);
|
||||||
}
|
}
|
||||||
if (tgtC.isAura()) {
|
if (tgtC.isAura()) {
|
||||||
if (tgtC.isEnchanting()) {
|
if (tgtC.isEnchanting()) {
|
||||||
|
|||||||
@@ -74,53 +74,20 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
|||||||
for (final Player p : tgtPlayers) {
|
for (final Player p : tgtPlayers) {
|
||||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||||
for (int i = 0; i < validAmount; i++) {
|
for (int i = 0; i < validAmount; i++) {
|
||||||
if (p.isHuman()) {
|
|
||||||
final String choiceTitle = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ";
|
Card c;
|
||||||
Card o;
|
|
||||||
if (sa.hasParam("AtRandom")) {
|
if (sa.hasParam("AtRandom")) {
|
||||||
o = Aggregates.random(choices);
|
c = Aggregates.random(choices);
|
||||||
} else if (sa.hasParam("Mandatory")) {
|
|
||||||
o = GuiChoose.one(choiceTitle, choices);
|
|
||||||
} else {
|
} else {
|
||||||
o = GuiChoose.oneOrNone(choiceTitle, choices);
|
c = p.getController().chooseSingleCardForEffect(choices, sa, sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ", !sa.hasParam("Mandatory"));
|
||||||
}
|
}
|
||||||
if (o != null) {
|
|
||||||
chosen.add(o);
|
if (c != null) {
|
||||||
choices.remove(o);
|
chosen.add(c);
|
||||||
|
choices.remove(c);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else { // Computer
|
|
||||||
String logic = sa.getParam("AILogic");
|
|
||||||
Card choice = null;
|
|
||||||
if (logic == null) {
|
|
||||||
// Base Logic is choose "best"
|
|
||||||
choice = CardFactoryUtil.getBestAI(choices);
|
|
||||||
} else if ("WorstCard".equals(logic)) {
|
|
||||||
choice = CardFactoryUtil.getWorstAI(choices);
|
|
||||||
} else if (logic.equals("BestBlocker")) {
|
|
||||||
if (!CardLists.filter(choices, Presets.UNTAPPED).isEmpty()) {
|
|
||||||
choices = CardLists.filter(choices, Presets.UNTAPPED);
|
|
||||||
}
|
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(choices);
|
|
||||||
} else if (logic.equals("Clone")) {
|
|
||||||
if (!CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
|
||||||
choices = CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
|
||||||
}
|
|
||||||
choice = CardFactoryUtil.getBestAI(choices);
|
|
||||||
} else if (logic.equals("Untap")) {
|
|
||||||
if (!CardLists.getValidCards(choices, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host).isEmpty()) {
|
|
||||||
choices = CardLists.getValidCards(choices, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host);
|
|
||||||
}
|
|
||||||
choice = CardFactoryUtil.getBestAI(choices);
|
|
||||||
}
|
|
||||||
if (choice != null) {
|
|
||||||
chosen.add(choice);
|
|
||||||
choices.remove(choice);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
host.setChosenCard(chosen);
|
host.setChosenCard(chosen);
|
||||||
if (sa.hasParam("RememberChosen")) {
|
if (sa.hasParam("RememberChosen")) {
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import forge.Singletons;
|
|||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.card.CardRulesPredicates;
|
import forge.card.CardRulesPredicates;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -90,9 +90,9 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("AILogic")) {
|
if (sa.hasParam("AILogic")) {
|
||||||
final String logic = sa.getParam("AILogic");
|
final String logic = sa.getParam("AILogic");
|
||||||
if (logic.equals("MostProminentInComputerDeck")) {
|
if (logic.equals("MostProminentInComputerDeck")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCardName(p.getCardsIn(ZoneType.Library));
|
chosen = ComputerUtilCard.getMostProminentCardName(p.getCardsIn(ZoneType.Library));
|
||||||
} else if (logic.equals("MostProminentInHumanDeck")) {
|
} else if (logic.equals("MostProminentInHumanDeck")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCardName(p.getOpponent().getCardsIn(ZoneType.Library));
|
chosen = ComputerUtilCard.getMostProminentCardName(p.getOpponent().getCardsIn(ZoneType.Library));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<Card> list = CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), p.getOpponent());
|
List<Card> list = CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), p.getOpponent());
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import forge.CardPredicates;
|
|||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -69,36 +69,36 @@ public class ChooseColorEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("AILogic")) {
|
if (sa.hasParam("AILogic")) {
|
||||||
final String logic = sa.getParam("AILogic");
|
final String logic = sa.getParam("AILogic");
|
||||||
if (logic.equals("MostProminentInHumanDeck")) {
|
if (logic.equals("MostProminentInHumanDeck")) {
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp)));
|
chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp)));
|
||||||
} else if (logic.equals("MostProminentInComputerDeck")) {
|
} else if (logic.equals("MostProminentInComputerDeck")) {
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai)));
|
chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai)));
|
||||||
} else if (logic.equals("MostProminentDualInComputerDeck")) {
|
} else if (logic.equals("MostProminentDualInComputerDeck")) {
|
||||||
List<String> prominence = CardFactoryUtil.getColorByProminence(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
List<String> prominence = ComputerUtilCard.getColorByProminence(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
||||||
chosen.add(prominence.get(0));
|
chosen.add(prominence.get(0));
|
||||||
chosen.add(prominence.get(1));
|
chosen.add(prominence.get(1));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentInGame")) {
|
else if (logic.equals("MostProminentInGame")) {
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(Singletons.getModel().getGame().getCardsInGame()));
|
chosen.add(ComputerUtilCard.getMostProminentColor(Singletons.getModel().getGame().getCardsInGame()));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentHumanCreatures")) {
|
else if (logic.equals("MostProminentHumanCreatures")) {
|
||||||
List<Card> list = opp.getCreaturesInPlay();
|
List<Card> list = opp.getCreaturesInPlay();
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
list = CardLists.filter(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp), CardPredicates.Presets.CREATURES);
|
list = CardLists.filter(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp), CardPredicates.Presets.CREATURES);
|
||||||
}
|
}
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(list));
|
chosen.add(ComputerUtilCard.getMostProminentColor(list));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentComputerControls")) {
|
else if (logic.equals("MostProminentComputerControls")) {
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield)));
|
chosen.add(ComputerUtilCard.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield)));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentHumanControls")) {
|
else if (logic.equals("MostProminentHumanControls")) {
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(ai.getOpponent().getCardsIn(ZoneType.Battlefield)));
|
chosen.add(ComputerUtilCard.getMostProminentColor(ai.getOpponent().getCardsIn(ZoneType.Battlefield)));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentPermanent")) {
|
else if (logic.equals("MostProminentPermanent")) {
|
||||||
final List<Card> list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
final List<Card> list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(list));
|
chosen.add(ComputerUtilCard.getMostProminentColor(list));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentAttackers")) {
|
else if (logic.equals("MostProminentAttackers")) {
|
||||||
chosen.add(CardFactoryUtil.getMostProminentColor(Singletons.getModel().getGame().getCombat()
|
chosen.add(ComputerUtilCard.getMostProminentColor(Singletons.getModel().getGame().getCombat()
|
||||||
.getAttackerList()));
|
.getAttackerList()));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentKeywordInComputerDeck")) {
|
else if (logic.equals("MostProminentKeywordInComputerDeck")) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import forge.card.cardfactory.CardFactoryUtil;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.SpellAbilityStackInstance;
|
import forge.card.spellability.SpellAbilityStackInstance;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -181,10 +182,10 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
|
|||||||
return ComputerUtilCombat.damageIfUnblocked(c, ai, Singletons.getModel().getGame().getCombat()) > 0;
|
return ComputerUtilCombat.damageIfUnblocked(c, ai, Singletons.getModel().getGame().getCombat()) > 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
chosen.add(CardFactoryUtil.getBestCreatureAI(sourcesToChooseFrom));
|
chosen.add(ComputerUtilCard.getBestCreatureAI(sourcesToChooseFrom));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chosen.add(CardFactoryUtil.getBestAI(sourcesToChooseFrom));
|
chosen.add(ComputerUtilCard.getBestAI(sourcesToChooseFrom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ import forge.Constant;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -103,22 +103,22 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("AILogic")) {
|
if (sa.hasParam("AILogic")) {
|
||||||
final String logic = sa.getParam("AILogic");
|
final String logic = sa.getParam("AILogic");
|
||||||
if (logic.equals("MostProminentOnBattlefield")) {
|
if (logic.equals("MostProminentOnBattlefield")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCreatureType(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield));
|
chosen = ComputerUtilCard.getMostProminentCreatureType(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentComputerControls")) {
|
else if (logic.equals("MostProminentComputerControls")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentHumanControls")) {
|
else if (logic.equals("MostProminentHumanControls")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
chosen = ComputerUtilCard.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
||||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp));
|
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentInComputerDeck")) {
|
else if (logic.equals("MostProminentInComputerDeck")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
||||||
}
|
}
|
||||||
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.PlayerZone;
|
import forge.game.zone.PlayerZone;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -195,9 +195,9 @@ public class DigEffect extends SpellAbilityEffect {
|
|||||||
chosen = GuiChoose.one(prompt + destZone2, valid);
|
chosen = GuiChoose.one(prompt + destZone2, valid);
|
||||||
movedCards.remove(chosen);
|
movedCards.remove(chosen);
|
||||||
} else { // Computer
|
} else { // Computer
|
||||||
Card chosen = CardFactoryUtil.getBestAI(valid);
|
Card chosen = ComputerUtilCard.getBestAI(valid);
|
||||||
if (sa.getActivatingPlayer().isHuman() && p.isHuman()) {
|
if (sa.getActivatingPlayer().isHuman() && p.isHuman()) {
|
||||||
chosen = CardFactoryUtil.getWorstAI(valid);
|
chosen = ComputerUtilCard.getWorstAI(valid);
|
||||||
}
|
}
|
||||||
movedCards.remove(chosen);
|
movedCards.remove(chosen);
|
||||||
}
|
}
|
||||||
@@ -250,9 +250,9 @@ public class DigEffect extends SpellAbilityEffect {
|
|||||||
changeNum = valid.size(); // always take all
|
changeNum = valid.size(); // always take all
|
||||||
}
|
}
|
||||||
for (j = 0; j < changeNum; j++) {
|
for (j = 0; j < changeNum; j++) {
|
||||||
Card chosen = CardFactoryUtil.getBestAI(valid);
|
Card chosen = ComputerUtilCard.getBestAI(valid);
|
||||||
if (sa.getActivatingPlayer().isHuman() && p.isHuman()) {
|
if (sa.getActivatingPlayer().isHuman() && p.isHuman()) {
|
||||||
chosen = CardFactoryUtil.getWorstAI(valid);
|
chosen = ComputerUtilCard.getWorstAI(valid);
|
||||||
}
|
}
|
||||||
if (chosen == null) {
|
if (chosen == null) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import forge.card.ability.AbilityUtils;
|
|||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -109,9 +110,9 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
if (sa.hasParam("DiscardValid")) {
|
if (sa.hasParam("DiscardValid")) {
|
||||||
final String validString = sa.getParam("DiscardValid");
|
final String validString = sa.getParam("DiscardValid");
|
||||||
if (validString.contains("Creature") && !validString.contains("nonCreature")) {
|
if (validString.contains("Creature") && !validString.contains("nonCreature")) {
|
||||||
final Card c = CardFactoryUtil.getBestCreatureAI(goodChoices);
|
final Card c = ComputerUtilCard.getBestCreatureAI(goodChoices);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
dChoices.add(CardFactoryUtil.getBestCreatureAI(goodChoices));
|
dChoices.add(ComputerUtilCard.getBestCreatureAI(goodChoices));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,12 @@ import java.util.List;
|
|||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.CardPredicates.Presets;
|
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.trigger.Trigger;
|
import forge.card.trigger.Trigger;
|
||||||
import forge.card.trigger.TriggerHandler;
|
import forge.card.trigger.TriggerHandler;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.gui.GuiDialog;
|
|
||||||
|
|
||||||
public class EncodeEffect extends SpellAbilityEffect {
|
public class EncodeEffect extends SpellAbilityEffect {
|
||||||
@Override
|
@Override
|
||||||
@@ -43,10 +39,11 @@ public class EncodeEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
}
|
}
|
||||||
// Handle choice of whether or not to encoded
|
// Handle choice of whether or not to encoded
|
||||||
|
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("Do you want to exile " + host + " and encode it onto a creature you control?");
|
sb.append("Do you want to exile " + host + " and encode it onto a creature you control?");
|
||||||
if (player.isHuman()
|
if (!player.getController().confirmAction(sa, null, sb.toString())) {
|
||||||
&& !GuiDialog.confirm(host, sb.toString())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Note: AI will always choose to encode
|
// Note: AI will always choose to encode
|
||||||
@@ -56,31 +53,8 @@ public class EncodeEffect extends SpellAbilityEffect {
|
|||||||
Card movedCard = Singletons.getModel().getGame().getAction().moveTo(ZoneType.Exile, host);
|
Card movedCard = Singletons.getModel().getGame().getAction().moveTo(ZoneType.Exile, host);
|
||||||
|
|
||||||
// choose a creature
|
// choose a creature
|
||||||
Card choice = null;
|
Card choice = player.getController().chooseSingleCardForEffect(choices, sa, "Choose a creature you control to encode ", true);
|
||||||
if (player.isHuman()) {
|
|
||||||
final String choiceTitle = "Choose a creature you control to encode ";
|
|
||||||
choice = GuiChoose.oneOrNone(choiceTitle, choices);
|
|
||||||
}
|
|
||||||
else { // Computer
|
|
||||||
// TODO: move this to AI method
|
|
||||||
String logic = sa.getParam("AILogic");
|
|
||||||
if (logic == null) {
|
|
||||||
// Base Logic is choose "best"
|
|
||||||
choice = CardFactoryUtil.getBestAI(choices);
|
|
||||||
} else if ("WorstCard".equals(logic)) {
|
|
||||||
choice = CardFactoryUtil.getWorstAI(choices);
|
|
||||||
} else if (logic.equals("BestBlocker")) {
|
|
||||||
if (!CardLists.filter(choices, Presets.UNTAPPED).isEmpty()) {
|
|
||||||
choices = CardLists.filter(choices, Presets.UNTAPPED);
|
|
||||||
}
|
|
||||||
choice = CardFactoryUtil.getBestCreatureAI(choices);
|
|
||||||
} else if (logic.equals("Clone")) {
|
|
||||||
if (!CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
|
||||||
choices = CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
|
||||||
}
|
|
||||||
choice = CardFactoryUtil.getBestAI(choices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (choice == null) {
|
if (choice == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import forge.Singletons;
|
|||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.AbilityManaPart;
|
import forge.card.spellability.AbilityManaPart;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -82,7 +82,7 @@ public class ManaEffect extends SpellAbilityEffect {
|
|||||||
final String logic = sa.getParam("AILogic");
|
final String logic = sa.getParam("AILogic");
|
||||||
String chosen = Constant.Color.BLACK;
|
String chosen = Constant.Color.BLACK;
|
||||||
if (logic.equals("MostProminentInComputerHand")) {
|
if (logic.equals("MostProminentInComputerHand")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentColor(activator.getCardsIn(
|
chosen = ComputerUtilCard.getMostProminentColor(activator.getCardsIn(
|
||||||
ZoneType.Hand));
|
ZoneType.Hand));
|
||||||
}
|
}
|
||||||
if (chosen.equals("")) {
|
if (chosen.equals("")) {
|
||||||
@@ -141,7 +141,7 @@ public class ManaEffect extends SpellAbilityEffect {
|
|||||||
final String logic = sa.getParam("AILogic");
|
final String logic = sa.getParam("AILogic");
|
||||||
String chosen = Constant.Color.BLACK;
|
String chosen = Constant.Color.BLACK;
|
||||||
if (logic.equals("MostProminentInComputerHand")) {
|
if (logic.equals("MostProminentInComputerHand")) {
|
||||||
chosen = CardFactoryUtil.getMostProminentColor(act.getCardsIn(ZoneType.Hand));
|
chosen = ComputerUtilCard.getMostProminentColor(act.getCardsIn(ZoneType.Hand));
|
||||||
}
|
}
|
||||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
||||||
abMana.setExpressChoice(MagicColor.toShortString(chosen));
|
abMana.setExpressChoice(MagicColor.toShortString(chosen));
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import forge.CardLists;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.cost.CostPartMana;
|
import forge.card.cost.CostPartMana;
|
||||||
import forge.card.cost.CostPart;
|
import forge.card.cost.CostPart;
|
||||||
@@ -23,6 +22,7 @@ import forge.card.spellability.SpellAbility;
|
|||||||
import forge.card.spellability.SpellAbilityRestriction;
|
import forge.card.spellability.SpellAbilityRestriction;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -126,7 +126,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tgtCard = CardFactoryUtil.getBestAI(tgtCards);
|
tgtCard = ComputerUtilCard.getBestAI(tgtCards);
|
||||||
if (tgtCard == null) {
|
if (tgtCard == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ import forge.Command;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ public class ProtectEffect extends SpellAbilityEffect {
|
|||||||
list = CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai.getOpponents());
|
list = CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai.getOpponents());
|
||||||
}
|
}
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
choice = CardFactoryUtil.getMostProminentColor(list);
|
choice = ComputerUtilCard.getMostProminentColor(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import forge.CardLists;
|
|||||||
import forge.card.ability.AbilityFactory;
|
import forge.card.ability.AbilityFactory;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.AbilitySub;
|
import forge.card.spellability.AbilitySub;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -221,11 +221,11 @@ public class TwoPilesEffect extends SpellAbilityEffect {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int cmc1 = CardFactoryUtil.evaluatePermanentList(new ArrayList<Card>(pile1));
|
int cmc1 = ComputerUtilCard.evaluatePermanentList(new ArrayList<Card>(pile1));
|
||||||
int cmc2 = CardFactoryUtil.evaluatePermanentList(new ArrayList<Card>(pile2));
|
int cmc2 = ComputerUtilCard.evaluatePermanentList(new ArrayList<Card>(pile2));
|
||||||
if (CardLists.getNotType(pool, "Creature").isEmpty()) {
|
if (CardLists.getNotType(pool, "Creature").isEmpty()) {
|
||||||
cmc1 = CardFactoryUtil.evaluateCreatureList(new ArrayList<Card>(pile1));
|
cmc1 = ComputerUtilCard.evaluateCreatureList(new ArrayList<Card>(pile1));
|
||||||
cmc2 = CardFactoryUtil.evaluateCreatureList(new ArrayList<Card>(pile2));
|
cmc2 = ComputerUtilCard.evaluateCreatureList(new ArrayList<Card>(pile2));
|
||||||
System.out.println("value:" + cmc1 + " " + cmc2);
|
System.out.println("value:" + cmc1 + " " + cmc2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import forge.card.ability.SpellAbilityEffect;
|
|||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
@@ -86,7 +87,7 @@ public class UntapEffect extends SpellAbilityEffect {
|
|||||||
while ((list.size() != 0) && (count < num)) {
|
while ((list.size() != 0) && (count < num)) {
|
||||||
for (int i = 0; (i < list.size()) && (count < num); i++) {
|
for (int i = 0; (i < list.size()) && (count < num); i++) {
|
||||||
|
|
||||||
final Card c = CardFactoryUtil.getBestLandAI(list);
|
final Card c = ComputerUtilCard.getBestLandAI(list);
|
||||||
c.untap();
|
c.untap();
|
||||||
list.remove(c);
|
list.remove(c);
|
||||||
count++;
|
count++;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import forge.card.trigger.Trigger;
|
|||||||
import forge.card.trigger.TriggerHandler;
|
import forge.card.trigger.TriggerHandler;
|
||||||
import forge.control.input.Input;
|
import forge.control.input.Input;
|
||||||
import forge.control.input.InputSelectManyCards;
|
import forge.control.input.InputSelectManyCards;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.PlayerZone;
|
import forge.game.zone.PlayerZone;
|
||||||
@@ -190,7 +191,7 @@ public class CardFactoryCreatures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.getTarget().resetTargets();
|
this.getTarget().resetTargets();
|
||||||
this.setTargetCard(CardFactoryUtil.getBestCreatureAI(targetables));
|
this.setTargetCard(ComputerUtilCard.getBestCreatureAI(targetables));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -262,7 +263,7 @@ public class CardFactoryCreatures {
|
|||||||
|
|
||||||
// Kill Wolves that can be killed first
|
// Kill Wolves that can be killed first
|
||||||
if (wolvesLeft.size() > 0) {
|
if (wolvesLeft.size() > 0) {
|
||||||
final Card best = CardFactoryUtil.getBestCreatureAI(wolvesLeft);
|
final Card best = ComputerUtilCard.getBestCreatureAI(wolvesLeft);
|
||||||
best.addDamage(1, target);
|
best.addDamage(1, target);
|
||||||
if ((ComputerUtilCombat.getDamageToKill(best) <= 0) || target.hasKeyword("Deathtouch")) {
|
if ((ComputerUtilCombat.getDamageToKill(best) <= 0) || target.hasKeyword("Deathtouch")) {
|
||||||
wolvesLeft.remove(best);
|
wolvesLeft.remove(best);
|
||||||
|
|||||||
@@ -18,17 +18,12 @@
|
|||||||
package forge.card.cardfactory;
|
package forge.card.cardfactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
@@ -45,7 +40,6 @@ import forge.CounterType;
|
|||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.CardCharacteristics;
|
import forge.card.CardCharacteristics;
|
||||||
import forge.card.CardType;
|
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.ability.AbilityFactory;
|
import forge.card.ability.AbilityFactory;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
@@ -71,8 +65,8 @@ import forge.card.trigger.TriggerHandler;
|
|||||||
import forge.card.trigger.TriggerType;
|
import forge.card.trigger.TriggerType;
|
||||||
import forge.control.input.Input;
|
import forge.control.input.Input;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.AiAttackController;
|
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.event.TokenCreatedEvent;
|
import forge.game.event.TokenCreatedEvent;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
@@ -85,7 +79,6 @@ import forge.game.zone.ZoneType;
|
|||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
import forge.gui.match.CMatchUI;
|
import forge.gui.match.CMatchUI;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.MyRandom;
|
|
||||||
|
|
||||||
import forge.view.ButtonUtil;
|
import forge.view.ButtonUtil;
|
||||||
|
|
||||||
@@ -98,659 +91,6 @@ import forge.view.ButtonUtil;
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class CardFactoryUtil {
|
public class CardFactoryUtil {
|
||||||
private static Random random = MyRandom.getRandom();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getMostExpensivePermanentAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @param spell
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @param targeted
|
|
||||||
* a boolean.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getMostExpensivePermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
|
||||||
List<Card> all = list;
|
|
||||||
if (targeted) {
|
|
||||||
all = CardLists.filter(all, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.canBeTargetedBy(spell);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardFactoryUtil.getMostExpensivePermanentAI(all);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getMostExpensivePermanentAI.
|
|
||||||
*
|
|
||||||
* @param all
|
|
||||||
* the all
|
|
||||||
* @return the card
|
|
||||||
*/
|
|
||||||
public static Card getMostExpensivePermanentAI(final List<Card> all) {
|
|
||||||
if (all.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Card biggest = null;
|
|
||||||
biggest = all.get(0);
|
|
||||||
|
|
||||||
int bigCMC = 0;
|
|
||||||
for (int i = 0; i < all.size(); i++) {
|
|
||||||
final Card card = all.get(i);
|
|
||||||
int curCMC = card.getCMC();
|
|
||||||
|
|
||||||
// Add all cost of all auras with the same controller
|
|
||||||
final List<Card> auras = CardLists.filterControlledBy(card.getEnchantedBy(), card.getController());
|
|
||||||
curCMC += Aggregates.sum(auras, CardPredicates.Accessors.fnGetCmc) + auras.size();
|
|
||||||
|
|
||||||
if (curCMC >= bigCMC) {
|
|
||||||
bigCMC = curCMC;
|
|
||||||
biggest = all.get(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return biggest;
|
|
||||||
}
|
|
||||||
|
|
||||||
// for Sarkhan the Mad
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getCheapestCreatureAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @param spell
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @param targeted
|
|
||||||
* a boolean.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getCheapestCreatureAI(List<Card> list, final SpellAbility spell, final boolean targeted) {
|
|
||||||
list = CardLists.filter(list, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.isCreature();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return CardFactoryUtil.getCheapestPermanentAI(list, spell, targeted);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getCheapestPermanentAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @param spell
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @param targeted
|
|
||||||
* a boolean.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getCheapestPermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
|
||||||
List<Card> all = list;
|
|
||||||
if (targeted) {
|
|
||||||
all = CardLists.filter(all, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.canBeTargetedBy(spell);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (all.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get cheapest card:
|
|
||||||
Card cheapest = null;
|
|
||||||
cheapest = all.get(0);
|
|
||||||
|
|
||||||
for (int i = 0; i < all.size(); i++) {
|
|
||||||
if (cheapest.getManaCost().getCMC() <= cheapest.getManaCost().getCMC()) {
|
|
||||||
cheapest = all.get(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cheapest;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getBestLandAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getBestLandAI(final List<Card> list) {
|
|
||||||
final List<Card> land = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
|
||||||
if (!(land.size() > 0)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prefer to target non basic lands
|
|
||||||
final List<Card> nbLand = CardLists.filter(land, Predicates.not(CardPredicates.Presets.BASIC_LANDS));
|
|
||||||
|
|
||||||
if (nbLand.size() > 0) {
|
|
||||||
// TODO - Rank non basics?
|
|
||||||
return Aggregates.random(nbLand);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no non-basic lands, target the least represented basic land type
|
|
||||||
String sminBL = "";
|
|
||||||
int iminBL = 20000; // hopefully no one will ever have more than 20000
|
|
||||||
// lands of one type....
|
|
||||||
int n = 0;
|
|
||||||
for (String name : Constant.Color.BASIC_LANDS) {
|
|
||||||
n = CardLists.getType(land, name).size();
|
|
||||||
if ((n < iminBL) && (n > 0)) {
|
|
||||||
// if two or more are tied, only the
|
|
||||||
// first
|
|
||||||
// one checked will be used
|
|
||||||
iminBL = n;
|
|
||||||
sminBL = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (iminBL == 20000) {
|
|
||||||
return null; // no basic land was a minimum
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Card> bLand = CardLists.getType(land, sminBL);
|
|
||||||
|
|
||||||
for (Card ut : Iterables.filter(bLand, CardPredicates.Presets.UNTAPPED)) {
|
|
||||||
return ut;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return Aggregates.random(bLand); // random tapped land of least represented type
|
|
||||||
}
|
|
||||||
|
|
||||||
// The AI doesn't really pick the best enchantment, just the most expensive.
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getBestEnchantmentAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @param spell
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @param targeted
|
|
||||||
* a boolean.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getBestEnchantmentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
|
||||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS);
|
|
||||||
if (targeted) {
|
|
||||||
all = CardLists.filter(all, new Predicate<Card>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.canBeTargetedBy(spell);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// get biggest Enchantment
|
|
||||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The AI doesn't really pick the best artifact, just the most expensive.
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getBestArtifactAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getBestArtifactAI(final List<Card> list) {
|
|
||||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ARTIFACTS);
|
|
||||||
if (all.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// get biggest Artifact
|
|
||||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* doesCreatureAttackAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param ai
|
|
||||||
* the AI player
|
|
||||||
* @param card
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public static boolean doesCreatureAttackAI(final Player ai, final Card card) {
|
|
||||||
final List<Card> att = new AiAttackController(ai, ai.getOpponent()).getAttackers().getAttackers();
|
|
||||||
|
|
||||||
return att.contains(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* evaluateCreatureList.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a int.
|
|
||||||
*/
|
|
||||||
public static int evaluateCreatureList(final List<Card> list) {
|
|
||||||
int value = 0;
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
value += CardFactoryUtil.evaluateCreature(list.get(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* evaluatePermanentList.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a int.
|
|
||||||
*/
|
|
||||||
public static int evaluatePermanentList(final List<Card> list) {
|
|
||||||
int value = 0;
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
value += list.get(i).getCMC() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* evaluateCreature.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param c
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @return a int.
|
|
||||||
*/
|
|
||||||
public static int evaluateCreature(final Card c) {
|
|
||||||
|
|
||||||
int value = 100;
|
|
||||||
if (c.isToken()) {
|
|
||||||
value = 80; // tokens should be worth less than actual cards
|
|
||||||
}
|
|
||||||
int power = c.getNetCombatDamage();
|
|
||||||
final int toughness = c.getNetDefense();
|
|
||||||
for (String keyword : c.getKeyword()) {
|
|
||||||
if (keyword.equals("Prevent all combat damage that would be dealt by CARDNAME.")
|
|
||||||
|| keyword.equals("Prevent all damage that would be dealt by CARDNAME.")
|
|
||||||
|| keyword.equals("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")
|
|
||||||
|| keyword.equals("Prevent all damage that would be dealt to and dealt by CARDNAME.")) {
|
|
||||||
power = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value += power * 15;
|
|
||||||
value += toughness * 10;
|
|
||||||
value += c.getCMC() * 5;
|
|
||||||
|
|
||||||
// Evasion keywords
|
|
||||||
if (c.hasKeyword("Flying")) {
|
|
||||||
value += power * 10;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Horsemanship")) {
|
|
||||||
value += power * 10;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Unblockable")) {
|
|
||||||
value += power * 10;
|
|
||||||
} else {
|
|
||||||
if (c.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
|
||||||
value += power * 6;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Fear")) {
|
|
||||||
value += power * 6;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Intimidate")) {
|
|
||||||
value += power * 6;
|
|
||||||
}
|
|
||||||
if (c.hasStartOfKeyword("CARDNAME can't be blocked except by")) {
|
|
||||||
value += power * 5;
|
|
||||||
}
|
|
||||||
if (c.hasStartOfKeyword("CARDNAME can't be blocked by")) {
|
|
||||||
value += power * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other good keywords
|
|
||||||
if (power > 0) {
|
|
||||||
if (c.hasKeyword("Double Strike")) {
|
|
||||||
value += 10 + (power * 15);
|
|
||||||
} else if (c.hasKeyword("First Strike")) {
|
|
||||||
value += 10 + (power * 5);
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Deathtouch")) {
|
|
||||||
value += 25;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Lifelink")) {
|
|
||||||
value += power * 10;
|
|
||||||
}
|
|
||||||
if (power > 1 && c.hasKeyword("Trample")) {
|
|
||||||
value += (power - 1) * 5;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Vigilance")) {
|
|
||||||
value += (power * 5) + (toughness * 5);
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Wither")) {
|
|
||||||
value += power * 10;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Infect")) {
|
|
||||||
value += power * 15;
|
|
||||||
}
|
|
||||||
value += c.getKeywordMagnitude("Rampage");
|
|
||||||
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
|
||||||
+ "put into a graveyard, put a +1/+1 counter on CARDNAME.")) {
|
|
||||||
value += 2;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
|
||||||
+ "put into a graveyard, put a +2/+2 counter on CARDNAME.")) {
|
|
||||||
value += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value += c.getKeywordMagnitude("Bushido") * 16;
|
|
||||||
value += c.getAmountOfKeyword("Flanking") * 15;
|
|
||||||
value += c.getAmountOfKeyword("Exalted") * 15;
|
|
||||||
value += c.getKeywordMagnitude("Annihilator") * 50;
|
|
||||||
|
|
||||||
|
|
||||||
// Defensive Keywords
|
|
||||||
if (c.hasKeyword("Reach") && !c.hasKeyword("Flying")) {
|
|
||||||
value += 5;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("CARDNAME can block creatures with shadow as though they didn't have shadow.")) {
|
|
||||||
value += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protection
|
|
||||||
if (c.hasKeyword("Indestructible")) {
|
|
||||||
value += 70;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Prevent all damage that would be dealt to CARDNAME.")) {
|
|
||||||
value += 60;
|
|
||||||
} else if (c.hasKeyword("Prevent all combat damage that would be dealt to CARDNAME.")) {
|
|
||||||
value += 50;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("Hexproof")) {
|
|
||||||
value += 35;
|
|
||||||
} else if (c.hasKeyword("Shroud")) {
|
|
||||||
value += 30;
|
|
||||||
}
|
|
||||||
if (c.hasStartOfKeyword("Protection")) {
|
|
||||||
value += 20;
|
|
||||||
}
|
|
||||||
if (c.hasStartOfKeyword("PreventAllDamageBy")) {
|
|
||||||
value += 10;
|
|
||||||
}
|
|
||||||
value += c.getKeywordMagnitude("Absorb") * 11;
|
|
||||||
|
|
||||||
// Bad keywords
|
|
||||||
if (c.hasKeyword("Defender") || c.hasKeyword("CARDNAME can't attack.")) {
|
|
||||||
value -= (power * 9) + 40;
|
|
||||||
} else if (c.getSVar("SacrificeEndCombat").equals("True")) {
|
|
||||||
value -= 40;
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("CARDNAME can't block.")) {
|
|
||||||
value -= 10;
|
|
||||||
} else if (c.hasKeyword("CARDNAME attacks each turn if able.")) {
|
|
||||||
value -= 10;
|
|
||||||
} else if (c.hasKeyword("CARDNAME can block only creatures with flying.")) {
|
|
||||||
value -= toughness * 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.hasStartOfKeyword("When CARDNAME is dealt damage, destroy it.")) {
|
|
||||||
value -= (toughness - 1) * 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.hasKeyword("CARDNAME can't attack or block.")) {
|
|
||||||
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("CARDNAME doesn't untap during your untap step.")) {
|
|
||||||
if (c.isTapped()) {
|
|
||||||
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
|
||||||
} else {
|
|
||||||
value -= 50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c.hasKeyword("At the beginning of the end step, destroy CARDNAME.")
|
|
||||||
|| c.hasKeyword("At the beginning of the end step, exile CARDNAME.")
|
|
||||||
|| c.hasKeyword("At the beginning of the end step, sacrifice CARDNAME.")) {
|
|
||||||
value -= 50;
|
|
||||||
} else if (c.hasStartOfKeyword("Cumulative upkeep")) {
|
|
||||||
value -= 30;
|
|
||||||
} else if (c.hasStartOfKeyword("At the beginning of your upkeep, destroy CARDNAME unless you pay")
|
|
||||||
|| c.hasStartOfKeyword("At the beginning of your upkeep, sacrifice CARDNAME unless you pay")
|
|
||||||
|| c.hasStartOfKeyword("Upkeep:")) {
|
|
||||||
value -= 20;
|
|
||||||
} else if (c.hasStartOfKeyword("(Echo unpaid)")) {
|
|
||||||
value -= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.hasStartOfKeyword("At the beginning of your upkeep, CARDNAME deals")) {
|
|
||||||
value -= 20;
|
|
||||||
}
|
|
||||||
if (c.hasStartOfKeyword("Fading")) {
|
|
||||||
value -= 20;
|
|
||||||
}
|
|
||||||
if (c.hasStartOfKeyword("Vanishing")) {
|
|
||||||
value -= 20;
|
|
||||||
}
|
|
||||||
if (c.getSVar("Targeting").equals("Dies")) {
|
|
||||||
value -= 25;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final SpellAbility sa : c.getSpellAbilities()) {
|
|
||||||
if (sa.isAbility()) {
|
|
||||||
value += 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!c.getManaAbility().isEmpty()) {
|
|
||||||
value += 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.isUntapped()) {
|
|
||||||
value += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// paired creatures are more valuable because they grant a bonus to the other creature
|
|
||||||
if (c.isPaired()) {
|
|
||||||
value += 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
|
|
||||||
} // evaluateCreature
|
|
||||||
|
|
||||||
// returns null if list.size() == 0
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getBestAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getBestAI(final List<Card> list) {
|
|
||||||
// Get Best will filter by appropriate getBest list if ALL of the list
|
|
||||||
// is of that type
|
|
||||||
if (CardLists.getNotType(list, "Creature").size() == 0) {
|
|
||||||
return CardFactoryUtil.getBestCreatureAI(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CardLists.getNotType(list, "Land").size() == 0) {
|
|
||||||
return CardFactoryUtil.getBestLandAI(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO - Once we get an EvaluatePermanent this should call
|
|
||||||
// getBestPermanent()
|
|
||||||
return CardFactoryUtil.getMostExpensivePermanentAI(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getBestCreatureAI.
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* the list
|
|
||||||
* @return the card
|
|
||||||
*/
|
|
||||||
public static Card getBestCreatureAI(final List<Card> list) {
|
|
||||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
|
||||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnEvaluateCreature);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This selection rates tokens higher
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getBestCreatureToBounceAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getBestCreatureToBounceAI(final List<Card> list) {
|
|
||||||
final int tokenBonus = 40;
|
|
||||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
|
||||||
Card biggest = null; // returns null if list.size() == 0
|
|
||||||
int biggestvalue = 0;
|
|
||||||
int newvalue = 0;
|
|
||||||
|
|
||||||
if (all.size() != 0) {
|
|
||||||
biggest = all.get(0);
|
|
||||||
|
|
||||||
for (int i = 0; i < all.size(); i++) {
|
|
||||||
biggestvalue = CardFactoryUtil.evaluateCreature(biggest);
|
|
||||||
if (biggest.isToken()) {
|
|
||||||
biggestvalue += tokenBonus; // raise the value of tokens
|
|
||||||
}
|
|
||||||
newvalue = CardFactoryUtil.evaluateCreature(all.get(i));
|
|
||||||
if (all.get(i).isToken()) {
|
|
||||||
newvalue += tokenBonus; // raise the value of tokens
|
|
||||||
}
|
|
||||||
if (biggestvalue < newvalue) {
|
|
||||||
biggest = all.get(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return biggest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getWorstAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getWorstAI(final List<Card> list) {
|
|
||||||
return CardFactoryUtil.getWorstPermanentAI(list, false, false, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns null if list.size() == 0
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getWorstCreatureAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getWorstCreatureAI(final List<Card> list) {
|
|
||||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
|
||||||
// get smallest creature
|
|
||||||
return Aggregates.itemWithMin(all, CardPredicates.Accessors.fnEvaluateCreature);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getWorstPermanentAI.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @param biasEnch
|
|
||||||
* a boolean.
|
|
||||||
* @param biasLand
|
|
||||||
* a boolean.
|
|
||||||
* @param biasArt
|
|
||||||
* a boolean.
|
|
||||||
* @param biasCreature
|
|
||||||
* a boolean.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getWorstPermanentAI(final List<Card> list, final boolean biasEnch, final boolean biasLand,
|
|
||||||
final boolean biasArt, final boolean biasCreature) {
|
|
||||||
if (list.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (biasEnch && Iterables.any(list, CardPredicates.Presets.ENCHANTMENTS)) {
|
|
||||||
return CardFactoryUtil.getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS), null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (biasArt && Iterables.any(list, CardPredicates.Presets.ARTIFACTS)) {
|
|
||||||
return CardFactoryUtil.getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ARTIFACTS), null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (biasLand && Iterables.any(list, CardPredicates.Presets.LANDS)) {
|
|
||||||
return CardFactoryUtil.getWorstLand(CardLists.filter(list, CardPredicates.Presets.LANDS));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (biasCreature && Iterables.any(list, CardPredicates.Presets.CREATURES)) {
|
|
||||||
return CardFactoryUtil.getWorstCreatureAI(CardLists.filter(list, CardPredicates.Presets.CREATURES));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> lands = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
|
||||||
if (lands.size() > 6) {
|
|
||||||
return CardFactoryUtil.getWorstLand(lands);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((CardLists.getType(list, "Artifact").size() > 0) || (CardLists.getType(list, "Enchantment").size() > 0)) {
|
|
||||||
return CardFactoryUtil.getCheapestPermanentAI(CardLists.filter(list, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.isArtifact() || c.isEnchantment();
|
|
||||||
}
|
|
||||||
}), null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CardLists.getType(list, "Creature").size() > 0) {
|
|
||||||
return CardFactoryUtil.getWorstCreatureAI(CardLists.getType(list, "Creature"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Planeswalkers fall through to here, lands will fall through if there
|
|
||||||
// aren't very many
|
|
||||||
return CardFactoryUtil.getCheapestPermanentAI(list, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* inputDestroyNoRegeneration.
|
* inputDestroyNoRegeneration.
|
||||||
@@ -3027,91 +2367,6 @@ public class CardFactoryUtil {
|
|||||||
return untap;
|
return untap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getMostProminentCardName.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public static String getMostProminentCardName(final List<Card> list) {
|
|
||||||
|
|
||||||
if (list.size() == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
|
||||||
|
|
||||||
for (final Card c : list) {
|
|
||||||
final String name = c.getName();
|
|
||||||
Integer currentCnt = map.get(name);
|
|
||||||
map.put(name, currentCnt == null ? Integer.valueOf(1) : Integer.valueOf(1 + currentCnt));
|
|
||||||
} // for
|
|
||||||
|
|
||||||
int max = 0;
|
|
||||||
String maxName = "";
|
|
||||||
|
|
||||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
|
||||||
final String type = entry.getKey();
|
|
||||||
// Log.debug(type + " - " + entry.getValue());
|
|
||||||
|
|
||||||
if (max < entry.getValue()) {
|
|
||||||
max = entry.getValue();
|
|
||||||
maxName = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return maxName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getMostProminentCreatureType.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public static String getMostProminentCreatureType(final List<Card> list) {
|
|
||||||
|
|
||||||
if (list.size() == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
|
||||||
|
|
||||||
for (final Card c : list) {
|
|
||||||
final ArrayList<String> typeList = c.getType();
|
|
||||||
|
|
||||||
for (final String var : typeList) {
|
|
||||||
if (CardType.isACreatureType(var)) {
|
|
||||||
if (!map.containsKey(var)) {
|
|
||||||
map.put(var, 1);
|
|
||||||
} else {
|
|
||||||
map.put(var, map.get(var) + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // for
|
|
||||||
|
|
||||||
int max = 0;
|
|
||||||
String maxType = "";
|
|
||||||
|
|
||||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
|
||||||
final String type = entry.getKey();
|
|
||||||
// Log.debug(type + " - " + entry.getValue());
|
|
||||||
|
|
||||||
if (max < entry.getValue()) {
|
|
||||||
max = entry.getValue();
|
|
||||||
maxType = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* isMostProminentColor.
|
* isMostProminentColor.
|
||||||
@@ -3153,96 +2408,6 @@ public class CardFactoryUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getMostProminentColor.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public static String getMostProminentColor(final List<Card> list) {
|
|
||||||
|
|
||||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
|
||||||
|
|
||||||
for (final Card c : list) {
|
|
||||||
for (final String color : CardUtil.getColors(c)) {
|
|
||||||
if (color.equals("colorless")) {
|
|
||||||
// nothing to do
|
|
||||||
} else if (!map.containsKey(color)) {
|
|
||||||
map.put(color, 1);
|
|
||||||
} else {
|
|
||||||
map.put(color, map.get(color) + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // for
|
|
||||||
|
|
||||||
int max = 0;
|
|
||||||
String maxColor = "";
|
|
||||||
|
|
||||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
|
||||||
final String color = entry.getKey();
|
|
||||||
Log.debug(color + " - " + entry.getValue());
|
|
||||||
|
|
||||||
if (max < entry.getValue()) {
|
|
||||||
max = entry.getValue();
|
|
||||||
maxColor = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> getColorByProminence(final List<Card> list) {
|
|
||||||
final HashMap<String, Integer> counts = new HashMap<String, Integer>();
|
|
||||||
for (String color : Constant.Color.ONLY_COLORS) {
|
|
||||||
counts.put(color, 0);
|
|
||||||
}
|
|
||||||
for (Card c : list) {
|
|
||||||
List<String> colors = c.determineColor().toStringList();
|
|
||||||
for (String col : colors) {
|
|
||||||
if (counts.containsKey(col)) {
|
|
||||||
counts.put(col.toString(), counts.get(col.toString()) + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ArrayList<String> res = new ArrayList<String>(counts.keySet());
|
|
||||||
Collections.sort(res, new Comparator<String>() {
|
|
||||||
@Override
|
|
||||||
public int compare(final String a, final String b) {
|
|
||||||
return counts.get(b) - counts.get(a);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getUsableManaSources.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* a {@link forge.game.player.Player} object.
|
|
||||||
* @return a int.
|
|
||||||
*/
|
|
||||||
public static int getUsableManaSources(final Player player) {
|
|
||||||
List<Card> list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
for (final SpellAbility am : c.getAIPlayableMana()) {
|
|
||||||
if (am.canPlay()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return list.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* makeToken.
|
* makeToken.
|
||||||
@@ -3423,66 +2588,6 @@ public class CardFactoryUtil {
|
|||||||
return neededDamage;
|
return neededDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* getWorstLand
|
|
||||||
* <p/>
|
|
||||||
* This function finds the worst land a player has in play based on: worst
|
|
||||||
* 1. tapped, basic land 2. tapped, non-basic land 3. untapped, basic land
|
|
||||||
* 4. untapped, non-basic land best
|
|
||||||
* <p/>
|
|
||||||
* This is useful when the AI needs to find one of its lands to sacrifice
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* - AllZone.getHumanPlayer() or AllZone.getComputerPlayer()
|
|
||||||
* @return the worst land found based on the description above
|
|
||||||
*/
|
|
||||||
public static Card getWorstLand(final Player player) {
|
|
||||||
final List<Card> lands = player.getLandsInPlay();
|
|
||||||
return CardFactoryUtil.getWorstLand(lands);
|
|
||||||
} // end getWorstLand
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getWorstLand.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param lands
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getWorstLand(final List<Card> lands) {
|
|
||||||
Card worstLand = null;
|
|
||||||
int maxScore = 0;
|
|
||||||
// first, check for tapped, basic lands
|
|
||||||
for (Card tmp : lands) {
|
|
||||||
int score = tmp.isTapped() ? 2 : 0;
|
|
||||||
score += tmp.isBasicLand() ? 1 : 0;
|
|
||||||
if (score >= maxScore) {
|
|
||||||
worstLand = tmp;
|
|
||||||
maxScore = score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return worstLand;
|
|
||||||
} // end getWorstLand
|
|
||||||
|
|
||||||
// may return null
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getRandomCard.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card getRandomCard(final List<Card> list) {
|
|
||||||
if (list.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int index = CardFactoryUtil.random.nextInt(list.size());
|
|
||||||
return list.get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -4068,10 +3173,10 @@ public class CardFactoryUtil {
|
|||||||
} else {
|
} else {
|
||||||
// AI choosing what to haunt
|
// AI choosing what to haunt
|
||||||
final List<Card> oppCreats = CardLists.filterControlledBy(creats, card.getController().getOpponent());
|
final List<Card> oppCreats = CardLists.filterControlledBy(creats, card.getController().getOpponent());
|
||||||
if (oppCreats.size() != 0) {
|
if (!oppCreats.isEmpty()) {
|
||||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(oppCreats));
|
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(oppCreats));
|
||||||
} else {
|
} else {
|
||||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(creats));
|
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(creats));
|
||||||
}
|
}
|
||||||
Singletons.getModel().getGame().getStack().add(haunterDiesWork);
|
Singletons.getModel().getGame().getStack().add(haunterDiesWork);
|
||||||
}
|
}
|
||||||
@@ -4759,7 +3864,7 @@ public class CardFactoryUtil {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (choices.size() != 0) {
|
if (choices.size() != 0) {
|
||||||
ability.setTargetCard(CardFactoryUtil.getBestCreatureAI(choices));
|
ability.setTargetCard(ComputerUtilCard.getBestCreatureAI(choices));
|
||||||
|
|
||||||
if (ability.getTargetCard() != null) {
|
if (ability.getTargetCard() != null) {
|
||||||
ability.setStackDescription("Put " + card.getCounters(CounterType.P1P1)
|
ability.setStackDescription("Put " + card.getCounters(CounterType.P1P1)
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import forge.CardLists;
|
|||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.control.input.Input;
|
import forge.control.input.Input;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -223,9 +223,9 @@ public class CostPutCounter extends CostPartWithList {
|
|||||||
|
|
||||||
Card card = null;
|
Card card = null;
|
||||||
if (this.getType().equals("Creature.YouCtrl")) {
|
if (this.getType().equals("Creature.YouCtrl")) {
|
||||||
card = CardFactoryUtil.getWorstCreatureAI(typeList);
|
card = ComputerUtilCard.getWorstCreatureAI(typeList);
|
||||||
} else {
|
} else {
|
||||||
card = CardFactoryUtil.getWorstPermanentAI(typeList, false, false, false, false);
|
card = ComputerUtilCard.getWorstPermanentAI(typeList, false, false, false, false);
|
||||||
}
|
}
|
||||||
this.addToList(card);
|
this.addToList(card);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,13 @@ import java.util.List;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
import forge.CardColor;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
import forge.CardUtil;
|
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
import forge.card.ability.effects.CharmEffect;
|
import forge.card.ability.effects.CharmEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.cost.CostPayment;
|
import forge.card.cost.CostPayment;
|
||||||
import forge.card.mana.ManaCostBeingPaid;
|
import forge.card.mana.ManaCostBeingPaid;
|
||||||
@@ -26,6 +25,7 @@ import forge.card.spellability.TargetSelection;
|
|||||||
import forge.card.staticability.StaticAbility;
|
import forge.card.staticability.StaticAbility;
|
||||||
import forge.control.input.InputControl;
|
import forge.control.input.InputControl;
|
||||||
import forge.control.input.InputPayManaSimple;
|
import forge.control.input.InputPayManaSimple;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -196,7 +196,7 @@ public class GameActionPlay {
|
|||||||
}
|
}
|
||||||
while (tapForConvoke != null && untappedCreats.size() != 0) {
|
while (tapForConvoke != null && untappedCreats.size() != 0) {
|
||||||
final Card workingCard = (Card) tapForConvoke;
|
final Card workingCard = (Card) tapForConvoke;
|
||||||
usableColors = CardUtil.getConvokableColors(workingCard, newCost);
|
usableColors = GameActionPlay.getConvokableColors(workingCard, newCost);
|
||||||
|
|
||||||
if (usableColors.size() != 0) {
|
if (usableColors.size() != 0) {
|
||||||
String chosenColor = usableColors.get(0);
|
String chosenColor = usableColors.get(0);
|
||||||
@@ -317,7 +317,7 @@ public class GameActionPlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chosen == null) {
|
if (chosen == null) {
|
||||||
chosen = CardFactoryUtil.getWorstCreatureAI(grave);
|
chosen = ComputerUtilCard.getWorstCreatureAI(grave);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chosen == null) {
|
if (chosen == null) {
|
||||||
@@ -503,4 +503,33 @@ public class GameActionPlay {
|
|||||||
final String costCuttingGetMultiKickerManaCostPaidColored0) {
|
final String costCuttingGetMultiKickerManaCostPaidColored0) {
|
||||||
this.costCuttingGetMultiKickerManaCostPaidColored = costCuttingGetMultiKickerManaCostPaidColored0;
|
this.costCuttingGetMultiKickerManaCostPaidColored = costCuttingGetMultiKickerManaCostPaidColored0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the convokable colors.
|
||||||
|
*
|
||||||
|
* @param cardToConvoke
|
||||||
|
* the card to convoke
|
||||||
|
* @param cost
|
||||||
|
* the cost
|
||||||
|
* @return the convokable colors
|
||||||
|
*/
|
||||||
|
public static ArrayList<String> getConvokableColors(final Card cardToConvoke, final ManaCostBeingPaid cost) {
|
||||||
|
final ArrayList<String> usableColors = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (cost.getColorlessManaAmount() > 0) {
|
||||||
|
usableColors.add("colorless");
|
||||||
|
}
|
||||||
|
for (final CardColor col : cardToConvoke.getColor()) {
|
||||||
|
for (final String strCol : col.toStringList()) {
|
||||||
|
if (strCol.equals("colorless")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cost.toString().contains(MagicColor.toShortString(strCol))) {
|
||||||
|
usableColors.add(strCol.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return usableColors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import forge.CardLists;
|
|||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.trigger.Trigger;
|
import forge.card.trigger.Trigger;
|
||||||
import forge.card.trigger.TriggerType;
|
import forge.card.trigger.TriggerType;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
@@ -909,7 +908,7 @@ public class AiAttackController {
|
|||||||
// see if the defending creature is of higher or lower
|
// see if the defending creature is of higher or lower
|
||||||
// value. We don't want to attack only to lose value
|
// value. We don't want to attack only to lose value
|
||||||
if (isWorthLessThanAllKillers && attacker.getSVar("SacMe").equals("")
|
if (isWorthLessThanAllKillers && attacker.getSVar("SacMe").equals("")
|
||||||
&& CardFactoryUtil.evaluateCreature(defender) <= CardFactoryUtil.evaluateCreature(attacker)) {
|
&& ComputerUtilCard.evaluateCreature(defender) <= ComputerUtilCard.evaluateCreature(attacker)) {
|
||||||
isWorthLessThanAllKillers = false;
|
isWorthLessThanAllKillers = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ public class AiController {
|
|||||||
discardList.add(hand.get(0));
|
discardList.add(hand.get(0));
|
||||||
hand.remove(hand.get(0));
|
hand.remove(hand.get(0));
|
||||||
} else { //Discard worst card
|
} else { //Discard worst card
|
||||||
Card worst = CardFactoryUtil.getWorstAI(hand);
|
Card worst = ComputerUtilCard.getWorstAI(hand);
|
||||||
discardList.add(worst);
|
discardList.add(worst);
|
||||||
hand.remove(worst);
|
hand.remove(worst);
|
||||||
}
|
}
|
||||||
@@ -606,14 +606,64 @@ public class AiController {
|
|||||||
return discardList;
|
return discardList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These methods might be moved into matching SpellAbilityAi classes just without all these switches here
|
||||||
public Card chooseSingleCardForEffect(List<Card> options, SpellAbility sa, String title, boolean isOptional) {
|
public Card chooseSingleCardForEffect(List<Card> options, SpellAbility sa, String title, boolean isOptional) {
|
||||||
ApiType api = sa.getApi();
|
ApiType api = sa.getApi();
|
||||||
if ( null == api ) {
|
if ( null == api ) {
|
||||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Card choice = null;
|
||||||
|
Card host = sa.getSourceCard();
|
||||||
|
String logic = sa.getParam("AILogic");
|
||||||
|
|
||||||
switch(api) {
|
switch(api) {
|
||||||
case Bond: return CardFactoryUtil.getBestCreatureAI(options);
|
case Bond:
|
||||||
|
return ComputerUtilCard.getBestCreatureAI(options);
|
||||||
|
|
||||||
|
case ChooseCard:
|
||||||
|
if (logic == null) {
|
||||||
|
// Base Logic is choose "best"
|
||||||
|
choice = ComputerUtilCard.getBestAI(options);
|
||||||
|
} else if ("WorstCard".equals(logic)) {
|
||||||
|
choice = ComputerUtilCard.getWorstAI(options);
|
||||||
|
} else if (logic.equals("BestBlocker")) {
|
||||||
|
if (!CardLists.filter(options, Presets.UNTAPPED).isEmpty()) {
|
||||||
|
options = CardLists.filter(options, Presets.UNTAPPED);
|
||||||
|
}
|
||||||
|
choice = ComputerUtilCard.getBestCreatureAI(options);
|
||||||
|
} else if (logic.equals("Clone")) {
|
||||||
|
if (!CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
||||||
|
options = CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
||||||
|
}
|
||||||
|
choice = ComputerUtilCard.getBestAI(options);
|
||||||
|
} else if (logic.equals("Untap")) {
|
||||||
|
if (!CardLists.getValidCards(options, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host).isEmpty()) {
|
||||||
|
options = CardLists.getValidCards(options, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host);
|
||||||
|
}
|
||||||
|
choice = ComputerUtilCard.getBestAI(options);
|
||||||
|
}
|
||||||
|
return choice;
|
||||||
|
|
||||||
|
case Encode:
|
||||||
|
if (logic == null) {
|
||||||
|
// Base Logic is choose "best"
|
||||||
|
choice = ComputerUtilCard.getBestAI(options);
|
||||||
|
} else if ("WorstCard".equals(logic)) {
|
||||||
|
choice = ComputerUtilCard.getWorstAI(options);
|
||||||
|
} else if (logic.equals("BestBlocker")) {
|
||||||
|
if (!CardLists.filter(options, Presets.UNTAPPED).isEmpty()) {
|
||||||
|
options = CardLists.filter(options, Presets.UNTAPPED);
|
||||||
|
}
|
||||||
|
choice = ComputerUtilCard.getBestCreatureAI(options);
|
||||||
|
} else if (logic.equals("Clone")) {
|
||||||
|
if (!CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
||||||
|
options = CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
||||||
|
}
|
||||||
|
choice = ComputerUtilCard.getBestAI(options);
|
||||||
|
}
|
||||||
|
return choice;
|
||||||
|
|
||||||
default: throw new InvalidParameterException("AI chooseSingleCard does not know how to choose card for " + api);
|
default: throw new InvalidParameterException("AI chooseSingleCard does not know how to choose card for " + api);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,12 +677,15 @@ public class AiController {
|
|||||||
|
|
||||||
switch(api) {
|
switch(api) {
|
||||||
case Discard:
|
case Discard:
|
||||||
if ( mode.equals("Random") ) { //
|
if ( mode.startsWith("Random") ) { //
|
||||||
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Encode:
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
String exMsg = String.format("AI confirmAction does not know what to decide about %s with %s mode.", api, mode);
|
String exMsg = String.format("AI confirmAction does not know what to decide about %s with %s mode.", api, mode);
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public class ComputerUtil {
|
|||||||
if (unless != null && !unless.endsWith(">")) {
|
if (unless != null && !unless.endsWith(">")) {
|
||||||
final int amount = AbilityUtils.calculateAmount(source, unless, sa);
|
final int amount = AbilityUtils.calculateAmount(source, unless, sa);
|
||||||
|
|
||||||
final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent());
|
final int usableManaSources = ComputerUtilCard.getUsableManaSources(ai.getOpponent());
|
||||||
|
|
||||||
// If the Unless isn't enough, this should be less likely to be used
|
// If the Unless isn't enough, this should be less likely to be used
|
||||||
if (amount > usableManaSources) {
|
if (amount > usableManaSources) {
|
||||||
@@ -384,7 +384,7 @@ public class ComputerUtil {
|
|||||||
if (landsInPlay.size() >= highestCMC
|
if (landsInPlay.size() >= highestCMC
|
||||||
|| (landsInPlay.size() + landsInHand.size() > 6 && landsInHand.size() > 1)) {
|
|| (landsInPlay.size() + landsInHand.size() > 6 && landsInHand.size() > 1)) {
|
||||||
// Don't need more land.
|
// Don't need more land.
|
||||||
return CardFactoryUtil.getWorstLand(landsInHand);
|
return ComputerUtilCard.getWorstLand(landsInHand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -678,11 +678,11 @@ public class ComputerUtil {
|
|||||||
Card c;
|
Card c;
|
||||||
|
|
||||||
if (CardLists.getNotType(remaining, "Creature").size() == 0) {
|
if (CardLists.getNotType(remaining, "Creature").size() == 0) {
|
||||||
c = CardFactoryUtil.getWorstCreatureAI(remaining);
|
c = ComputerUtilCard.getWorstCreatureAI(remaining);
|
||||||
} else if (CardLists.getNotType(remaining, "Land").size() == 0) {
|
} else if (CardLists.getNotType(remaining, "Land").size() == 0) {
|
||||||
c = CardFactoryUtil.getWorstLand(CardLists.filter(remaining, CardPredicates.Presets.LANDS));
|
c = ComputerUtilCard.getWorstLand(CardLists.filter(remaining, CardPredicates.Presets.LANDS));
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getWorstPermanentAI(remaining, false, false, false, false);
|
c = ComputerUtilCard.getWorstPermanentAI(remaining, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ArrayList<Card> auras = c.getEnchantedBy();
|
final ArrayList<Card> auras = c.getEnchantedBy();
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import forge.CardLists;
|
|||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.game.phase.Combat;
|
import forge.game.phase.Combat;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -360,9 +359,9 @@ public class ComputerUtilBlock {
|
|||||||
// destroyed
|
// destroyed
|
||||||
killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker, safeBlockers, combat);
|
killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker, safeBlockers, combat);
|
||||||
if (killingBlockers.size() > 0) {
|
if (killingBlockers.size() > 0) {
|
||||||
blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
blocker = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
|
||||||
} else if (!attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
} else if (!attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||||
blocker = CardFactoryUtil.getWorstCreatureAI(safeBlockers);
|
blocker = ComputerUtilCard.getWorstCreatureAI(safeBlockers);
|
||||||
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
||||||
}
|
}
|
||||||
} // no safe blockers
|
} // no safe blockers
|
||||||
@@ -378,9 +377,9 @@ public class ComputerUtilBlock {
|
|||||||
}
|
}
|
||||||
// 4.Blockers that can destroy the attacker and are worth less
|
// 4.Blockers that can destroy the attacker and are worth less
|
||||||
if (blocker == null && killingBlockers.size() > 0) {
|
if (blocker == null && killingBlockers.size() > 0) {
|
||||||
final Card worst = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
final Card worst = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
|
||||||
|
|
||||||
if ((CardFactoryUtil.evaluateCreature(worst) + ComputerUtilBlock.getDiff()) < CardFactoryUtil
|
if ((ComputerUtilCard.evaluateCreature(worst) + ComputerUtilBlock.getDiff()) < ComputerUtilCard
|
||||||
.evaluateCreature(attacker)) {
|
.evaluateCreature(attacker)) {
|
||||||
blocker = worst;
|
blocker = worst;
|
||||||
}
|
}
|
||||||
@@ -471,7 +470,7 @@ public class ComputerUtilBlock {
|
|||||||
&& !(c.hasKeyword("First Strike") || c.hasKeyword("Double Strike"))) {
|
&& !(c.hasKeyword("First Strike") || c.hasKeyword("Double Strike"))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return lifeInDanger || (CardFactoryUtil.evaluateCreature(c) + ComputerUtilBlock.getDiff()) < CardFactoryUtil
|
return lifeInDanger || (ComputerUtilCard.evaluateCreature(c) + ComputerUtilBlock.getDiff()) < ComputerUtilCard
|
||||||
.evaluateCreature(attacker);
|
.evaluateCreature(attacker);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -479,11 +478,11 @@ public class ComputerUtilBlock {
|
|||||||
return combat;
|
return combat;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Card leader = CardFactoryUtil.getBestCreatureAI(usableBlockers);
|
final Card leader = ComputerUtilCard.getBestCreatureAI(usableBlockers);
|
||||||
blockGang.add(leader);
|
blockGang.add(leader);
|
||||||
usableBlockers.remove(leader);
|
usableBlockers.remove(leader);
|
||||||
absorbedDamage = ComputerUtilCombat.getEnoughDamageToKill(leader, attacker.getNetCombatDamage(), attacker, true);
|
absorbedDamage = ComputerUtilCombat.getEnoughDamageToKill(leader, attacker.getNetCombatDamage(), attacker, true);
|
||||||
currentValue = CardFactoryUtil.evaluateCreature(leader);
|
currentValue = ComputerUtilCard.evaluateCreature(leader);
|
||||||
|
|
||||||
for (final Card blocker : usableBlockers) {
|
for (final Card blocker : usableBlockers) {
|
||||||
// Add an additional blocker if the current blockers are not
|
// Add an additional blocker if the current blockers are not
|
||||||
@@ -491,7 +490,7 @@ public class ComputerUtilBlock {
|
|||||||
final int currentDamage = ComputerUtilCombat.totalDamageOfBlockers(attacker, blockGang);
|
final int currentDamage = ComputerUtilCombat.totalDamageOfBlockers(attacker, blockGang);
|
||||||
final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker);
|
final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker);
|
||||||
final int absorbedDamage2 = ComputerUtilCombat.getEnoughDamageToKill(blocker, attacker.getNetCombatDamage(), attacker, true);
|
final int absorbedDamage2 = ComputerUtilCombat.getEnoughDamageToKill(blocker, attacker.getNetCombatDamage(), attacker, true);
|
||||||
final int addedValue = CardFactoryUtil.evaluateCreature(blocker);
|
final int addedValue = ComputerUtilCard.evaluateCreature(blocker);
|
||||||
final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker)
|
final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker)
|
||||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
|
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
|
||||||
if ((damageNeeded > currentDamage || CombatUtil.needsBlockers(attacker) > blockGang.size())
|
if ((damageNeeded > currentDamage || CombatUtil.needsBlockers(attacker) > blockGang.size())
|
||||||
@@ -499,7 +498,7 @@ public class ComputerUtilBlock {
|
|||||||
// The attacker will be killed
|
// The attacker will be killed
|
||||||
&& (absorbedDamage2 + absorbedDamage > attacker.getNetCombatDamage()
|
&& (absorbedDamage2 + absorbedDamage > attacker.getNetCombatDamage()
|
||||||
// only one blocker can be killed
|
// only one blocker can be killed
|
||||||
|| currentValue + addedValue - 50 <= CardFactoryUtil.evaluateCreature(attacker)
|
|| currentValue + addedValue - 50 <= ComputerUtilCard.evaluateCreature(attacker)
|
||||||
// or attacker is worth more
|
// or attacker is worth more
|
||||||
|| (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)))
|
|| (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)))
|
||||||
// or life is in danger
|
// or life is in danger
|
||||||
@@ -545,7 +544,7 @@ public class ComputerUtilBlock {
|
|||||||
ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true),
|
ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true),
|
||||||
combat);
|
combat);
|
||||||
if ((killingBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if ((killingBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
final Card blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
final Card blocker = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
|
||||||
combat.addBlocker(attacker, blocker);
|
combat.addBlocker(attacker, blocker);
|
||||||
currentAttackers.remove(attacker);
|
currentAttackers.remove(attacker);
|
||||||
}
|
}
|
||||||
@@ -579,7 +578,7 @@ public class ComputerUtilBlock {
|
|||||||
chumpBlockers = ComputerUtilBlock
|
chumpBlockers = ComputerUtilBlock
|
||||||
.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true);
|
.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true);
|
||||||
if ((chumpBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if ((chumpBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
final Card blocker = CardFactoryUtil.getWorstCreatureAI(chumpBlockers);
|
final Card blocker = ComputerUtilCard.getWorstCreatureAI(chumpBlockers);
|
||||||
combat.addBlocker(attacker, blocker);
|
combat.addBlocker(attacker, blocker);
|
||||||
currentAttackers.remove(attacker);
|
currentAttackers.remove(attacker);
|
||||||
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
||||||
@@ -697,7 +696,7 @@ public class ComputerUtilBlock {
|
|||||||
final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker);
|
final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker);
|
||||||
if ((damageNeeded > currentDamage)
|
if ((damageNeeded > currentDamage)
|
||||||
&& !(damageNeeded > (currentDamage + additionalDamage))
|
&& !(damageNeeded > (currentDamage + additionalDamage))
|
||||||
&& ((CardFactoryUtil.evaluateCreature(blocker) + ComputerUtilBlock.getDiff()) < CardFactoryUtil
|
&& ((ComputerUtilCard.evaluateCreature(blocker) + ComputerUtilBlock.getDiff()) < ComputerUtilCard
|
||||||
.evaluateCreature(attacker)) && CombatUtil.canBlock(attacker, blocker, combat)) {
|
.evaluateCreature(attacker)) && CombatUtil.canBlock(attacker, blocker, combat)) {
|
||||||
combat.addBlocker(attacker, blocker);
|
combat.addBlocker(attacker, blocker);
|
||||||
ComputerUtilBlock.getBlockersLeft().remove(blocker);
|
ComputerUtilBlock.getBlockersLeft().remove(blocker);
|
||||||
|
|||||||
917
src/main/java/forge/game/ai/ComputerUtilCard.java
Normal file
917
src/main/java/forge/game/ai/ComputerUtilCard.java
Normal file
@@ -0,0 +1,917 @@
|
|||||||
|
package forge.game.ai;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.esotericsoftware.minlog.Log;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
import forge.Card;
|
||||||
|
import forge.CardLists;
|
||||||
|
import forge.CardPredicates;
|
||||||
|
import forge.CardUtil;
|
||||||
|
import forge.Constant;
|
||||||
|
import forge.card.CardType;
|
||||||
|
import forge.card.spellability.SpellAbility;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
import forge.util.Aggregates;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this type.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ComputerUtilCard {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getMostExpensivePermanentAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @param spell
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @param targeted
|
||||||
|
* a boolean.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getMostExpensivePermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||||
|
List<Card> all = list;
|
||||||
|
if (targeted) {
|
||||||
|
all = CardLists.filter(all, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
return c.canBeTargetedBy(spell);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ComputerUtilCard.getMostExpensivePermanentAI(all);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The AI doesn't really pick the best artifact, just the most expensive.
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getBestArtifactAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getBestArtifactAI(final List<Card> list) {
|
||||||
|
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ARTIFACTS);
|
||||||
|
if (all.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// get biggest Artifact
|
||||||
|
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The AI doesn't really pick the best enchantment, just the most expensive.
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getBestEnchantmentAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @param spell
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @param targeted
|
||||||
|
* a boolean.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getBestEnchantmentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||||
|
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS);
|
||||||
|
if (targeted) {
|
||||||
|
all = CardLists.filter(all, new Predicate<Card>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
return c.canBeTargetedBy(spell);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// get biggest Enchantment
|
||||||
|
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getBestLandAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getBestLandAI(final List<Card> list) {
|
||||||
|
final List<Card> land = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
||||||
|
if (!(land.size() > 0)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prefer to target non basic lands
|
||||||
|
final List<Card> nbLand = CardLists.filter(land, Predicates.not(CardPredicates.Presets.BASIC_LANDS));
|
||||||
|
|
||||||
|
if (nbLand.size() > 0) {
|
||||||
|
// TODO - Rank non basics?
|
||||||
|
return Aggregates.random(nbLand);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no non-basic lands, target the least represented basic land type
|
||||||
|
String sminBL = "";
|
||||||
|
int iminBL = 20000; // hopefully no one will ever have more than 20000
|
||||||
|
// lands of one type....
|
||||||
|
int n = 0;
|
||||||
|
for (String name : Constant.Color.BASIC_LANDS) {
|
||||||
|
n = CardLists.getType(land, name).size();
|
||||||
|
if ((n < iminBL) && (n > 0)) {
|
||||||
|
// if two or more are tied, only the
|
||||||
|
// first
|
||||||
|
// one checked will be used
|
||||||
|
iminBL = n;
|
||||||
|
sminBL = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iminBL == 20000) {
|
||||||
|
return null; // no basic land was a minimum
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Card> bLand = CardLists.getType(land, sminBL);
|
||||||
|
|
||||||
|
for (Card ut : Iterables.filter(bLand, CardPredicates.Presets.UNTAPPED)) {
|
||||||
|
return ut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return Aggregates.random(bLand); // random tapped land of least represented type
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getCheapestPermanentAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @param spell
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @param targeted
|
||||||
|
* a boolean.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getCheapestPermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||||
|
List<Card> all = list;
|
||||||
|
if (targeted) {
|
||||||
|
all = CardLists.filter(all, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
return c.canBeTargetedBy(spell);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (all.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get cheapest card:
|
||||||
|
Card cheapest = null;
|
||||||
|
cheapest = all.get(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < all.size(); i++) {
|
||||||
|
if (cheapest.getManaCost().getCMC() <= cheapest.getManaCost().getCMC()) {
|
||||||
|
cheapest = all.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cheapest;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// for Sarkhan the Mad
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getCheapestCreatureAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @param spell
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @param targeted
|
||||||
|
* a boolean.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getCheapestCreatureAI(List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||||
|
list = CardLists.filter(list, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
return c.isCreature();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return getCheapestPermanentAI(list, spell, targeted);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns null if list.size() == 0
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getBestAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getBestAI(final List<Card> list) {
|
||||||
|
// Get Best will filter by appropriate getBest list if ALL of the list
|
||||||
|
// is of that type
|
||||||
|
if (CardLists.getNotType(list, "Creature").size() == 0) {
|
||||||
|
return ComputerUtilCard.getBestCreatureAI(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CardLists.getNotType(list, "Land").size() == 0) {
|
||||||
|
return getBestLandAI(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - Once we get an EvaluatePermanent this should call
|
||||||
|
// getBestPermanent()
|
||||||
|
return ComputerUtilCard.getMostExpensivePermanentAI(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getBestCreatureAI.
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* the list
|
||||||
|
* @return the card
|
||||||
|
*/
|
||||||
|
public static Card getBestCreatureAI(final List<Card> list) {
|
||||||
|
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||||
|
return Aggregates.itemWithMax(all, ComputerUtilCard.fnEvaluateCreature);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This selection rates tokens higher
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getBestCreatureToBounceAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getBestCreatureToBounceAI(final List<Card> list) {
|
||||||
|
final int tokenBonus = 40;
|
||||||
|
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||||
|
Card biggest = null; // returns null if list.size() == 0
|
||||||
|
int biggestvalue = 0;
|
||||||
|
int newvalue = 0;
|
||||||
|
|
||||||
|
if (all.size() != 0) {
|
||||||
|
biggest = all.get(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < all.size(); i++) {
|
||||||
|
biggestvalue = ComputerUtilCard.evaluateCreature(biggest);
|
||||||
|
if (biggest.isToken()) {
|
||||||
|
biggestvalue += tokenBonus; // raise the value of tokens
|
||||||
|
}
|
||||||
|
newvalue = ComputerUtilCard.evaluateCreature(all.get(i));
|
||||||
|
if (all.get(i).isToken()) {
|
||||||
|
newvalue += tokenBonus; // raise the value of tokens
|
||||||
|
}
|
||||||
|
if (biggestvalue < newvalue) {
|
||||||
|
biggest = all.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return biggest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getWorstAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getWorstAI(final List<Card> list) {
|
||||||
|
return ComputerUtilCard.getWorstPermanentAI(list, false, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns null if list.size() == 0
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getWorstCreatureAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getWorstCreatureAI(final List<Card> list) {
|
||||||
|
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||||
|
// get smallest creature
|
||||||
|
return Aggregates.itemWithMin(all, ComputerUtilCard.fnEvaluateCreature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getWorstPermanentAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @param biasEnch
|
||||||
|
* a boolean.
|
||||||
|
* @param biasLand
|
||||||
|
* a boolean.
|
||||||
|
* @param biasArt
|
||||||
|
* a boolean.
|
||||||
|
* @param biasCreature
|
||||||
|
* a boolean.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getWorstPermanentAI(final List<Card> list, final boolean biasEnch, final boolean biasLand,
|
||||||
|
final boolean biasArt, final boolean biasCreature) {
|
||||||
|
if (list.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (biasEnch && Iterables.any(list, CardPredicates.Presets.ENCHANTMENTS)) {
|
||||||
|
return getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (biasArt && Iterables.any(list, CardPredicates.Presets.ARTIFACTS)) {
|
||||||
|
return getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ARTIFACTS), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (biasLand && Iterables.any(list, CardPredicates.Presets.LANDS)) {
|
||||||
|
return ComputerUtilCard.getWorstLand(CardLists.filter(list, CardPredicates.Presets.LANDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (biasCreature && Iterables.any(list, CardPredicates.Presets.CREATURES)) {
|
||||||
|
return getWorstCreatureAI(CardLists.filter(list, CardPredicates.Presets.CREATURES));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Card> lands = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
||||||
|
if (lands.size() > 6) {
|
||||||
|
return ComputerUtilCard.getWorstLand(lands);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((CardLists.getType(list, "Artifact").size() > 0) || (CardLists.getType(list, "Enchantment").size() > 0)) {
|
||||||
|
return getCheapestPermanentAI(CardLists.filter(list, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
return c.isArtifact() || c.isEnchantment();
|
||||||
|
}
|
||||||
|
}), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CardLists.getType(list, "Creature").size() > 0) {
|
||||||
|
return getWorstCreatureAI(CardLists.getType(list, "Creature"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Planeswalkers fall through to here, lands will fall through if there
|
||||||
|
// aren't very many
|
||||||
|
return getCheapestPermanentAI(list, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Function<Card, Integer> fnEvaluateCreature = new Function<Card, Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer apply(Card a) {
|
||||||
|
return ComputerUtilCard.evaluateCreature(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final Comparator<Card> EvaluateCreatureComparator = new Comparator<Card>() {
|
||||||
|
@Override
|
||||||
|
public int compare(final Card a, final Card b) {
|
||||||
|
return ComputerUtilCard.evaluateCreature(b) - ComputerUtilCard.evaluateCreature(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* evaluateCreature.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @return a int.
|
||||||
|
*/
|
||||||
|
public static int evaluateCreature(final Card c) {
|
||||||
|
|
||||||
|
int value = 100;
|
||||||
|
if (c.isToken()) {
|
||||||
|
value = 80; // tokens should be worth less than actual cards
|
||||||
|
}
|
||||||
|
int power = c.getNetCombatDamage();
|
||||||
|
final int toughness = c.getNetDefense();
|
||||||
|
for (String keyword : c.getKeyword()) {
|
||||||
|
if (keyword.equals("Prevent all combat damage that would be dealt by CARDNAME.")
|
||||||
|
|| keyword.equals("Prevent all damage that would be dealt by CARDNAME.")
|
||||||
|
|| keyword.equals("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")
|
||||||
|
|| keyword.equals("Prevent all damage that would be dealt to and dealt by CARDNAME.")) {
|
||||||
|
power = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value += power * 15;
|
||||||
|
value += toughness * 10;
|
||||||
|
value += c.getCMC() * 5;
|
||||||
|
|
||||||
|
// Evasion keywords
|
||||||
|
if (c.hasKeyword("Flying")) {
|
||||||
|
value += power * 10;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Horsemanship")) {
|
||||||
|
value += power * 10;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Unblockable")) {
|
||||||
|
value += power * 10;
|
||||||
|
} else {
|
||||||
|
if (c.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||||
|
value += power * 6;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Fear")) {
|
||||||
|
value += power * 6;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Intimidate")) {
|
||||||
|
value += power * 6;
|
||||||
|
}
|
||||||
|
if (c.hasStartOfKeyword("CARDNAME can't be blocked except by")) {
|
||||||
|
value += power * 5;
|
||||||
|
}
|
||||||
|
if (c.hasStartOfKeyword("CARDNAME can't be blocked by")) {
|
||||||
|
value += power * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other good keywords
|
||||||
|
if (power > 0) {
|
||||||
|
if (c.hasKeyword("Double Strike")) {
|
||||||
|
value += 10 + (power * 15);
|
||||||
|
} else if (c.hasKeyword("First Strike")) {
|
||||||
|
value += 10 + (power * 5);
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Deathtouch")) {
|
||||||
|
value += 25;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Lifelink")) {
|
||||||
|
value += power * 10;
|
||||||
|
}
|
||||||
|
if (power > 1 && c.hasKeyword("Trample")) {
|
||||||
|
value += (power - 1) * 5;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Vigilance")) {
|
||||||
|
value += (power * 5) + (toughness * 5);
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Wither")) {
|
||||||
|
value += power * 10;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Infect")) {
|
||||||
|
value += power * 15;
|
||||||
|
}
|
||||||
|
value += c.getKeywordMagnitude("Rampage");
|
||||||
|
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
||||||
|
+ "put into a graveyard, put a +1/+1 counter on CARDNAME.")) {
|
||||||
|
value += 2;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
||||||
|
+ "put into a graveyard, put a +2/+2 counter on CARDNAME.")) {
|
||||||
|
value += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value += c.getKeywordMagnitude("Bushido") * 16;
|
||||||
|
value += c.getAmountOfKeyword("Flanking") * 15;
|
||||||
|
value += c.getAmountOfKeyword("Exalted") * 15;
|
||||||
|
value += c.getKeywordMagnitude("Annihilator") * 50;
|
||||||
|
|
||||||
|
|
||||||
|
// Defensive Keywords
|
||||||
|
if (c.hasKeyword("Reach") && !c.hasKeyword("Flying")) {
|
||||||
|
value += 5;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("CARDNAME can block creatures with shadow as though they didn't have shadow.")) {
|
||||||
|
value += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protection
|
||||||
|
if (c.hasKeyword("Indestructible")) {
|
||||||
|
value += 70;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Prevent all damage that would be dealt to CARDNAME.")) {
|
||||||
|
value += 60;
|
||||||
|
} else if (c.hasKeyword("Prevent all combat damage that would be dealt to CARDNAME.")) {
|
||||||
|
value += 50;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("Hexproof")) {
|
||||||
|
value += 35;
|
||||||
|
} else if (c.hasKeyword("Shroud")) {
|
||||||
|
value += 30;
|
||||||
|
}
|
||||||
|
if (c.hasStartOfKeyword("Protection")) {
|
||||||
|
value += 20;
|
||||||
|
}
|
||||||
|
if (c.hasStartOfKeyword("PreventAllDamageBy")) {
|
||||||
|
value += 10;
|
||||||
|
}
|
||||||
|
value += c.getKeywordMagnitude("Absorb") * 11;
|
||||||
|
|
||||||
|
// Bad keywords
|
||||||
|
if (c.hasKeyword("Defender") || c.hasKeyword("CARDNAME can't attack.")) {
|
||||||
|
value -= (power * 9) + 40;
|
||||||
|
} else if (c.getSVar("SacrificeEndCombat").equals("True")) {
|
||||||
|
value -= 40;
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("CARDNAME can't block.")) {
|
||||||
|
value -= 10;
|
||||||
|
} else if (c.hasKeyword("CARDNAME attacks each turn if able.")) {
|
||||||
|
value -= 10;
|
||||||
|
} else if (c.hasKeyword("CARDNAME can block only creatures with flying.")) {
|
||||||
|
value -= toughness * 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.hasStartOfKeyword("When CARDNAME is dealt damage, destroy it.")) {
|
||||||
|
value -= (toughness - 1) * 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.hasKeyword("CARDNAME can't attack or block.")) {
|
||||||
|
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("CARDNAME doesn't untap during your untap step.")) {
|
||||||
|
if (c.isTapped()) {
|
||||||
|
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
||||||
|
} else {
|
||||||
|
value -= 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c.hasKeyword("At the beginning of the end step, destroy CARDNAME.")
|
||||||
|
|| c.hasKeyword("At the beginning of the end step, exile CARDNAME.")
|
||||||
|
|| c.hasKeyword("At the beginning of the end step, sacrifice CARDNAME.")) {
|
||||||
|
value -= 50;
|
||||||
|
} else if (c.hasStartOfKeyword("Cumulative upkeep")) {
|
||||||
|
value -= 30;
|
||||||
|
} else if (c.hasStartOfKeyword("At the beginning of your upkeep, destroy CARDNAME unless you pay")
|
||||||
|
|| c.hasStartOfKeyword("At the beginning of your upkeep, sacrifice CARDNAME unless you pay")
|
||||||
|
|| c.hasStartOfKeyword("Upkeep:")) {
|
||||||
|
value -= 20;
|
||||||
|
} else if (c.hasStartOfKeyword("(Echo unpaid)")) {
|
||||||
|
value -= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.hasStartOfKeyword("At the beginning of your upkeep, CARDNAME deals")) {
|
||||||
|
value -= 20;
|
||||||
|
}
|
||||||
|
if (c.hasStartOfKeyword("Fading")) {
|
||||||
|
value -= 20;
|
||||||
|
}
|
||||||
|
if (c.hasStartOfKeyword("Vanishing")) {
|
||||||
|
value -= 20;
|
||||||
|
}
|
||||||
|
if (c.getSVar("Targeting").equals("Dies")) {
|
||||||
|
value -= 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final SpellAbility sa : c.getSpellAbilities()) {
|
||||||
|
if (sa.isAbility()) {
|
||||||
|
value += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!c.getManaAbility().isEmpty()) {
|
||||||
|
value += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.isUntapped()) {
|
||||||
|
value += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// paired creatures are more valuable because they grant a bonus to the other creature
|
||||||
|
if (c.isPaired()) {
|
||||||
|
value += 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
|
||||||
|
} // evaluateCreature
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* evaluatePermanentList.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a int.
|
||||||
|
*/
|
||||||
|
public static int evaluatePermanentList(final List<Card> list) {
|
||||||
|
int value = 0;
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
value += list.get(i).getCMC() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* evaluateCreatureList.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a int.
|
||||||
|
*/
|
||||||
|
public static int evaluateCreatureList(final List<Card> list) {
|
||||||
|
int value = 0;
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
value += evaluateCreature(list.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* doesCreatureAttackAI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param ai
|
||||||
|
* the AI player
|
||||||
|
* @param card
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public static boolean doesCreatureAttackAI(final Player ai, final Card card) {
|
||||||
|
final List<Card> att = new AiAttackController(ai, ai.getOpponent()).getAttackers().getAttackers();
|
||||||
|
|
||||||
|
return att.contains(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
// may return null
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getRandomCard.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getRandomCard(final List<Card> list) {
|
||||||
|
if (list.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int index = ComputerUtilCard.random.nextInt(list.size());
|
||||||
|
return list.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Random random = MyRandom.getRandom();
|
||||||
|
/**
|
||||||
|
* getMostExpensivePermanentAI.
|
||||||
|
*
|
||||||
|
* @param all
|
||||||
|
* the all
|
||||||
|
* @return the card
|
||||||
|
*/
|
||||||
|
public static Card getMostExpensivePermanentAI(final List<Card> all) {
|
||||||
|
if (all.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Card biggest = null;
|
||||||
|
biggest = all.get(0);
|
||||||
|
|
||||||
|
int bigCMC = 0;
|
||||||
|
for (int i = 0; i < all.size(); i++) {
|
||||||
|
final Card card = all.get(i);
|
||||||
|
int curCMC = card.getCMC();
|
||||||
|
|
||||||
|
// Add all cost of all auras with the same controller
|
||||||
|
final List<Card> auras = CardLists.filterControlledBy(card.getEnchantedBy(), card.getController());
|
||||||
|
curCMC += Aggregates.sum(auras, CardPredicates.Accessors.fnGetCmc) + auras.size();
|
||||||
|
|
||||||
|
if (curCMC >= bigCMC) {
|
||||||
|
bigCMC = curCMC;
|
||||||
|
biggest = all.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return biggest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getMostProminentCardName.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public static String getMostProminentCardName(final List<Card> list) {
|
||||||
|
|
||||||
|
if (list.size() == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||||
|
|
||||||
|
for (final Card c : list) {
|
||||||
|
final String name = c.getName();
|
||||||
|
Integer currentCnt = map.get(name);
|
||||||
|
map.put(name, currentCnt == null ? Integer.valueOf(1) : Integer.valueOf(1 + currentCnt));
|
||||||
|
} // for
|
||||||
|
|
||||||
|
int max = 0;
|
||||||
|
String maxName = "";
|
||||||
|
|
||||||
|
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
final String type = entry.getKey();
|
||||||
|
// Log.debug(type + " - " + entry.getValue());
|
||||||
|
|
||||||
|
if (max < entry.getValue()) {
|
||||||
|
max = entry.getValue();
|
||||||
|
maxName = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getMostProminentCreatureType.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public static String getMostProminentCreatureType(final List<Card> list) {
|
||||||
|
|
||||||
|
if (list.size() == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||||
|
|
||||||
|
for (final Card c : list) {
|
||||||
|
final ArrayList<String> typeList = c.getType();
|
||||||
|
|
||||||
|
for (final String var : typeList) {
|
||||||
|
if (CardType.isACreatureType(var)) {
|
||||||
|
if (!map.containsKey(var)) {
|
||||||
|
map.put(var, 1);
|
||||||
|
} else {
|
||||||
|
map.put(var, map.get(var) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
|
||||||
|
int max = 0;
|
||||||
|
String maxType = "";
|
||||||
|
|
||||||
|
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
final String type = entry.getKey();
|
||||||
|
// Log.debug(type + " - " + entry.getValue());
|
||||||
|
|
||||||
|
if (max < entry.getValue()) {
|
||||||
|
max = entry.getValue();
|
||||||
|
maxType = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getMostProminentColor.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public static String getMostProminentColor(final List<Card> list) {
|
||||||
|
|
||||||
|
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||||
|
|
||||||
|
for (final Card c : list) {
|
||||||
|
for (final String color : CardUtil.getColors(c)) {
|
||||||
|
if (color.equals("colorless")) {
|
||||||
|
// nothing to do
|
||||||
|
} else if (!map.containsKey(color)) {
|
||||||
|
map.put(color, 1);
|
||||||
|
} else {
|
||||||
|
map.put(color, map.get(color) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
|
||||||
|
int max = 0;
|
||||||
|
String maxColor = "";
|
||||||
|
|
||||||
|
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
final String color = entry.getKey();
|
||||||
|
Log.debug(color + " - " + entry.getValue());
|
||||||
|
|
||||||
|
if (max < entry.getValue()) {
|
||||||
|
max = entry.getValue();
|
||||||
|
maxColor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getColorByProminence(final List<Card> list) {
|
||||||
|
final HashMap<String, Integer> counts = new HashMap<String, Integer>();
|
||||||
|
for (String color : Constant.Color.ONLY_COLORS) {
|
||||||
|
counts.put(color, 0);
|
||||||
|
}
|
||||||
|
for (Card c : list) {
|
||||||
|
List<String> colors = c.determineColor().toStringList();
|
||||||
|
for (String col : colors) {
|
||||||
|
if (counts.containsKey(col)) {
|
||||||
|
counts.put(col.toString(), counts.get(col.toString()) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ArrayList<String> res = new ArrayList<String>(counts.keySet());
|
||||||
|
Collections.sort(res, new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(final String a, final String b) {
|
||||||
|
return counts.get(b) - counts.get(a);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getUsableManaSources.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* a {@link forge.game.player.Player} object.
|
||||||
|
* @return a int.
|
||||||
|
*/
|
||||||
|
public static int getUsableManaSources(final Player player) {
|
||||||
|
List<Card> list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
for (final SpellAbility am : c.getAIPlayableMana()) {
|
||||||
|
if (am.canPlay()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getWorstLand.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param lands
|
||||||
|
* a {@link forge.CardList} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card getWorstLand(final List<Card> lands) {
|
||||||
|
Card worstLand = null;
|
||||||
|
int maxScore = 0;
|
||||||
|
// first, check for tapped, basic lands
|
||||||
|
for (Card tmp : lands) {
|
||||||
|
int score = tmp.isTapped() ? 2 : 0;
|
||||||
|
score += tmp.isBasicLand() ? 1 : 0;
|
||||||
|
if (score >= maxScore) {
|
||||||
|
worstLand = tmp;
|
||||||
|
maxScore = score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return worstLand;
|
||||||
|
} // end getWorstLand
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ import forge.Singletons;
|
|||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.cost.CostPayment;
|
import forge.card.cost.CostPayment;
|
||||||
import forge.card.mana.ManaCostBeingPaid;
|
import forge.card.mana.ManaCostBeingPaid;
|
||||||
@@ -748,7 +747,7 @@ public class ComputerUtilMana {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if combo mana can produce most common color in hand
|
// check if combo mana can produce most common color in hand
|
||||||
String commonColor = CardFactoryUtil.getMostProminentColor(ai.getCardsIn(
|
String commonColor = ComputerUtilCard.getMostProminentColor(ai.getCardsIn(
|
||||||
ZoneType.Hand));
|
ZoneType.Hand));
|
||||||
if (!commonColor.isEmpty() && abMana.getComboColors().contains(MagicColor.toShortString(commonColor))) {
|
if (!commonColor.isEmpty() && abMana.getComboColors().contains(MagicColor.toShortString(commonColor))) {
|
||||||
choice = MagicColor.toShortString(commonColor);
|
choice = MagicColor.toShortString(commonColor);
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import forge.game.GameState;
|
|||||||
import forge.game.GlobalRuleChange;
|
import forge.game.GlobalRuleChange;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
import forge.game.ai.ComputerUtilBlock;
|
import forge.game.ai.ComputerUtilBlock;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -1573,7 +1574,7 @@ public class CombatUtil {
|
|||||||
enchantment = ((Card) check);
|
enchantment = ((Card) check);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
enchantment = CardFactoryUtil.getBestEnchantmentAI(enchantments, this, false);
|
enchantment = ComputerUtilCard.getBestEnchantmentAI(enchantments, this, false);
|
||||||
}
|
}
|
||||||
if ((enchantment != null) && attacker.isInPlay()) {
|
if ((enchantment != null) && attacker.isInPlay()) {
|
||||||
Singletons.getModel().getGame().getAction().changeZone(Singletons.getModel().getGame().getZoneOf(enchantment),
|
Singletons.getModel().getGame().getAction().changeZone(Singletons.getModel().getGame().getZoneOf(enchantment),
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ import forge.CardPredicates;
|
|||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.control.input.Input;
|
import forge.control.input.Input;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.Zone;
|
import forge.game.zone.Zone;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -246,7 +246,7 @@ public class Untap extends Phase {
|
|||||||
artList = CardLists.filter(artList, Presets.ARTIFACTS);
|
artList = CardLists.filter(artList, Presets.ARTIFACTS);
|
||||||
artList = CardLists.filter(artList, tappedCanUntap);
|
artList = CardLists.filter(artList, tappedCanUntap);
|
||||||
if (artList.size() > 0) {
|
if (artList.size() > 0) {
|
||||||
CardFactoryUtil.getBestArtifactAI(artList).untap();
|
ComputerUtilCard.getBestArtifactAI(artList).untap();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final Input target = new Input() {
|
final Input target = new Input() {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import forge.control.input.InputSelectManyCards;
|
|||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.ai.ComputerUtilMana;
|
import forge.game.ai.ComputerUtilMana;
|
||||||
@@ -501,7 +502,7 @@ public class Upkeep extends Phase {
|
|||||||
if (indestruct.size() > 0) {
|
if (indestruct.size() > 0) {
|
||||||
game.getAction().destroyNoRegeneration(indestruct.get(0));
|
game.getAction().destroyNoRegeneration(indestruct.get(0));
|
||||||
} else if (targets.size() > 0) {
|
} else if (targets.size() > 0) {
|
||||||
final Card target = CardFactoryUtil.getWorstCreatureAI(targets);
|
final Card target = ComputerUtilCard.getWorstCreatureAI(targets);
|
||||||
if (null == target) {
|
if (null == target) {
|
||||||
// must be nothing valid to destroy
|
// must be nothing valid to destroy
|
||||||
} else {
|
} else {
|
||||||
@@ -632,7 +633,7 @@ public class Upkeep extends Phase {
|
|||||||
if (c.getController().isComputer()) {
|
if (c.getController().isComputer()) {
|
||||||
target = GuiChoose.one("Select a card to sacrifice", playerLand);
|
target = GuiChoose.one("Select a card to sacrifice", playerLand);
|
||||||
} else {
|
} else {
|
||||||
target = CardFactoryUtil.getBestLandAI(playerLand);
|
target = ComputerUtilCard.getBestLandAI(playerLand);
|
||||||
}
|
}
|
||||||
game.getAction().sacrifice(target, null);
|
game.getAction().sacrifice(target, null);
|
||||||
} // end resolve()
|
} // end resolve()
|
||||||
@@ -1027,7 +1028,7 @@ public class Upkeep extends Phase {
|
|||||||
|
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
if (player.isComputer()) {
|
if (player.isComputer()) {
|
||||||
Card toTap = CardFactoryUtil.getWorstPermanentAI(list, false, false, false, false);
|
Card toTap = ComputerUtilCard.getWorstPermanentAI(list, false, false, false, false);
|
||||||
// try to find non creature cards without tap abilities
|
// try to find non creature cards without tap abilities
|
||||||
List<Card> betterList = CardLists.filter(list, new Predicate<Card>() {
|
List<Card> betterList = CardLists.filter(list, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import forge.Card;
|
|||||||
|
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.AiController;
|
import forge.game.ai.AiController;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
@@ -175,7 +175,7 @@ public class AIPlayer extends Player {
|
|||||||
public final void sacrificePermanent(final String prompt, final List<Card> choices) {
|
public final void sacrificePermanent(final String prompt, final List<Card> choices) {
|
||||||
if (choices.size() > 0) {
|
if (choices.size() > 0) {
|
||||||
// TODO - this could probably use better AI
|
// TODO - this could probably use better AI
|
||||||
final Card c = CardFactoryUtil.getWorstPermanentAI(choices, false, false, false, false);
|
final Card c = ComputerUtilCard.getWorstPermanentAI(choices, false, false, false, false);
|
||||||
game.getAction().sacrificeDestroy(c);
|
game.getAction().sacrificeDestroy(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import forge.control.input.InputPayManaExecuteCommands;
|
|||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.event.SpellResolvedEvent;
|
import forge.game.event.SpellResolvedEvent;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -901,9 +902,9 @@ public class MagicStack extends MyObservable {
|
|||||||
// AI choosing what to haunt
|
// AI choosing what to haunt
|
||||||
final List<Card> oppCreats = CardLists.filterControlledBy(creats, source.getController().getOpponents());
|
final List<Card> oppCreats = CardLists.filterControlledBy(creats, source.getController().getOpponents());
|
||||||
if (oppCreats.size() != 0) {
|
if (oppCreats.size() != 0) {
|
||||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(oppCreats));
|
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(oppCreats));
|
||||||
} else {
|
} else {
|
||||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(creats));
|
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(creats));
|
||||||
}
|
}
|
||||||
this.add(haunterDiesWork);
|
this.add(haunterDiesWork);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,4 +107,22 @@ public class GuiDownloadPicturesLQ extends GuiDownloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the ideal filename.
|
||||||
|
*
|
||||||
|
* @param cardName
|
||||||
|
* the card name
|
||||||
|
* @param artIndex
|
||||||
|
* the art index
|
||||||
|
* @param artIndexMax
|
||||||
|
* the art index max
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
public static String buildIdealFilename(final String cardName, final int artIndex, final int artIndexMax) {
|
||||||
|
final String nn = artIndexMax > 1 ? Integer.toString(artIndex + 1) : "";
|
||||||
|
final String mwsCardName = GuiDisplayUtil.cleanStringMWS(cardName);
|
||||||
|
// 3 letter set code with MWS filename format
|
||||||
|
return String.format("%s%s.full.jpg", mwsCardName, nn);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloader {
|
|||||||
|
|
||||||
if (!foundSetImage) {
|
if (!foundSetImage) {
|
||||||
final int artsCnt = c.getRules().getEditionInfo(setCode3).getCopiesCount();
|
final int artsCnt = c.getRules().getEditionInfo(setCode3).getCopiesCount();
|
||||||
final String filename = CardUtil.buildIdealFilename(cardName, c.getArtIndex(), artsCnt);
|
final String filename = GuiDownloadPicturesLQ.buildIdealFilename(cardName, c.getArtIndex(), artsCnt);
|
||||||
String url = urlBase + setCode2 + "/" + Base64Coder.encodeString(filename, true);
|
String url = urlBase + setCode2 + "/" + Base64Coder.encodeString(filename, true);
|
||||||
cList.add(new DownloadObject(url, new File(this.picturesPath + File.separator + setCode3, filename)));
|
cList.add(new DownloadObject(url, new File(this.picturesPath + File.separator + setCode3, filename)));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user