- The AI can now use spellAbilities giving shroud to creatures to protect them from spellAbilities on the stack.

This commit is contained in:
Sloth
2012-02-24 14:03:18 +00:00
parent 3132a376ee
commit e72f5f93a0
3 changed files with 50 additions and 38 deletions

View File

@@ -1929,11 +1929,11 @@ public class ComputerUtil {
*/ */
public static boolean containsUsefulKeyword(final ArrayList<String> keywords, final Card card) { public static boolean containsUsefulKeyword(final ArrayList<String> keywords, final Card card) {
for (final String keyword : keywords) { for (final String keyword : keywords) {
if (ComputerUtil.isUsefulKeyword(keyword, card)) { if (!ComputerUtil.isUsefulKeyword(keyword, card)) {
return true; return false;
} }
} }
return false; return true;
} }
/** /**
@@ -1978,9 +1978,6 @@ public class ComputerUtil {
if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card)) { if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card)) {
return false; return false;
} }
} else if (keyword.endsWith("Shroud")) {
// TODO: check stack for spells and abilities
return false;
} else if (keyword.startsWith("Rampage")) { } else if (keyword.startsWith("Rampage")) {
if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card) if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card)
|| (AllZoneUtil.getCreaturesInPlay(human).size() < 2)) { || (AllZoneUtil.getCreaturesInPlay(human).size() < 2)) {

View File

@@ -2272,8 +2272,10 @@ public class AbilityFactory {
ArrayList<Object> objects = new ArrayList<Object>(); ArrayList<Object> objects = new ArrayList<Object>();
final ArrayList<Object> threatened = new ArrayList<Object>(); final ArrayList<Object> threatened = new ArrayList<Object>();
String saviourApi = ""; String saviourApi = "";
HashMap<String, String> saviourParams = null;
if (saviourAf != null) { if (saviourAf != null) {
saviourApi = saviourAf.getAPI(); saviourApi = saviourAf.getAPI();
saviourParams = saviourAf.getMapParams();
} }
if (topStack == null) { if (topStack == null) {
@@ -2299,7 +2301,7 @@ public class AbilityFactory {
final String threatApi = topAf.getAPI(); final String threatApi = topAf.getAPI();
final HashMap<String, String> threatParams = topAf.getMapParams(); final HashMap<String, String> threatParams = topAf.getMapParams();
// Lethal Damage => prevent damage/regeneration/bounce // Lethal Damage => prevent damage/regeneration/bounce/shroud
if (threatApi.equals("DealDamage") || threatApi.equals("DamageAll")) { if (threatApi.equals("DealDamage") || threatApi.equals("DamageAll")) {
// If PredictDamage is >= Lethal Damage // If PredictDamage is >= Lethal Damage
final int dmg = AbilityFactory.calculateAmount(topStack.getSourceCard(), final int dmg = AbilityFactory.calculateAmount(topStack.getSourceCard(),
@@ -2323,6 +2325,13 @@ public class AbilityFactory {
continue; continue;
} }
// give Shroud to targeted creatures
if (saviourApi.equals("Pump") && tgt == null && saviourParams.containsKey("KW")
&& (saviourParams.get("KW").endsWith("Shroud")
|| saviourParams.get("KW").endsWith("Hexproof"))) {
continue;
}
// don't bounce or blink a permanent that the human // don't bounce or blink a permanent that the human
// player owns or is a token // player owns or is a token
if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) { if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) {
@@ -2345,10 +2354,10 @@ public class AbilityFactory {
} }
} }
} }
// Destroy => regeneration/bounce // Destroy => regeneration/bounce/shroud
else if ((threatApi.equals("Destroy") || threatApi.equals("DestroyAll")) else if ((threatApi.equals("Destroy") || threatApi.equals("DestroyAll"))
&& ((saviourApi.equals("Regenerate") && !threatParams.containsKey("NoRegen")) || saviourApi && ((saviourApi.equals("Regenerate") && !threatParams.containsKey("NoRegen")) || saviourApi
.equals("ChangeZone"))) { .equals("ChangeZone") || saviourApi.equals("Pump"))) {
for (final Object o : objects) { for (final Object o : objects) {
if (o instanceof Card) { if (o instanceof Card) {
final Card c = (Card) o; final Card c = (Card) o;
@@ -2362,6 +2371,13 @@ public class AbilityFactory {
continue; continue;
} }
// give Shroud to targeted creatures
if (saviourApi.equals("Pump") && tgt == null && saviourParams.containsKey("KW")
&& (saviourParams.get("KW").endsWith("Shroud")
|| saviourParams.get("KW").endsWith("Hexproof"))) {
continue;
}
// don't bounce or blink a permanent that the human // don't bounce or blink a permanent that the human
// player owns or is a token // player owns or is a token
if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) { if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) {
@@ -2376,13 +2392,21 @@ public class AbilityFactory {
} }
} }
} }
// Exiling => bounce // Exiling => bounce/shroud
else if ((threatApi.equals("ChangeZone") || threatApi.equals("ChangeZoneAll")) else if ((threatApi.equals("ChangeZone") || threatApi.equals("ChangeZoneAll"))
&& saviourApi.equals("ChangeZone") && threatParams.containsKey("Destination") && (saviourApi.equals("ChangeZone") || saviourApi.equals("Pump"))
&& threatParams.containsKey("Destination")
&& threatParams.get("Destination").equals("Exile")) { && threatParams.get("Destination").equals("Exile")) {
for (final Object o : objects) { for (final Object o : objects) {
if (o instanceof Card) { if (o instanceof Card) {
final Card c = (Card) o; final Card c = (Card) o;
// give Shroud to targeted creatures
if (saviourApi.equals("Pump") && tgt == null && saviourParams.containsKey("KW")
&& (saviourParams.get("KW").endsWith("Shroud")
|| saviourParams.get("KW").endsWith("Hexproof"))) {
continue;
}
// don't bounce or blink a permanent that the human // don't bounce or blink a permanent that the human
// player owns or is a token // player owns or is a token
if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) { if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) {

View File

@@ -278,6 +278,11 @@ public class AbilityFactoryPump {
return false; return false;
} }
if ((keywords.contains("Shroud") || keywords.contains("Hexproof"))
&& AbilityFactory.predictThreatenedObjects(sa.getAbilityFactory()).contains(this)) {
return true;
}
// will the creature attack (only relevant for sorcery speed)? // will the creature attack (only relevant for sorcery speed)?
if (CardFactoryUtil.doesCreatureAttackAI(c) if (CardFactoryUtil.doesCreatureAttackAI(c)
&& AllZone.getPhaseHandler().isBefore(Constant.Phase.COMBAT_DECLARE_ATTACKERS) && AllZone.getPhaseHandler().isBefore(Constant.Phase.COMBAT_DECLARE_ATTACKERS)
@@ -372,15 +377,16 @@ public class AbilityFactoryPump {
} // getCurseCreatures() } // getCurseCreatures()
private boolean containsCombatRelevantKeyword(final ArrayList<String> keywords) { private boolean containsCombatRelevantKeyword(final ArrayList<String> keywords) {
boolean flag = false;
for (final String keyword : keywords) { for (final String keyword : keywords) {
// since most keywords are combat relevant check for those that are // since most keywords are combat relevant check for those that are
// not // not
if (!keyword.equals("HIDDEN This card doesn't untap during your next untap step.")) { if (keyword.equals("HIDDEN This card doesn't untap during your next untap step.")
flag = true; || keyword.endsWith("Shroud") || keyword.endsWith("Hexproof")) {
continue;
} }
return true;
} }
return flag; return false;
} }
/** /**
@@ -426,11 +432,9 @@ public class AbilityFactoryPump {
return false; return false;
} }
} else if (AllZone.getStack().size() > 0) { } else if (AllZone.getStack().size() > 0) {
// TODO: pump something only if the top thing on the stack will kill if (!this.keywords.contains("Shroud") && !this.keywords.contains("Hexproof")) {
// it via damage return false;
// or if top thing on stack will pump it/enchant it and I want to }
// kill it
return false;
} }
final int activations = restrict.getNumberTurnActivations(); final int activations = restrict.getNumberTurnActivations();
@@ -479,21 +483,12 @@ public class AbilityFactoryPump {
return false; return false;
} }
final boolean givesKws = !this.keywords.get(0).equals("none");
String[] kwPump = { "none" };
if (givesKws) {
kwPump = this.keywords.toArray(new String[this.keywords.size()]);
}
final String[] keywords = kwPump;
// when this happens we need to expand AI to consider if its ok for // when this happens we need to expand AI to consider if its ok for
// everything? // everything?
for (final Card card : cards) { for (final Card card : cards) {
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
// Don't add duplicate keywords if (!ComputerUtil.containsUsefulKeyword(this.keywords, card)) {
final boolean hKW = card.hasAnyKeyword(keywords);
if (givesKws && hKW) {
return false; return false;
} }
@@ -501,18 +496,14 @@ public class AbilityFactoryPump {
if (card.getController().isComputer()) { if (card.getController().isComputer()) {
return false; return false;
} }
if (!ComputerUtil.containsUsefulKeyword(this.keywords, card)) {
return false;
}
return (r.nextFloat() <= Math.pow(.6667, activations)); return (r.nextFloat() <= Math.pow(.6667, activations));
} }
if (((card.getNetDefense() + defense) > 0) && (!card.hasAnyKeyword(this.keywords))) { if (((card.getNetDefense() + defense) > 0) && (!card.hasAnyKeyword(this.keywords))) {
if (card.hasSickness() && this.keywords.contains("Haste")) { if ((keywords.contains("Shroud") || keywords.contains("Hexproof"))
return true; && AbilityFactory.predictThreatenedObjects(sa.getAbilityFactory()).contains(card)) {
} else if (card.hasSickness() ^ this.keywords.contains("Haste")) { return (r.nextFloat() <= Math.pow(.6667, activations));
return false; } else if (this.hostCard.equals(card) && !this.keywords.contains("Haste")) {
} else if (this.hostCard.equals(card)) {
if (r.nextFloat() <= Math.pow(.6667, activations)) { if (r.nextFloat() <= Math.pow(.6667, activations)) {
return CardFactoryUtil.doesCreatureAttackAI(card) && !sa.getPayCosts().getTap(); return CardFactoryUtil.doesCreatureAttackAI(card) && !sa.getPayCosts().getTap();
} }