From cae9ebdef2ea5a38918de196eefe1b1e7d71afde Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 22:13:37 +0000 Subject: [PATCH] - AI will now predict battle cry boni. --- src/forge/CombatUtil.java | 112 +++++++++++++++++----------- src/forge/ComputerUtil_Attack2.java | 48 ++++++++---- src/forge/ComputerUtil_Block2.java | 26 +++---- src/forge/Computer_Race.java | 8 +- src/forge/RunTest.java | 2 +- 5 files changed, 123 insertions(+), 73 deletions(-) diff --git a/src/forge/CombatUtil.java b/src/forge/CombatUtil.java index 9fe0f5459f9..a73d725dc1c 100644 --- a/src/forge/CombatUtil.java +++ b/src/forge/CombatUtil.java @@ -601,7 +601,7 @@ public class CombatUtil { { int damage = attacker.getNetCombatDamage(); int sum = 0; - damage += predictPowerBonusOfAttacker(attacker,null); + damage += predictPowerBonusOfAttacker(attacker,null,null); if (!attacker.hasKeyword("Infect")) { sum = attacked.predictDamage(damage, attacker, true); if (attacker.hasKeyword("Double Strike")) sum += attacked.predictDamage(damage, attacker, true); @@ -614,7 +614,7 @@ public class CombatUtil { { int damage = attacker.getNetCombatDamage(); int poison = 0; - damage += predictPowerBonusOfAttacker(attacker,null); + damage += predictPowerBonusOfAttacker(attacker, null, null); if (attacker.hasKeyword("Infect")) { poison += attacked.predictDamage(damage, attacker, true); if (attacker.hasKeyword("Double Strike")) poison += attacked.predictDamage(damage, attacker, true); @@ -761,7 +761,7 @@ public class CombatUtil { // This calculates the amount of damage a blocker in a blockgang can take from the attacker (for trampling attackers) public static int shieldDamage(Card attacker, Card defender) { - if (!canDestroyBlocker(defender,attacker)) return 100; + if (!canDestroyBlocker(defender,attacker, null)) return 100; int flankingMagnitude = 0; if(attacker.getKeyword().contains("Flanking") && !defender.getKeyword().contains("Flanking")) { @@ -796,7 +796,7 @@ public class CombatUtil { CardList blockers = AllZone.Combat.getBlockers(attacker); for (Card defender:blockers) { - if(CombatUtil.canDestroyAttacker(attacker, defender) && + if(CombatUtil.canDestroyAttacker(attacker, defender, AllZone.Combat) && !(defender.getKeyword().contains("Wither") || defender.getKeyword().contains("Infect"))) return true; } @@ -805,20 +805,24 @@ public class CombatUtil { } //Will this trigger trigger? - public static boolean combatTriggerWillTrigger(Card attacker, Card defender, Trigger trigger) { + public static boolean combatTriggerWillTrigger(Card attacker, Card defender, Trigger trigger, Combat combat) { HashMap trigParams = trigger.getMapParams(); boolean willTrigger = false; Card source = trigger.getHostCard(); + if (combat == null) combat = AllZone.Combat; if (!trigger.zonesCheck()) return false; if (!trigger.requirementsCheck()) return false; if (trigParams.get("Mode").equals("Attacks")) { willTrigger = true; - if (attacker.isAttacking()) return false; //The trigger should have triggered already - if(trigParams.containsKey("ValidCard")) - if(!trigger.matchesValid(attacker, trigParams.get("ValidCard").split(","), source)) + if(attacker.isAttacking()) return false; //The trigger should have triggered already + if(trigParams.containsKey("ValidCard")) { + if(!trigger.matchesValid(attacker, trigParams.get("ValidCard").split(","), source) + && !(combat.isAttacking(source) && + trigger.matchesValid(source, trigParams.get("ValidCard").split(","), source))) return false; + } } // defender == null means unblocked @@ -876,14 +880,14 @@ public class CombatUtil { HashMap trigParams = trigger.getMapParams(); Card source = trigger.getHostCard(); - if(combatTriggerWillTrigger(attacker, defender, trigger) && trigParams.containsKey("Execute")) { + if(combatTriggerWillTrigger(attacker, defender, trigger, null) && trigParams.containsKey("Execute")) { String ability = source.getSVar(trigParams.get("Execute")); AbilityFactory AF = new AbilityFactory(); HashMap abilityParams = AF.getMapParams(ability, source); if (abilityParams.containsKey("AB")) { if (abilityParams.get("AB").equals("Pump")) if (!abilityParams.containsKey("ValidTgts") && !abilityParams.containsKey("Tgt")) - if (AbilityFactory.getDefinedCards(source, trigParams.get("Defined"), null).contains(defender)) + if (AbilityFactory.getDefinedCards(source, abilityParams.get("Defined"), null).contains(defender)) if (abilityParams.containsKey("NumAtt")){ String att = abilityParams.get("NumAtt"); if (att.startsWith("+")) @@ -911,14 +915,14 @@ public class CombatUtil { HashMap trigParams = trigger.getMapParams(); Card source = trigger.getHostCard(); - if(combatTriggerWillTrigger(attacker, defender, trigger) && trigParams.containsKey("Execute")) { + if(combatTriggerWillTrigger(attacker, defender, trigger, null) && trigParams.containsKey("Execute")) { String ability = source.getSVar(trigParams.get("Execute")); AbilityFactory AF = new AbilityFactory(); HashMap abilityParams = AF.getMapParams(ability, source); if (abilityParams.containsKey("AB")) { if (abilityParams.get("AB").equals("Pump")) if (!abilityParams.containsKey("ValidTgts") && !abilityParams.containsKey("Tgt")) - if (AbilityFactory.getDefinedCards(source, trigParams.get("Defined"), null).contains(defender)) + if (AbilityFactory.getDefinedCards(source, abilityParams.get("Defined"), null).contains(defender)) if (abilityParams.containsKey("NumDef")) { String def = abilityParams.get("NumDef"); if (def.startsWith("+")) @@ -932,7 +936,7 @@ public class CombatUtil { } //Predict the Power bonus of the blocker if blocking the attacker (Flanking, Bushido and other triggered abilities) - public static int predictPowerBonusOfAttacker(Card attacker, Card defender) { + public static int predictPowerBonusOfAttacker(Card attacker, Card defender, Combat combat) { int power = 0; power += attacker.getKeywordMagnitude("Bushido"); @@ -952,26 +956,38 @@ public class CombatUtil { HashMap trigParams = trigger.getMapParams(); Card source = trigger.getHostCard(); - if(combatTriggerWillTrigger(attacker, defender, trigger) && trigParams.containsKey("Execute")) { + if(combatTriggerWillTrigger(attacker, defender, trigger, combat) && trigParams.containsKey("Execute")) { String ability = source.getSVar(trigParams.get("Execute")); AbilityFactory AF = new AbilityFactory(); HashMap abilityParams = AF.getMapParams(ability, source); - if (abilityParams.containsKey("AB")) { + if (abilityParams.containsKey("AB")) { + boolean isValid = false; + + //Pump if (abilityParams.get("AB").equals("Pump")) - if (!abilityParams.containsKey("ValidTgts") && !abilityParams.containsKey("Tgt")) - if (AbilityFactory.getDefinedCards(source, trigParams.get("Defined"), null).contains(attacker)) - if (abilityParams.containsKey("NumAtt")){ - String att = abilityParams.get("NumAtt"); - if (att.startsWith("+")) - att = att.substring(1); - try { - power += Integer.parseInt(att); - } - catch(NumberFormatException nfe) { - //can't parse the number (X for example) - power += 0; - } + if (!abilityParams.containsKey("ValidTgts") && !abilityParams.containsKey("Tgt")) //not targeted + if (AbilityFactory.getDefinedCards(source, abilityParams.get("Defined"), null).contains(attacker)) + isValid = true; + + //PumpAll + if (abilityParams.get("AB").equals("PumpAll") && abilityParams.containsKey("ValidCards")) + if (attacker.isValidCard(abilityParams.get("ValidCards").split(","), source.getController(), source) + || attacker.isValidCard(abilityParams.get("ValidCards").replace("attacking+", "").split(",") + , source.getController(), source)) + isValid = true; + + if (abilityParams.containsKey("NumAtt") && isValid){ + String att = abilityParams.get("NumAtt"); + if (att.startsWith("+")) + att = att.substring(1); + try { + power += Integer.parseInt(att); } + catch(NumberFormatException nfe) { + //can't parse the number (X for example) + power += 0; + } + } } } } @@ -979,7 +995,7 @@ public class CombatUtil { } //Predict the Toughness bonus of the blocker if blocking the attacker (Flanking, Bushido and other triggered abilities) - public static int predictToughnessBonusOfAttacker(Card attacker, Card defender) { + public static int predictToughnessBonusOfAttacker(Card attacker, Card defender, Combat combat) { int toughness = 0; toughness += attacker.getKeywordMagnitude("Bushido"); @@ -990,15 +1006,27 @@ public class CombatUtil { HashMap trigParams = trigger.getMapParams(); Card source = trigger.getHostCard(); - if(combatTriggerWillTrigger(attacker, defender, trigger) && trigParams.containsKey("Execute")) { + if(combatTriggerWillTrigger(attacker, defender, trigger, combat) && trigParams.containsKey("Execute")) { String ability = source.getSVar(trigParams.get("Execute")); AbilityFactory AF = new AbilityFactory(); HashMap abilityParams = AF.getMapParams(ability, source); if (abilityParams.containsKey("AB")) { + boolean isValid = false; + + //Pump if (abilityParams.get("AB").equals("Pump")) - if (!abilityParams.containsKey("ValidTgts") && !abilityParams.containsKey("Tgt")) - if (AbilityFactory.getDefinedCards(source, trigParams.get("Defined"), null).contains(attacker)) - if (abilityParams.containsKey("NumDef")) { + if (!abilityParams.containsKey("ValidTgts") && !abilityParams.containsKey("Tgt")) //not targeted + if (AbilityFactory.getDefinedCards(source, abilityParams.get("Defined"), null).contains(attacker)) + isValid = true; + + //PumpAll + if (abilityParams.get("AB").equals("PumpAll") && abilityParams.containsKey("ValidCards")) + if (attacker.isValidCard(abilityParams.get("ValidCards").split(","), source.getController(), source) + || attacker.isValidCard(abilityParams.get("ValidCards").replace("attacking+", "").split(",") + , source.getController(), source)) + isValid = true; + + if (abilityParams.containsKey("NumDef") && isValid){ String def = abilityParams.get("NumDef"); if (def.startsWith("+")) def = def.substring(1); @@ -1017,7 +1045,7 @@ public class CombatUtil { } //can the blocker destroy the attacker? - public static boolean canDestroyAttacker(Card attacker, Card defender) { + public static boolean canDestroyAttacker(Card attacker, Card defender, Combat combat) { if(attacker.getName().equals("Sylvan Basilisk") && !defender.getKeyword().contains("Indestructible")) return false; @@ -1039,10 +1067,10 @@ public class CombatUtil { //int attBushidoMagnitude = attacker.getKeywordMagnitude("Bushido"); int defenderDamage = defender.getNetAttack() + predictPowerBonusOfBlocker(attacker, defender); - int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender); + int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender, combat); if (AllZoneUtil.isCardInPlay("Doran, the Siege Tower")) { defenderDamage = defender.getNetDefense() + predictToughnessBonusOfBlocker(attacker, defender); - attackerDamage = attacker.getNetDefense() + predictToughnessBonusOfAttacker(attacker, defender); + attackerDamage = attacker.getNetDefense() + predictToughnessBonusOfAttacker(attacker, defender, combat); } // consider Damage Prevention/Replacement @@ -1050,7 +1078,7 @@ public class CombatUtil { attackerDamage = defender.predictDamage(attackerDamage, attacker, true); int defenderLife = defender.getKillDamage() + predictToughnessBonusOfBlocker(attacker, defender); - int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender); + int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender, combat); if(defender.getKeyword().contains("Double Strike") ) { if(defender.getKeyword().contains("Deathtouch") && defenderDamage > 0) return true; @@ -1088,14 +1116,14 @@ public class CombatUtil { public static boolean blockerWouldBeDestroyed(Card blocker) { Card attacker = AllZone.Combat.getAttackerBlockedBy(blocker); - if(canDestroyBlocker(blocker, attacker) && + if(canDestroyBlocker(blocker, attacker, AllZone.Combat) && !(attacker.getKeyword().contains("Wither") || attacker.getKeyword().contains("Infect"))) return true; return false; } //can the attacker destroy this blocker? - public static boolean canDestroyBlocker(Card defender, Card attacker) { + public static boolean canDestroyBlocker(Card defender, Card attacker, Combat combat) { int flankingMagnitude = 0; if(attacker.getKeyword().contains("Flanking") && !defender.getKeyword().contains("Flanking")) { @@ -1112,10 +1140,10 @@ public class CombatUtil { if(attacker.getName().equals("Sylvan Basilisk") && !defender.getKeyword().contains("Indestructible")) return true; int defenderDamage = defender.getNetAttack() + predictPowerBonusOfBlocker(attacker, defender); - int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender); + int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender, combat); if (AllZoneUtil.isCardInPlay("Doran, the Siege Tower")) { defenderDamage = defender.getNetDefense() + predictToughnessBonusOfBlocker(attacker, defender); - attackerDamage = attacker.getNetDefense() + predictToughnessBonusOfAttacker(attacker, defender); + attackerDamage = attacker.getNetDefense() + predictToughnessBonusOfAttacker(attacker, defender, combat); } // consider Damage Prevention/Replacement @@ -1123,7 +1151,7 @@ public class CombatUtil { attackerDamage = defender.predictDamage(attackerDamage, attacker, true); int defenderLife = defender.getKillDamage() + predictToughnessBonusOfBlocker(attacker, defender); - int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender); + int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender, combat); if(attacker.getKeyword().contains("Double Strike") ) { if(attacker.getKeyword().contains("Deathtouch") && attackerDamage > 0) return true; diff --git a/src/forge/ComputerUtil_Attack2.java b/src/forge/ComputerUtil_Attack2.java index 81d427ebc93..562e1dd7edc 100644 --- a/src/forge/ComputerUtil_Attack2.java +++ b/src/forge/ComputerUtil_Attack2.java @@ -1,9 +1,11 @@ package forge; import java.util.ArrayList; +import java.util.HashMap; import java.util.Random; import forge.card.cardFactory.CardFactoryUtil; +import forge.card.trigger.Trigger; //doesHumanAttackAndWin() uses the global variable AllZone.ComputerPlayer public class ComputerUtil_Attack2 { @@ -41,7 +43,29 @@ public class ComputerUtil_Attack2 { blockers = getPossibleBlockers(possibleBlockers, attackers); this.blockerLife = blockerLife; }//constructor - + + public CardList sortAttackers(CardList in) + { + CardList list = new CardList(); + + //Cards with triggers should come first (for Battle Cry) + for(Card attacker:in) { + ArrayList registeredTriggers = AllZone.TriggerHandler.getRegisteredTriggers(); + for(Trigger trigger : registeredTriggers) + { + HashMap trigParams = trigger.getMapParams(); + if (trigParams.get("Mode").equals("Attacks") && trigger.getHostCard().equals(attacker)) + list.add(attacker); + } + } + + for(Card attacker:in) { + if(!list.contains(attacker)) list.add(attacker); + } + + return list; + }//sortAttackers() + public CardList getPossibleAttackers(CardList in) { CardList list = new CardList(in.toArray()); @@ -358,7 +382,8 @@ public class ComputerUtil_Attack2 { aiAggression = 5; // attack at all costs }else if((playerLifeToDamageRatio < 2 && ratioDiff >= 0) || ratioDiff > 3 || (ratioDiff > 0 && outNumber > 0)){ aiAggression = 3; // attack expecting to kill creatures or damage player. - }else if(ratioDiff >= 0 || ratioDiff + outNumber >= -1){ // at 0 ratio expect to potentially gain an advantage by attacking first + }else if(ratioDiff >= 0 || ratioDiff + outNumber >= -1){ + // at 0 ratio expect to potentially gain an advantage by attacking first // if the ai has a slight advantage // or the ai has a significant advantage numerically but only a slight disadvantage damage/life aiAggression = 2; // attack expecting to destroy creatures/be unblockable @@ -412,15 +437,12 @@ public class ComputerUtil_Attack2 { else { System.out.println("Normal attack"); - //so the biggest creature will usually attack - //I think this works, not sure, may have to change it - //sortNonFlyingFirst has to be done first, because it reverses everything - CardListUtil.sortNonFlyingFirst(attackersLeft); - CardListUtil.sortAttackLowFirst(attackersLeft); - + attackersLeft = notNeededAsBlockers(attackersLeft, combat); - System.out.println(attackersLeft.size()); - + System.out.println(attackersLeft.size()); + + attackersLeft = sortAttackers(attackersLeft); + for(int i = 0; i < attackersLeft.size(); i++) { Card attacker = attackersLeft.get(i); @@ -428,7 +450,7 @@ public class ComputerUtil_Attack2 { if (!attacker.hasFirstStrike() && !attacker.hasDoubleStrike()) totalFirstStrikeBlockPower = CombatUtil.getTotalFirstStrikeBlockPower(attacker, AllZone.HumanPlayer); - if ( shouldAttack(attacker,blockers, combat) && (totalFirstStrikeBlockPower < attacker.getKillDamage() || aiAggression == 5) + if (shouldAttack(attacker,blockers,combat) && (totalFirstStrikeBlockPower < attacker.getKillDamage() || aiAggression == 5) && CombatUtil.canAttack(attacker, combat)) combat.addAttacker(attacker); } @@ -474,7 +496,7 @@ public class ComputerUtil_Attack2 { for (Card defender:defenders) { if(CombatUtil.canBlock(attacker, defender)){ //, combat )) { canBeBlocked = true; - if(CombatUtil.canDestroyAttacker(attacker, defender)) { + if(CombatUtil.canDestroyAttacker(attacker, defender, combat)) { canBeKilledByOne = true; // there is a single creature on the battlefield that can kill the creature // see if the defending creature is of higher or lower value. We don't want to attack only to lose value if(CardFactoryUtil.evaluateCreature(defender) <= CardFactoryUtil.evaluateCreature(attacker)){ @@ -482,7 +504,7 @@ public class ComputerUtil_Attack2 { } } // see if this attacking creature can destroy this defender, if not record that it can't kill everything - if(!CombatUtil.canDestroyBlocker(defender, attacker)){ + if(!CombatUtil.canDestroyBlocker(defender, attacker, combat)){ canKillAll = false; if(defender.getKeyword().contains("Wither") || defender.getKeyword().contains("Infect")){ canKillAllDangerous = false; // there is a dangerous creature that can survive an attack from this creature diff --git a/src/forge/ComputerUtil_Block2.java b/src/forge/ComputerUtil_Block2.java index 0e890c7a3b2..4c226ae0e98 100644 --- a/src/forge/ComputerUtil_Block2.java +++ b/src/forge/ComputerUtil_Block2.java @@ -28,22 +28,22 @@ public class ComputerUtil_Block2 } //finds blockers that won't be destroyed - private static CardList getSafeBlockers(Card attacker, CardList blockersLeft) { + private static CardList getSafeBlockers(Card attacker, CardList blockersLeft, Combat combat) { CardList blockers = new CardList(); for(Card b : blockersLeft) { - if(!CombatUtil.canDestroyBlocker(b,attacker)) blockers.add(b); + if(!CombatUtil.canDestroyBlocker(b,attacker, combat)) blockers.add(b); } return blockers; } //finds blockers that destroy the attacker - private static CardList getKillingBlockers(Card attacker, CardList blockersLeft) { + private static CardList getKillingBlockers(Card attacker, CardList blockersLeft, Combat combat) { CardList blockers = new CardList(); for(Card b : blockersLeft) { - if(CombatUtil.canDestroyAttacker(attacker,b)) blockers.add(b); + if(CombatUtil.canDestroyAttacker(attacker,b,combat)) blockers.add(b); } return blockers; @@ -102,12 +102,12 @@ public class ComputerUtil_Block2 CardList blockers = getPossibleBlockers(attacker, blockersLeft, combat); - CardList safeBlockers = getSafeBlockers(attacker, blockers); + CardList safeBlockers = getSafeBlockers(attacker, blockers, combat); CardList killingBlockers = new CardList(); if(safeBlockers.size() > 0) { // 1.Blockers that can destroy the attacker but won't get destroyed - killingBlockers = getKillingBlockers(attacker, safeBlockers); + killingBlockers = getKillingBlockers(attacker, safeBlockers, combat); if(killingBlockers.size() > 0) blocker = CardFactoryUtil.AI_getWorstCreature(killingBlockers); // 2.Blockers that won't get destroyed @@ -117,7 +117,7 @@ public class ComputerUtil_Block2 } } // no safe blockers else { - killingBlockers = getKillingBlockers(attacker, blockers); + killingBlockers = getKillingBlockers(attacker, blockers, combat); if(killingBlockers.size() > 0) { // 3.Blockers that can destroy the attacker and are worth less Card worst = CardFactoryUtil.AI_getWorstCreature(killingBlockers); @@ -183,7 +183,7 @@ public class ComputerUtil_Block2 for(Card attacker : attackersLeft) { killingBlockers = - getKillingBlockers(attacker, getPossibleBlockers(attacker, blockersLeft, combat)); + getKillingBlockers(attacker, getPossibleBlockers(attacker, blockersLeft, combat), combat); if(killingBlockers.size() > 0 && CombatUtil.lifeInDanger(combat)) { Card blocker = CardFactoryUtil.AI_getWorstCreature(killingBlockers); combat.addBlocker(attacker, blocker); @@ -254,7 +254,7 @@ public class ComputerUtil_Block2 blockers = getPossibleBlockers(attacker, blockersLeft, combat); //Try to use safe blockers first - safeBlockers = getSafeBlockers(attacker, blockers); + safeBlockers = getSafeBlockers(attacker, blockers, combat); for(Card blocker : safeBlockers) { //Add an additional blocker if the current blockers are not enough and the new one would deal additional damage if(attacker.getKillDamage() > CombatUtil.totalDamageOfBlockers(attacker,combat.getBlockers(attacker)) @@ -358,8 +358,8 @@ public class ComputerUtil_Block2 if (CombatUtil.lifeInDanger(combat)) combat = makeChumpBlocks(combat); //choose necessary chump blocks if life is still in danger //Reinforce blockers blocking attackers with trample if life is still in danger if (CombatUtil.lifeInDanger(combat)) combat = reinforceBlockersAgainstTrample(combat); - if (!CombatUtil.lifeInDanger(combat)) combat = makeGangBlocks(combat); - if (!CombatUtil.lifeInDanger(combat)) combat = reinforceBlockersToKill(combat); + combat = makeGangBlocks(combat); + combat = reinforceBlockersToKill(combat); } //== 3. If the AI life would be in serious danger make an even safer approach == @@ -370,9 +370,9 @@ public class ComputerUtil_Block2 if (!CombatUtil.lifeInDanger(combat)) combat = makeGoodBlocks(combat); //Reinforce blockers blocking attackers with trample if life is still in danger if (CombatUtil.lifeInDanger(combat)) combat = reinforceBlockersAgainstTrample(combat); - if (!CombatUtil.lifeInDanger(combat)) combat = makeGangBlocks(combat); + combat = makeGangBlocks(combat); //Support blockers not destroying the attacker with more blockers to try to kill the attacker - if (!CombatUtil.lifeInDanger(combat)) combat = reinforceBlockersToKill(combat); + combat = reinforceBlockersToKill(combat); } // assign blockers that have to block diff --git a/src/forge/Computer_Race.java b/src/forge/Computer_Race.java index 1c3a578b1f1..7417b07d415 100644 --- a/src/forge/Computer_Race.java +++ b/src/forge/Computer_Race.java @@ -91,8 +91,8 @@ public class Computer_Race CardList c = blockList; for(int i = 0; i < c.size(); i++) - if(CombatUtil.canDestroyAttacker(attacker, c.get(i)) && - (! CombatUtil.canDestroyBlocker(c.get(i), attacker))) + if(CombatUtil.canDestroyAttacker(attacker, c.get(i), null) && + (! CombatUtil.canDestroyBlocker(c.get(i), attacker, null))) return c.get(i); return null; @@ -105,7 +105,7 @@ public class Computer_Race CardList c = blockList; for(int i = 0; i < c.size(); i++) - if(CombatUtil.canDestroyAttacker(attacker, c.get(i))) + if(CombatUtil.canDestroyAttacker(attacker, c.get(i), null)) return c.get(i); return null; @@ -118,7 +118,7 @@ public class Computer_Race CardList c = blockList; for(int i = 0; i < c.size(); i++) - if(! CombatUtil.canDestroyBlocker(c.get(i), attacker)) + if(! CombatUtil.canDestroyBlocker(c.get(i), attacker, null)) return c.get(i); return null; diff --git a/src/forge/RunTest.java b/src/forge/RunTest.java index badd506b4ca..ae67116511d 100644 --- a/src/forge/RunTest.java +++ b/src/forge/RunTest.java @@ -300,7 +300,7 @@ public class RunTest Card card = cf.getCard("Sylvan Basilisk", null); Card card2 = cf.getCard("Exalted Angel", null); - check("121a", !CombatUtil.canDestroyAttacker(card, card2)); + check("121a", !CombatUtil.canDestroyAttacker(card, card2, null)); } { check("122", CardUtil.getConvertedManaCost("0") == 0);