- Moved all AI related functions in CombatUtil to the new class ComputerUtilCombat.

This commit is contained in:
Sloth
2013-01-26 22:06:31 +00:00
parent c0fbd16d93
commit 2d15feec8f
20 changed files with 1718 additions and 1662 deletions

1
.gitattributes vendored
View File

@@ -13855,6 +13855,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/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
src/main/java/forge/game/event/BlockerAssignedEvent.java -text src/main/java/forge/game/event/BlockerAssignedEvent.java -text

View File

@@ -30,12 +30,12 @@ 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.ComputerUtilCombat;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilBlock; import forge.game.ai.ComputerUtilBlock;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.phase.Combat; import forge.game.phase.Combat;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -495,7 +495,7 @@ public class ChangeZoneAi extends SpellAiLogic {
} }
combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay()); combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay());
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
// need something AI can cast now // need something AI can cast now
CardLists.sortByEvaluateCreature(list); CardLists.sortByEvaluateCreature(list);
for (Card c : list) { for (Card c : list) {
@@ -741,7 +741,7 @@ public class ChangeZoneAi extends SpellAiLogic {
CardLists.sortByEvaluateCreature(combatants); CardLists.sortByEvaluateCreature(combatants);
for (final Card c : combatants) { for (final Card c : combatants) {
if (c.getShield() == 0 && CombatUtil.combatantWouldBeDestroyed(c) && !c.getOwner().isHuman() && !c.isToken()) { if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(c) && !c.getOwner().isHuman() && !c.isToken()) {
tgt.addTarget(c); tgt.addTarget(c);
return true; return true;
} }

View File

@@ -14,8 +14,8 @@ import forge.card.abilityfactory.SpellAiLogic;
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.ComputerUtilCombat;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -112,7 +112,7 @@ public class ChooseSourceAi extends SpellAiLogic {
if (!c.isAttacking(ai) || !Singletons.getModel().getGame().getCombat().isUnblocked(c)) { if (!c.isAttacking(ai) || !Singletons.getModel().getGame().getCombat().isUnblocked(c)) {
return false; return false;
} }
return CombatUtil.damageIfUnblocked(c, ai, Singletons.getModel().getGame().getCombat()) > 0; return ComputerUtilCombat.damageIfUnblocked(c, ai, Singletons.getModel().getGame().getCombat()) > 0;
} }
}); });
if (choices.isEmpty()) { if (choices.isEmpty()) {

View File

@@ -13,8 +13,8 @@ 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.ComputerUtilCombat;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
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;
import forge.game.player.Player; import forge.game.player.Player;
@@ -68,13 +68,13 @@ public class DamagePreventAi extends SpellAiLogic {
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;
flag |= CombatUtil.combatantWouldBeDestroyed(c); flag |= ComputerUtilCombat.combatantWouldBeDestroyed(c);
} else if (o instanceof Player) { } else if (o instanceof Player) {
// Don't need to worry about Combat Damage during AI's turn // Don't need to worry about Combat Damage during AI's turn
final Player p = (Player) o; final Player p = (Player) o;
if (!handler.isPlayerTurn(p)) { if (!handler.isPlayerTurn(p)) {
flag |= (p.isComputer() && ((CombatUtil.wouldLoseLife(ai, Singletons.getModel().getGame().getCombat()) && sa flag |= (p.isComputer() && ((ComputerUtilCombat.wouldLoseLife(ai, Singletons.getModel().getGame().getCombat()) && sa
.isAbility()) || CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()))); .isAbility()) || ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())));
} }
} }
} }
@@ -117,8 +117,8 @@ public class DamagePreventAi extends SpellAiLogic {
} // Protect combatants } // Protect combatants
else if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { else if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (sa.canTarget(ai) && CombatUtil.wouldLoseLife(ai, Singletons.getModel().getGame().getCombat()) if (sa.canTarget(ai) && ComputerUtilCombat.wouldLoseLife(ai, Singletons.getModel().getGame().getCombat())
&& (CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()) || sa.isAbility()) && (ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()) || sa.isAbility())
&& Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(ai.getOpponent())) { && Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(ai.getOpponent())) {
tgt.addTarget(ai); tgt.addTarget(ai);
chance = true; chance = true;
@@ -134,7 +134,7 @@ public class DamagePreventAi extends SpellAiLogic {
CardLists.sortByEvaluateCreature(combatants); CardLists.sortByEvaluateCreature(combatants);
for (final Card c : combatants) { for (final Card c : combatants) {
if (CombatUtil.combatantWouldBeDestroyed(c)) { if (ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
tgt.addTarget(c); tgt.addTarget(c);
chance = true; chance = true;
break; break;
@@ -195,7 +195,7 @@ public class DamagePreventAi extends SpellAiLogic {
CardLists.sortByEvaluateCreature(combatants); CardLists.sortByEvaluateCreature(combatants);
if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
for (final Card c : combatants) { for (final Card c : combatants) {
if (CombatUtil.combatantWouldBeDestroyed(c)) { if (ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
tgt.addTarget(c); tgt.addTarget(c);
return true; return true;
} }

View File

@@ -13,6 +13,7 @@ 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.ComputerUtilCombat;
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;
@@ -50,7 +51,7 @@ public class EffectAi extends SpellAiLogic {
if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) { if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) {
return false; return false;
} }
if (!CombatUtil.lifeInDanger(ai, game.getCombat())) { if (!ComputerUtilCombat.lifeInDanger(ai, game.getCombat())) {
return false; return false;
} }
final Target tgt = sa.getTarget(); final Target tgt = sa.getTarget();

View File

@@ -4,7 +4,7 @@ package forge.card.abilityfactory.ai;
import forge.Singletons; import forge.Singletons;
import forge.card.abilityfactory.SpellAiLogic; import forge.card.abilityfactory.SpellAiLogic;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.phase.CombatUtil; import forge.game.ai.ComputerUtilCombat;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
@@ -34,7 +34,7 @@ public class FogAi extends SpellAiLogic {
} }
// Cast it if life is in danger // Cast it if life is in danger
return CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()); return ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat());
} }
@Override @Override

View File

@@ -10,10 +10,10 @@ import forge.card.cost.Cost;
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.ComputerUtilCombat;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.util.MyRandom; import forge.util.MyRandom;
@@ -67,7 +67,7 @@ public class LifeGainAi extends SpellAiLogic {
return false; return false;
} }
boolean lifeCritical = life <= 5; boolean lifeCritical = life <= 5;
lifeCritical |= (Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DAMAGE) && CombatUtil lifeCritical |= (Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DAMAGE) && ComputerUtilCombat
.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())); .lifeInDanger(ai, Singletons.getModel().getGame().getCombat()));
if (abCost != null && !lifeCritical) { if (abCost != null && !lifeCritical) {

View File

@@ -13,6 +13,7 @@ import forge.card.abilityfactory.SpellAiLogic;
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.ComputerUtilCombat;
import forge.game.phase.CombatUtil; import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
@@ -72,10 +73,10 @@ public class MustBlockAi extends SpellAiLogic {
if (!CombatUtil.canBlock(definedAttacker, c)) { if (!CombatUtil.canBlock(definedAttacker, c)) {
return false; return false;
} }
if (CombatUtil.canDestroyAttacker(definedAttacker, c, null, false)) { if (ComputerUtilCombat.canDestroyAttacker(definedAttacker, c, null, false)) {
return false; return false;
} }
if (!CombatUtil.canDestroyBlocker(c, definedAttacker, null, false)) { if (!ComputerUtilCombat.canDestroyBlocker(c, definedAttacker, null, false)) {
return false; return false;
} }
c.setTapped(tapped); c.setTapped(tapped);

View File

@@ -15,8 +15,8 @@ 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.ComputerUtilCombat;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -90,14 +90,14 @@ public class ProtectAi extends SpellAiLogic {
// is the creature blocking and unable to destroy the attacker // is the creature blocking and unable to destroy the attacker
// or would be destroyed itself? // or would be destroyed itself?
if (c.isBlocking() if (c.isBlocking()
&& (CombatUtil.blockerWouldBeDestroyed(c))) { && (ComputerUtilCombat.blockerWouldBeDestroyed(c))) {
return true; return true;
} }
// is the creature in blocked and the blocker would survive // is the creature in blocked and the blocker would survive
if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS) if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
&& Singletons.getModel().getGame().getCombat().isAttacking(c) && Singletons.getModel().getGame().getCombat().isBlocked(c) && Singletons.getModel().getGame().getCombat().isAttacking(c) && Singletons.getModel().getGame().getCombat().isBlocked(c)
&& CombatUtil.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) { && ComputerUtilCombat.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) {
return true; return true;
} }

View File

@@ -16,6 +16,7 @@ import forge.card.abilityfactory.AbilityFactory;
import forge.card.abilityfactory.SpellAiLogic; import forge.card.abilityfactory.SpellAiLogic;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
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;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
@@ -180,7 +181,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
&& !CardLists.getKeyword(Singletons.getModel().getGame().getCombat().getAttackerList(), "Flying").isEmpty() && !CardLists.getKeyword(Singletons.getModel().getGame().getCombat().getAttackerList(), "Flying").isEmpty()
&& !card.hasKeyword("Reach") && !card.hasKeyword("Reach")
&& CombatUtil.canBlock(card) && CombatUtil.canBlock(card)
&& CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) { && ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) {
return true; return true;
} }
Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach")); Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach"));
@@ -196,7 +197,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
&& ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) && ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
&& !CardLists.getKeyword(Singletons.getModel().getGame().getCombat().getAttackerList(), "Horsemanship").isEmpty() && !CardLists.getKeyword(Singletons.getModel().getGame().getCombat().getAttackerList(), "Horsemanship").isEmpty()
&& CombatUtil.canBlock(card) && CombatUtil.canBlock(card)
&& CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) { && ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) {
return true; return true;
} }
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
@@ -222,7 +223,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
List<Card> attackers = combat.getAttackers(); List<Card> attackers = combat.getAttackers();
for (Card attacker : attackers) { for (Card attacker : attackers) {
if (CombatUtil.canBlock(attacker, card, combat) if (CombatUtil.canBlock(attacker, card, combat)
&& !CombatUtil.canDestroyAttacker(attacker, card, combat, false)) { && !ComputerUtilCombat.canDestroyAttacker(attacker, card, combat, false)) {
return true; return true;
} }
} }
@@ -231,7 +232,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
List<Card> blockers = opp.getCreaturesInPlay(); List<Card> blockers = opp.getCreaturesInPlay();
for (Card blocker : blockers) { for (Card blocker : blockers) {
if (CombatUtil.canBlock(card, blocker, combat) if (CombatUtil.canBlock(card, blocker, combat)
&& !CombatUtil.canDestroyBlocker(blocker, card, combat, false)) { && !ComputerUtilCombat.canDestroyBlocker(blocker, card, combat, false)) {
return true; return true;
} }
} }
@@ -407,13 +408,13 @@ public abstract class PumpAiBase extends SpellAiLogic {
// is the creature blocking and unable to destroy the attacker // is the creature blocking and unable to destroy the attacker
// or would be destroyed itself? // or would be destroyed itself?
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && c.isBlocking()) { if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && c.isBlocking()) {
if (defense > 0 && CombatUtil.blockerWouldBeDestroyed(c)) { if (defense > 0 && ComputerUtilCombat.blockerWouldBeDestroyed(c)) {
return true; return true;
} }
List<Card> blockedBy = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(c); List<Card> blockedBy = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(c);
// For now, Only care the first creature blocked by a card. // For now, Only care the first creature blocked by a card.
// TODO Add in better BlockAdditional support // TODO Add in better BlockAdditional support
if (!blockedBy.isEmpty() && attack > 0 && !CombatUtil.attackerWouldBeDestroyed(blockedBy.get(0))) { if (!blockedBy.isEmpty() && attack > 0 && !ComputerUtilCombat.attackerWouldBeDestroyed(blockedBy.get(0))) {
return true; return true;
} }
} }
@@ -431,7 +432,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
&& Singletons.getModel().getGame().getCombat().isBlocked(c) && Singletons.getModel().getGame().getCombat().isBlocked(c)
&& Singletons.getModel().getGame().getCombat().getBlockers(c) != null && Singletons.getModel().getGame().getCombat().getBlockers(c) != null
&& !Singletons.getModel().getGame().getCombat().getBlockers(c).isEmpty() && !Singletons.getModel().getGame().getCombat().getBlockers(c).isEmpty()
&& !CombatUtil.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) { && !ComputerUtilCombat.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) {
return true; return true;
} }
@@ -447,7 +448,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
&& c.isBlocking() && c.isBlocking()
&& defense > 0 && defense > 0
&& attackerHasTrample && attackerHasTrample
&& (sa.isAbility() || CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()))) { && (sa.isAbility() || ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()))) {
return true; return true;
} }

View File

@@ -13,6 +13,7 @@ import forge.card.abilityfactory.AbilityFactory;
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.ComputerUtilCombat;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.phase.CombatUtil; import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -90,7 +91,7 @@ public class PumpAllAi extends PumpAiBase {
totalPower += Math.min(c.getNetAttack(), power * -1); totalPower += Math.min(c.getNetAttack(), power * -1);
if (phase == PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY if (phase == PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY
&& Singletons.getModel().getGame().getCombat().getUnblockedAttackers().contains(c)) { && Singletons.getModel().getGame().getCombat().getUnblockedAttackers().contains(c)) {
if (CombatUtil.lifeInDanger(sa.getActivatingPlayer(), Singletons.getModel().getGame().getCombat())) { if (ComputerUtilCombat.lifeInDanger(sa.getActivatingPlayer(), Singletons.getModel().getGame().getCombat())) {
return true; return true;
} }
totalPower += Math.min(c.getNetAttack(), power * -1); totalPower += Math.min(c.getNetAttack(), power * -1);

View File

@@ -31,8 +31,8 @@ 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.ComputerUtilCombat;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -95,7 +95,7 @@ public class RegenerateAi extends SpellAiLogic {
for (final Card c : list) { for (final Card c : list) {
if (c.getShield() == 0) { if (c.getShield() == 0) {
flag |= CombatUtil.combatantWouldBeDestroyed(c); flag |= ComputerUtilCombat.combatantWouldBeDestroyed(c);
} }
} }
@@ -139,7 +139,7 @@ public class RegenerateAi extends SpellAiLogic {
CardLists.sortByEvaluateCreature(combatants); CardLists.sortByEvaluateCreature(combatants);
for (final Card c : combatants) { for (final Card c : combatants) {
if ((c.getShield() == 0) && CombatUtil.combatantWouldBeDestroyed(c)) { if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
tgt.addTarget(c); tgt.addTarget(c);
chance = true; chance = true;
break; break;
@@ -190,7 +190,7 @@ public class RegenerateAi extends SpellAiLogic {
CardLists.sortByEvaluateCreature(combatants); CardLists.sortByEvaluateCreature(combatants);
if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
for (final Card c : combatants) { for (final Card c : combatants) {
if ((c.getShield() == 0) && CombatUtil.combatantWouldBeDestroyed(c)) { if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
tgt.addTarget(c); tgt.addTarget(c);
return true; return true;
} }

View File

@@ -11,8 +11,8 @@ import forge.card.abilityfactory.AbilityFactory;
import forge.card.abilityfactory.SpellAiLogic; import forge.card.abilityfactory.SpellAiLogic;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.ai.ComputerUtilCombat;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -68,7 +68,7 @@ public class RegenerateAllAi extends SpellAiLogic {
final List<Card> combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES); final List<Card> combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES);
for (final Card c : combatants) { for (final Card c : combatants) {
if (c.getShield() == 0 && CombatUtil.combatantWouldBeDestroyed(c)) { if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
numSaved++; numSaved++;
} }
} }

View File

@@ -4,8 +4,8 @@ import forge.Card;
import forge.Singletons; import forge.Singletons;
import forge.card.abilityfactory.SpellAiLogic; import forge.card.abilityfactory.SpellAiLogic;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.ai.ComputerUtilCombat;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.phase.CombatUtil;
import forge.game.player.Player; import forge.game.player.Player;
public class StoreSVarAi extends SpellAiLogic { public class StoreSVarAi extends SpellAiLogic {
@@ -16,7 +16,7 @@ public class StoreSVarAi extends SpellAiLogic {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
if (ComputerUtil.waitForBlocking(sa) || ai.getLife() + 1 >= source.getNetDefense() if (ComputerUtil.waitForBlocking(sa) || ai.getLife() + 1 >= source.getNetDefense()
|| (ai.getLife() > 5 && !CombatUtil.lifeInSeriousDanger(ai, Singletons.getModel().getGame().getCombat()))) { || (ai.getLife() > 5 && !ComputerUtilCombat.lifeInSeriousDanger(ai, Singletons.getModel().getGame().getCombat()))) {
return false; return false;
} }

View File

@@ -14,7 +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.phase.CombatUtil; 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;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
@@ -178,7 +178,7 @@ public class ChooseSourceEffect extends SpellEffect {
if (!c.isAttacking(ai) || !Singletons.getModel().getGame().getCombat().isUnblocked(c)) { if (!c.isAttacking(ai) || !Singletons.getModel().getGame().getCombat().isUnblocked(c)) {
return false; return false;
} }
return CombatUtil.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(CardFactoryUtil.getBestCreatureAI(sourcesToChooseFrom));

View File

@@ -140,15 +140,15 @@ public class AiAttackController {
public final boolean isEffectiveAttacker(final Player ai, final Card attacker, final Combat combat) { public final boolean isEffectiveAttacker(final Player ai, final Card attacker, final Combat combat) {
// if the attacker will die when attacking don't attack // if the attacker will die when attacking don't attack
if ((attacker.getNetDefense() + CombatUtil.predictToughnessBonusOfAttacker(attacker, null, combat, true)) <= 0) { if ((attacker.getNetDefense() + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, null, combat, true)) <= 0) {
return false; return false;
} }
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
if (CombatUtil.damageIfUnblocked(attacker, opp, combat) > 0) { if (ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat) > 0) {
return true; return true;
} }
if (CombatUtil.poisonIfUnblocked(attacker, opp) > 0) { if (ComputerUtilCombat.poisonIfUnblocked(attacker, opp) > 0) {
return true; return true;
} }
if (this.attackers.size() == 1 && attacker.hasKeyword("Exalted")) { if (this.attackers.size() == 1 && attacker.hasKeyword("Exalted")) {
@@ -158,7 +158,7 @@ public class AiAttackController {
final List<Card> controlledByCompy = ai.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES); final List<Card> controlledByCompy = ai.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES);
for (final Card c : controlledByCompy) { for (final Card c : controlledByCompy) {
for (final Trigger trigger : c.getTriggers()) { for (final Trigger trigger : c.getTriggers()) {
if (CombatUtil.combatTriggerWillTrigger(attacker, null, trigger, combat)) { if (ComputerUtilCombat.combatTriggerWillTrigger(attacker, null, trigger, combat)) {
return true; return true;
} }
} }
@@ -350,8 +350,8 @@ public class AiAttackController {
blockersLeft--; blockersLeft--;
continue; continue;
} }
totalAttack += CombatUtil.damageIfUnblocked(attacker, ai, null); totalAttack += ComputerUtilCombat.damageIfUnblocked(attacker, ai, null);
totalPoison += CombatUtil.poisonIfUnblocked(attacker, ai); totalPoison += ComputerUtilCombat.poisonIfUnblocked(attacker, ai);
} }
if (totalAttack > 0 && ai.getLife() <= totalAttack if (totalAttack > 0 && ai.getLife() <= totalAttack
@@ -425,12 +425,12 @@ public class AiAttackController {
} }
unblockedAttackers.addAll(remainingAttackers); unblockedAttackers.addAll(remainingAttackers);
if ((CombatUtil.sumDamageIfUnblocked(remainingAttackers, opp) >= opp.getLife()) if ((ComputerUtilCombat.sumDamageIfUnblocked(remainingAttackers, opp) >= opp.getLife())
&& !((opp.cantLoseForZeroOrLessLife() || ai.cantWin()) && (opp.getLife() < 1))) { && !((opp.cantLoseForZeroOrLessLife() || ai.cantWin()) && (opp.getLife() < 1))) {
return true; return true;
} }
if (CombatUtil.sumPoisonIfUnblocked(remainingAttackers, opp) >= (10 - opp.getPoisonCounters())) { if (ComputerUtilCombat.sumPoisonIfUnblocked(remainingAttackers, opp) >= (10 - opp.getPoisonCounters())) {
return true; return true;
} }
@@ -621,7 +621,7 @@ public class AiAttackController {
if (CombatUtil.canAttackNextTurn(pCard)) { if (CombatUtil.canAttackNextTurn(pCard)) {
candidateAttackers.add(pCard); candidateAttackers.add(pCard);
if (pCard.getNetCombatDamage() > 0) { if (pCard.getNetCombatDamage() > 0) {
candidateUnblockedDamage += CombatUtil.damageIfUnblocked(pCard, opp, null); candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null);
computerForces += 1; computerForces += 1;
} }
@@ -717,7 +717,7 @@ public class AiAttackController {
} }
} }
if (isUnblockableCreature) { if (isUnblockableCreature) {
unblockableDamage += CombatUtil.damageIfUnblocked(attacker, opp, combat); unblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat);
} }
} }
for (final Card attacker : nextTurnAttackers) { for (final Card attacker : nextTurnAttackers) {
@@ -731,7 +731,7 @@ public class AiAttackController {
} }
} }
if (isUnblockableCreature) { if (isUnblockableCreature) {
nextUnblockableDamage += CombatUtil.damageIfUnblocked(attacker, opp, null); nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, null);
} }
} }
if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife() if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife()
@@ -785,7 +785,7 @@ public class AiAttackController {
for (int i = 0; i < attackersLeft.size(); i++) { for (int i = 0; i < attackersLeft.size(); i++) {
final Card attacker = attackersLeft.get(i); final Card attacker = attackersLeft.get(i);
if (this.aiAggression < 5 && !attacker.hasFirstStrike() && !attacker.hasDoubleStrike() if (this.aiAggression < 5 && !attacker.hasFirstStrike() && !attacker.hasDoubleStrike()
&& CombatUtil.getTotalFirstStrikeBlockPower(attacker, ai.getOpponent()) && ComputerUtilCombat.getTotalFirstStrikeBlockPower(attacker, ai.getOpponent())
>= attacker.getKillDamage()) { >= attacker.getKillDamage()) {
continue; continue;
} }
@@ -803,7 +803,7 @@ public class AiAttackController {
CardLists.sortAttackLowFirst(attacking); CardLists.sortAttackLowFirst(attacking);
for (Card atta : attacking) { for (Card atta : attacking) {
if (attackNum >= blockNum || !CombatUtil.canBeBlocked(attacker, this.blockers)) { if (attackNum >= blockNum || !CombatUtil.canBeBlocked(attacker, this.blockers)) {
damage += CombatUtil.damageIfUnblocked(atta, opp, null); damage += ComputerUtilCombat.damageIfUnblocked(atta, opp, null);
} else if (CombatUtil.canBeBlocked(attacker, this.blockers)) { } else if (CombatUtil.canBeBlocked(attacker, this.blockers)) {
attackNum++; attackNum++;
} }
@@ -901,7 +901,7 @@ public class AiAttackController {
if ((isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2) if ((isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2)
&& CombatUtil.canBlock(attacker, defender)) { && CombatUtil.canBlock(attacker, defender)) {
numberOfPossibleBlockers += 1; numberOfPossibleBlockers += 1;
if (isWorthLessThanAllKillers && CombatUtil.canDestroyAttacker(attacker, defender, combat, false) if (isWorthLessThanAllKillers && ComputerUtilCombat.canDestroyAttacker(attacker, defender, combat, false)
&& !(attacker.hasKeyword("Undying") && attacker.getCounters(CounterType.P1P1) == 0)) { && !(attacker.hasKeyword("Undying") && attacker.getCounters(CounterType.P1P1) == 0)) {
canBeKilledByOne = true; // there is a single creature on canBeKilledByOne = true; // there is a single creature on
// the battlefield that can kill // the battlefield that can kill
@@ -915,7 +915,7 @@ public class AiAttackController {
} }
// see if this attacking creature can destroy this defender, if // see if this attacking creature can destroy this defender, if
// not record that it can't kill everything // not record that it can't kill everything
if (canKillAllDangerous && !CombatUtil.canDestroyBlocker(defender, attacker, combat, false)) { if (canKillAllDangerous && !ComputerUtilCombat.canDestroyBlocker(defender, attacker, combat, false)) {
canKillAll = false; canKillAll = false;
if (!canKillAllDangerous) { if (!canKillAllDangerous) {
continue; continue;

View File

@@ -1006,7 +1006,7 @@ public class ComputerUtil {
} }
} }
combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay()); combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay());
if (!CombatUtil.lifeInDanger(ai, combat)) { if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
// Otherwise, return false. Do not play now. // Otherwise, return false. Do not play now.
ret = false; ret = false;
} }

View File

@@ -233,7 +233,7 @@ public class ComputerUtilBlock {
final List<Card> blockers = new ArrayList<Card>(); final List<Card> blockers = new ArrayList<Card>();
for (final Card b : blockersLeft) { for (final Card b : blockersLeft) {
if (!CombatUtil.canDestroyBlocker(b, attacker, combat, false)) { if (!ComputerUtilCombat.canDestroyBlocker(b, attacker, combat, false)) {
blockers.add(b); blockers.add(b);
} }
} }
@@ -259,7 +259,7 @@ public class ComputerUtilBlock {
final List<Card> blockers = new ArrayList<Card>(); final List<Card> blockers = new ArrayList<Card>();
for (final Card b : blockersLeft) { for (final Card b : blockersLeft) {
if (CombatUtil.canDestroyAttacker(attacker, b, combat, false)) { if (ComputerUtilCombat.canDestroyAttacker(attacker, b, combat, false)) {
blockers.add(b); blockers.add(b);
} }
} }
@@ -293,7 +293,7 @@ public class ComputerUtilBlock {
return firstAttacker; return firstAttacker;
} }
final boolean bLifeInDanger = CombatUtil.lifeInDanger(ai, combat); final boolean bLifeInDanger = ComputerUtilCombat.lifeInDanger(ai, combat);
// TODO Add creatures attacking Planeswalkers in order of which we want // TODO Add creatures attacking Planeswalkers in order of which we want
// to protect // to protect
@@ -427,14 +427,14 @@ public class ComputerUtilBlock {
CardLists.sortAttack(firstStrikeBlockers); CardLists.sortAttack(firstStrikeBlockers);
for (final Card blocker : firstStrikeBlockers) { for (final Card blocker : firstStrikeBlockers) {
final int damageNeeded = attacker.getKillDamage() final int damageNeeded = attacker.getKillDamage()
+ CombatUtil.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
// if the total damage of the blockgang was not enough // if the total damage of the blockgang was not enough
// without but is enough with this blocker finish the // without but is enough with this blocker finish the
// blockgang // blockgang
if (CombatUtil.totalDamageOfBlockers(attacker, blockGang) < damageNeeded if (ComputerUtilCombat.totalDamageOfBlockers(attacker, blockGang) < damageNeeded
|| CombatUtil.needsBlockers(attacker) > blockGang.size()) { || CombatUtil.needsBlockers(attacker) > blockGang.size()) {
blockGang.add(blocker); blockGang.add(blocker);
if (CombatUtil.totalDamageOfBlockers(attacker, blockGang) >= damageNeeded) { if (ComputerUtilCombat.totalDamageOfBlockers(attacker, blockGang) >= damageNeeded) {
currentAttackers.remove(attacker); currentAttackers.remove(attacker);
for (final Card b : blockGang) { for (final Card b : blockGang) {
if (CombatUtil.canBlock(attacker, blocker, combat)) { if (CombatUtil.canBlock(attacker, blocker, combat)) {
@@ -488,13 +488,13 @@ public class ComputerUtilBlock {
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
// enough and the new one would deal the remaining damage // enough and the new one would deal the remaining damage
final int currentDamage = CombatUtil.totalDamageOfBlockers(attacker, blockGang); final int currentDamage = ComputerUtilCombat.totalDamageOfBlockers(attacker, blockGang);
final int additionalDamage = CombatUtil.dealsDamageAsBlocker(attacker, blocker); final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker);
final int absorbedDamage2 = blocker final int absorbedDamage2 = blocker
.getEnoughDamageToKill(attacker.getNetCombatDamage(), attacker, true); .getEnoughDamageToKill(attacker.getNetCombatDamage(), attacker, true);
final int addedValue = CardFactoryUtil.evaluateCreature(blocker); final int addedValue = CardFactoryUtil.evaluateCreature(blocker);
final int damageNeeded = attacker.getKillDamage() final int damageNeeded = attacker.getKillDamage()
+ CombatUtil.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())
&& !(damageNeeded > currentDamage + additionalDamage) && !(damageNeeded > currentDamage + additionalDamage)
// The attacker will be killed // The attacker will be killed
@@ -502,7 +502,7 @@ public class ComputerUtilBlock {
// only one blocker can be killed // only one blocker can be killed
|| currentValue + addedValue - 50 <= CardFactoryUtil.evaluateCreature(attacker) || currentValue + addedValue - 50 <= CardFactoryUtil.evaluateCreature(attacker)
// or attacker is worth more // or attacker is worth more
|| (lifeInDanger && CombatUtil.lifeInDanger(ai, combat))) || (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)))
// or life is in danger // or life is in danger
&& CombatUtil.canBlock(attacker, blocker, combat)) { && CombatUtil.canBlock(attacker, blocker, combat)) {
// this is needed for attackers that can't be blocked by // this is needed for attackers that can't be blocked by
@@ -545,7 +545,7 @@ public class ComputerUtilBlock {
killingBlockers = ComputerUtilBlock.getKillingBlockers(attacker, killingBlockers = ComputerUtilBlock.getKillingBlockers(attacker,
ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true), ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true),
combat); combat);
if ((killingBlockers.size() > 0) && CombatUtil.lifeInDanger(ai, combat)) { if ((killingBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
final Card blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers); final Card blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
combat.addBlocker(attacker, blocker); combat.addBlocker(attacker, blocker);
currentAttackers.remove(attacker); currentAttackers.remove(attacker);
@@ -579,7 +579,7 @@ public class ComputerUtilBlock {
chumpBlockers = ComputerUtilBlock chumpBlockers = ComputerUtilBlock
.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true); .getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true);
if ((chumpBlockers.size() > 0) && CombatUtil.lifeInDanger(ai, combat)) { if ((chumpBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
final Card blocker = CardFactoryUtil.getWorstCreatureAI(chumpBlockers); final Card blocker = CardFactoryUtil.getWorstCreatureAI(chumpBlockers);
combat.addBlocker(attacker, blocker); combat.addBlocker(attacker, blocker);
currentAttackers.remove(attacker); currentAttackers.remove(attacker);
@@ -626,9 +626,9 @@ public class ComputerUtilBlock {
for (final Card blocker : chumpBlockers) { for (final Card blocker : chumpBlockers) {
// Add an additional blocker if the current blockers are not // Add an additional blocker if the current blockers are not
// enough and the new one would suck some of the damage // enough and the new one would suck some of the damage
if (CombatUtil.getAttack(attacker) > CombatUtil.totalShieldDamage(attacker, combat.getBlockers(attacker)) if (ComputerUtilCombat.getAttack(attacker) > ComputerUtilCombat.totalShieldDamage(attacker, combat.getBlockers(attacker))
&& CombatUtil.shieldDamage(attacker, blocker) > 0 && ComputerUtilCombat.shieldDamage(attacker, blocker) > 0
&& CombatUtil.canBlock(attacker, blocker, combat) && CombatUtil.lifeInDanger(ai, combat)) { && CombatUtil.canBlock(attacker, blocker, combat) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat.addBlocker(attacker, blocker); combat.addBlocker(attacker, blocker);
} }
} }
@@ -667,11 +667,11 @@ public class ComputerUtilBlock {
safeBlockers = ComputerUtilBlock.getSafeBlockers(attacker, blockers, combat); safeBlockers = ComputerUtilBlock.getSafeBlockers(attacker, blockers, combat);
for (final Card blocker : safeBlockers) { for (final Card blocker : safeBlockers) {
final int damageNeeded = attacker.getKillDamage() final int damageNeeded = attacker.getKillDamage()
+ CombatUtil.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
// Add an additional blocker if the current blockers are not // Add an additional blocker if the current blockers are not
// enough and the new one would deal additional damage // enough and the new one would deal additional damage
if ((damageNeeded > CombatUtil.totalDamageOfBlockers(attacker, combat.getBlockers(attacker))) if ((damageNeeded > ComputerUtilCombat.totalDamageOfBlockers(attacker, combat.getBlockers(attacker)))
&& (CombatUtil.dealsDamageAsBlocker(attacker, blocker) > 0) && ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker) > 0
&& CombatUtil.canBlock(attacker, blocker, combat)) { && CombatUtil.canBlock(attacker, blocker, combat)) {
combat.addBlocker(attacker, blocker); combat.addBlocker(attacker, blocker);
} }
@@ -691,11 +691,11 @@ public class ComputerUtilBlock {
for (final Card blocker : safeBlockers) { for (final Card blocker : safeBlockers) {
final int damageNeeded = attacker.getKillDamage() final int damageNeeded = attacker.getKillDamage()
+ CombatUtil.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
// Add an additional blocker if the current blockers are not // Add an additional blocker if the current blockers are not
// enough and the new one would deal the remaining damage // enough and the new one would deal the remaining damage
final int currentDamage = CombatUtil.totalDamageOfBlockers(attacker, combat.getBlockers(attacker)); final int currentDamage = ComputerUtilCombat.totalDamageOfBlockers(attacker, combat.getBlockers(attacker));
final int additionalDamage = CombatUtil.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 && ((CardFactoryUtil.evaluateCreature(blocker) + ComputerUtilBlock.getDiff()) < CardFactoryUtil
@@ -810,13 +810,13 @@ public class ComputerUtilBlock {
// == 1. choose best blocks first == // == 1. choose best blocks first ==
combat = ComputerUtilBlock.makeGoodBlocks(combat); combat = ComputerUtilBlock.makeGoodBlocks(combat);
combat = ComputerUtilBlock.makeGangBlocks(ai, combat); combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose
// necessary // necessary
// trade blocks // trade blocks
} }
// if life is in danger // if life is in danger
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose
// necessary // necessary
// chump blocks // chump blocks
@@ -824,18 +824,18 @@ public class ComputerUtilBlock {
// if life is still in danger // if life is still in danger
// Reinforce blockers blocking attackers with trample if life is still // Reinforce blockers blocking attackers with trample if life is still
// in danger // in danger
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.reinforceBlockersAgainstTrample(ai, combat); combat = ComputerUtilBlock.reinforceBlockersAgainstTrample(ai, combat);
} }
// Support blockers not destroying the attacker with more blockers to // Support blockers not destroying the attacker with more blockers to
// try to kill the attacker // try to kill the attacker
if (!CombatUtil.lifeInDanger(ai, combat)) { if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.reinforceBlockersToKill(combat); combat = ComputerUtilBlock.reinforceBlockersToKill(combat);
} }
// == 2. If the AI life would still be in danger make a safer approach // == 2. If the AI life would still be in danger make a safer approach
// == // ==
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
lifeInDanger = true; lifeInDanger = true;
combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset
// every // every
@@ -846,7 +846,7 @@ public class ComputerUtilBlock {
// trade blocks // trade blocks
// if life is in danger // if life is in danger
combat = ComputerUtilBlock.makeGoodBlocks(combat); combat = ComputerUtilBlock.makeGoodBlocks(combat);
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose
// necessary // necessary
// chump // chump
@@ -855,7 +855,7 @@ public class ComputerUtilBlock {
// danger // danger
// Reinforce blockers blocking attackers with trample if life is // Reinforce blockers blocking attackers with trample if life is
// still in danger // still in danger
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.reinforceBlockersAgainstTrample(ai, combat); combat = ComputerUtilBlock.reinforceBlockersAgainstTrample(ai, combat);
} }
combat = ComputerUtilBlock.makeGangBlocks(ai, combat); combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
@@ -864,20 +864,20 @@ public class ComputerUtilBlock {
// == 3. If the AI life would be in serious danger make an even safer // == 3. If the AI life would be in serious danger make an even safer
// approach == // approach ==
if (CombatUtil.lifeInSeriousDanger(ai, combat)) { if (ComputerUtilCombat.lifeInSeriousDanger(ai, combat)) {
combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset
// every // every
// block // block
// assignment // assignment
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose chump combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose chump
// blocks // blocks
if (CombatUtil.lifeInDanger(ai, combat)) { if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose
// necessary // necessary
// trade // trade
} }
if (!CombatUtil.lifeInDanger(ai, combat)) { if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
combat = ComputerUtilBlock.makeGoodBlocks(combat); combat = ComputerUtilBlock.makeGoodBlocks(combat);
} }
// Reinforce blockers blocking attackers with trample if life is // Reinforce blockers blocking attackers with trample if life is

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff