mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
- AI will now predict battle cry boni.
This commit is contained in:
@@ -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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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;
|
||||
|
||||
@@ -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<Trigger> registeredTriggers = AllZone.TriggerHandler.getRegisteredTriggers();
|
||||
for(Trigger trigger : registeredTriggers)
|
||||
{
|
||||
HashMap<String,String> 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user