- Improved AI handling Mishra's Factory.

This commit is contained in:
Sloth
2014-11-29 12:03:55 +00:00
parent e69385abb0
commit f57df312c0
5 changed files with 40 additions and 36 deletions

View File

@@ -794,9 +794,9 @@ public class AiController {
} }
// cast 0 mana cost spells first (might be a Mox) // cast 0 mana cost spells first (might be a Mox)
if (a1 == 0 && b1 > 0) { if (a1 == 0 && b1 > 0 && ApiType.Mana != a.getApi()) {
return -1; return -1;
} else if (a1 > 0 && b1 == 0) { } else if (a1 > 0 && b1 == 0 && ApiType.Mana != b.getApi()) {
return 1; return 1;
} }
@@ -837,6 +837,9 @@ public class AiController {
if (ApiType.DestroyAll == sa.getApi()) { if (ApiType.DestroyAll == sa.getApi()) {
p += 4; p += 4;
} }
else if (ApiType.Mana == sa.getApi()) {
p -= 9;
}
return p; return p;
} }

View File

@@ -1780,7 +1780,7 @@ public class ComputerUtilCombat {
* </p> * </p>
* @param ai * @param ai
* *
* @param defender * @param blocker
* a {@link forge.game.card.Card} object. * a {@link forge.game.card.Card} object.
* @param attacker * @param attacker
* a {@link forge.game.card.Card} object. * a {@link forge.game.card.Card} object.
@@ -1790,7 +1790,7 @@ public class ComputerUtilCombat {
* a boolean. * a boolean.
* @return a boolean. * @return a boolean.
*/ */
public static boolean canDestroyBlocker(Player ai, final Card defender, final Card attacker, final Combat combat, public static boolean canDestroyBlocker(Player ai, final Card blocker, final Card attacker, final Combat combat,
final boolean withoutAbilities) { final boolean withoutAbilities) {
final Game game = ai.getGame(); final Game game = ai.getGame();
@@ -1803,76 +1803,76 @@ public class ComputerUtilCombat {
} }
int flankingMagnitude = 0; int flankingMagnitude = 0;
if (attacker.hasKeyword("Flanking") && !defender.hasKeyword("Flanking")) { if (attacker.hasKeyword("Flanking") && !blocker.hasKeyword("Flanking")) {
flankingMagnitude = attacker.getAmountOfKeyword("Flanking"); flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
if (flankingMagnitude >= defender.getNetToughness()) { if (flankingMagnitude >= blocker.getNetToughness()) {
return true; return true;
} }
if ((flankingMagnitude >= ComputerUtilCombat.getDamageToKill(defender)) && !defender.hasKeyword("Indestructible")) { if ((flankingMagnitude >= ComputerUtilCombat.getDamageToKill(blocker)) && !blocker.hasKeyword("Indestructible")) {
return true; return true;
} }
} // flanking } // flanking
if (((defender.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(ai, defender) && !withoutAbilities)) && !(attacker if (((blocker.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(ai, blocker) && !withoutAbilities)) && !(attacker
.hasKeyword("Wither") || attacker.hasKeyword("Infect"))) .hasKeyword("Wither") || attacker.hasKeyword("Infect")))
|| (defender.hasKeyword("Persist") && !defender.canReceiveCounters(CounterType.M1M1) && (defender || (blocker.hasKeyword("Persist") && !blocker.canReceiveCounters(CounterType.M1M1) && (blocker
.getCounters(CounterType.M1M1) == 0)) .getCounters(CounterType.M1M1) == 0))
|| (defender.hasKeyword("Undying") && !defender.canReceiveCounters(CounterType.P1P1) && (defender || (blocker.hasKeyword("Undying") && !blocker.canReceiveCounters(CounterType.P1P1) && (blocker
.getCounters(CounterType.P1P1) == 0))) { .getCounters(CounterType.P1P1) == 0))) {
return false; return false;
} }
if (checkDestroyBlockerTrigger(attacker, defender) && !defender.hasKeyword("Indestructible")) { if (checkDestroyBlockerTrigger(attacker, blocker) && !blocker.hasKeyword("Indestructible")) {
return true; return true;
} }
if (defender.isEquipped()) { if (blocker.isEquipped()) {
for (Card equipment : defender.getEquippedBy(false)) { for (Card equipment : blocker.getEquippedBy(false)) {
if (equipment.getName().equals("Godsend")) { if (equipment.getName().equals("Godsend")) {
return false; return false;
} }
} }
} }
int defenderDamage = defender.getNetPower() int defenderDamage = blocker.getNetPower()
+ ComputerUtilCombat.predictPowerBonusOfBlocker(attacker, defender, withoutAbilities); + ComputerUtilCombat.predictPowerBonusOfBlocker(attacker, blocker, withoutAbilities);
int attackerDamage = attacker.getNetPower() int attackerDamage = attacker.getNetPower()
+ ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, defender, combat, withoutAbilities); + ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, blocker, combat, withoutAbilities);
if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.toughnessAssignsDamage)) { if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.toughnessAssignsDamage)) {
defenderDamage = defender.getNetToughness() defenderDamage = blocker.getNetToughness()
+ ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, defender, withoutAbilities); + ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
attackerDamage = attacker.getNetToughness() attackerDamage = attacker.getNetToughness()
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, defender, combat, withoutAbilities); + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities);
} }
int possibleDefenderPrevention = 0; int possibleDefenderPrevention = 0;
int possibleAttackerPrevention = 0; int possibleAttackerPrevention = 0;
if (!withoutAbilities) { if (!withoutAbilities) {
possibleDefenderPrevention = ComputerUtil.possibleDamagePrevention(defender); possibleDefenderPrevention = ComputerUtil.possibleDamagePrevention(blocker);
possibleAttackerPrevention = ComputerUtil.possibleDamagePrevention(attacker); possibleAttackerPrevention = ComputerUtil.possibleDamagePrevention(attacker);
} }
// consider Damage Prevention/Replacement // consider Damage Prevention/Replacement
defenderDamage = predictDamageTo(attacker, defenderDamage, possibleAttackerPrevention, defender, true); defenderDamage = predictDamageTo(attacker, defenderDamage, possibleAttackerPrevention, blocker, true);
attackerDamage = predictDamageTo(defender, attackerDamage, possibleDefenderPrevention, attacker, true); attackerDamage = predictDamageTo(blocker, attackerDamage, possibleDefenderPrevention, attacker, true);
if (combat != null) { if (combat != null) {
for (Card atkr : combat.getAttackersBlockedBy(defender)) { for (Card atkr : combat.getAttackersBlockedBy(blocker)) {
if (!atkr.equals(attacker)) { if (!atkr.equals(attacker)) {
attackerDamage += predictDamageTo(defender, atkr.getNetCombatDamage(), 0, atkr, true); attackerDamage += predictDamageTo(blocker, atkr.getNetCombatDamage(), 0, atkr, true);
} }
} }
} }
final int defenderLife = ComputerUtilCombat.getDamageToKill(defender) final int defenderLife = ComputerUtilCombat.getDamageToKill(blocker)
+ ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, defender, withoutAbilities); + ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
final int attackerLife = ComputerUtilCombat.getDamageToKill(attacker) final int attackerLife = ComputerUtilCombat.getDamageToKill(attacker)
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, defender, combat, withoutAbilities); + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities);
if (attacker.hasKeyword("Double Strike")) { if (attacker.hasKeyword("Double Strike")) {
if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || defender.hasSVar("DestroyWhenDamaged"))) { if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || blocker.hasSVar("DestroyWhenDamaged"))) {
return true; return true;
} }
if (attackerDamage >= defenderLife) { if (attackerDamage >= defenderLife) {
@@ -1881,11 +1881,11 @@ public class ComputerUtilCombat {
// Attacker may kill the blocker before he can deal normal // Attacker may kill the blocker before he can deal normal
// (secondary) damage // (secondary) damage
if (dealsFirstStrikeDamage(defender, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible")) { if (dealsFirstStrikeDamage(blocker, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible")) {
if (defenderDamage >= attackerLife) { if (defenderDamage >= attackerLife) {
return false; return false;
} }
if (defenderDamage > 0 && (hasKeyword(defender, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) { if (defenderDamage > 0 && (hasKeyword(blocker, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) {
return false; return false;
} }
} }
@@ -1896,18 +1896,18 @@ public class ComputerUtilCombat {
else { // no double strike for attacker else { // no double strike for attacker
// Defender may kill the attacker before he can deal any damage // Defender may kill the attacker before he can deal any damage
if (dealsFirstStrikeDamage(defender, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible") if (dealsFirstStrikeDamage(blocker, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible")
&& !dealsFirstStrikeDamage(attacker, withoutAbilities, combat)) { && !dealsFirstStrikeDamage(attacker, withoutAbilities, combat)) {
if (defenderDamage >= attackerLife) { if (defenderDamage >= attackerLife) {
return false; return false;
} }
if (defenderDamage > 0 && (hasKeyword(defender, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) { if (defenderDamage > 0 && (hasKeyword(blocker, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) {
return false; return false;
} }
} }
if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || defender.hasSVar("DestroyWhenDamaged"))) { if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || blocker.hasSVar("DestroyWhenDamaged"))) {
return true; return true;
} }

View File

@@ -152,7 +152,7 @@ public class AnimateAi extends SpellAbilityAi {
boolean givesHaste = sa.hasParam("Keywords") && sa.getParam("Keywords").contains("Haste"); boolean givesHaste = sa.hasParam("Keywords") && sa.getParam("Keywords").contains("Haste");
for (final Card c : defined) { for (final Card c : defined) {
bFlag |= !c.isCreature() && !c.isTapped() bFlag |= !c.isCreature() && !c.isTapped()
&& (c.getTurnInZone() != game.getPhaseHandler().getTurn() || givesHaste) && (c.getTurnInZone() != ph.getTurn() || givesHaste || ph.getPlayerTurn().isOpponentOf(aiPlayer))
&& !c.isEquipping(); && !c.isEquipping();
// for creatures that could be improved (like Figure of Destiny) // for creatures that could be improved (like Figure of Destiny)

View File

@@ -324,7 +324,7 @@ public class PumpAi extends PumpAiBase {
list.remove(sa.getHostCard()); list.remove(sa.getHostCard());
} }
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS) if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)
&& game.getPhaseHandler().isPlayerTurn(opp)) { && game.getPhaseHandler().getPlayerTurn().isOpponentOf(ai)) {
list.remove(sa.getHostCard()); list.remove(sa.getHostCard());
} }
} }

View File

@@ -436,7 +436,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
return false; return false;
} }
if ((c.getNetToughness() + defense) <= 0) { if (c.getNetToughness() + defense <= 0) {
return false; return false;
} }
@@ -754,6 +754,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
kws.add(kw); kws.add(kw);
} }
} }
pumped.addNewPT(c.getCurrentPower(), c.getCurrentPower(), timestamp);
pumped.addTempPowerBoost(c.getTempPowerBoost() + a); pumped.addTempPowerBoost(c.getTempPowerBoost() + a);
pumped.addTempToughnessBoost(c.getTempToughnessBoost() + d); pumped.addTempToughnessBoost(c.getTempToughnessBoost() + d);
pumped.addChangedCardKeywords(kws, new ArrayList<String>(), false, timestamp); pumped.addChangedCardKeywords(kws, new ArrayList<String>(), false, timestamp);