- Improved AI using Ulamog's Nullifier.

This commit is contained in:
Sloth
2015-09-28 08:42:05 +00:00
parent e922e3dea3
commit 7145da0e53
4 changed files with 35 additions and 6 deletions

View File

@@ -226,7 +226,7 @@ public class AiController {
}
// if trigger is not mandatory - no problem
if (params.get("OptionalDecider") != null) {
if (params.get("OptionalDecider") != null && api == null) {
continue;
}
@@ -243,6 +243,11 @@ public class AiController {
} else {
rightapi = true;
}
if (!(exSA instanceof AbilitySub)) {
if (!ComputerUtilCost.canPayCost(exSA, player)) {
return false;
}
}
}
if (sa != null) {
@@ -255,7 +260,7 @@ public class AiController {
// Run non-mandatory trigger.
// These checks only work if the Executing SpellAbility is an Ability_Sub.
if ((exSA instanceof AbilitySub) && !doTrigger(exSA, false)) {
if (exSA instanceof AbilitySub && !doTrigger(exSA, false)) {
// AI would not run this trigger if given the chance
return false;
}
@@ -691,6 +696,7 @@ public class AiController {
&& (game.getPhaseHandler().isPlayerTurn(player)
|| game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS))
&& (!card.hasETBTrigger(true) || card.hasSVar("AmbushAI"))
&& game.getStack().isEmpty()
&& !ComputerUtil.castPermanentInMain1(player, sa)) {
return AiPlayDecision.AnotherTime;
}

View File

@@ -1,5 +1,7 @@
package forge.ai.ability;
import java.util.Iterator;
import forge.ai.ComputerUtilCost;
import forge.ai.ComputerUtilMana;
import forge.ai.SpellAbilityAi;
@@ -10,6 +12,7 @@ import forge.game.card.CardFactoryUtil;
import forge.game.cost.Cost;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetRestrictions;
import forge.util.MyRandom;
@@ -119,7 +122,24 @@ public class CounterAi extends SpellAbilityAi {
if (game.getStack().isEmpty()) {
return false;
}
final SpellAbility topSA = game.getStack().peekAbility();
SpellAbility topSA = game.getStack().peekAbility();
// triggered abilities see themselves on the stack, so find another spell on the stack
if (sa.isTrigger() && topSA.isTrigger() && game.getStack().size() > 1) {
Iterator<SpellAbilityStackInstance> it = game.getStack().iterator();
SpellAbilityStackInstance si = game.getStack().peek();
while (it.hasNext()) {
si = it.next();
if (si.isTrigger()) {
it.remove();
} else {
break;
}
}
topSA = si.getSpellAbility(true);
}
if (!CardFactoryUtil.isCounterableBy(topSA.getHostCard(), sa) || topSA.getActivatingPlayer() == ai) {
return false;
}
@@ -170,7 +190,6 @@ public class CounterAi extends SpellAbilityAi {
// force the Human into making decisions)
// But really it should be more picky about how it counters things
return true;
}

View File

@@ -79,7 +79,7 @@ public class PermanentCreatureAi extends SpellAbilityAi {
}
// Wait for Main2 if possible
if (ph.is(PhaseType.MAIN1)
if (ph.is(PhaseType.MAIN1) && ph.isPlayerTurn(aiPlayer)
&& !ComputerUtil.castPermanentInMain1(aiPlayer, sa)) {
return false;
}

View File

@@ -2,6 +2,8 @@ package forge.ai.ability;
import forge.ai.ComputerUtil;
import forge.ai.SpellAbilityAi;
import forge.game.Game;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
@@ -18,13 +20,15 @@ public class PermanentNoncreatureAi extends SpellAbilityAi {
@Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
String logic = sa.getParam("AILogic");
Game game = aiPlayer.getGame();
final PhaseHandler ph = game.getPhaseHandler();
if ("DontCast".equals(logic)) {
return false;
}
// Wait for Main2 if possible
if (aiPlayer.getGame().getPhaseHandler().is(PhaseType.MAIN1)
if (ph.is(PhaseType.MAIN1) && ph.isPlayerTurn(aiPlayer)
&& !ComputerUtil.castPermanentInMain1(aiPlayer, sa)) {
return false;
}