- Re-factored AiBlockController.shouldThisBlock() into ComputerUtilCard.doesSpecifiedCreatureBlock()

- Changed Outlast AI to use doesSpecifiedCreatureBlock()
This commit is contained in:
excessum
2014-09-24 13:04:46 +00:00
parent 2813896e6b
commit 14c4b95658
4 changed files with 43 additions and 21 deletions

View File

@@ -927,23 +927,6 @@ public class AiBlockController {
return first;
}
/**
* Decide if a creature is going to be used as a blocker (is only used for AnimateAi so far)
* @param ai controller of creature
* @param blocker creature to be evaluated (must NOT already be in combat)
* @return creature will be a blocker
*/
public static boolean shouldThisBlock(final Player ai, Card blocker) {
AiBlockController aiBlk = new AiBlockController(ai);
Combat combat = ai.getGame().getCombat();
aiBlk.assignBlockers(combat, blocker, null);
if (combat.getAllBlockers().isEmpty()) {
return false;
} else {
combat.removeFromCombat(blocker);
return true;
}
}
/**
* Check if an attacker can be blocked profitably (ie. kill attacker)
* @param ai controller of attacking creature

View File

@@ -15,6 +15,7 @@ import forge.game.Game;
import forge.game.ability.AbilityUtils;
import forge.game.card.*;
import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
@@ -627,12 +628,51 @@ public class ComputerUtilCard {
aiAtk.declareAttackers(combat);
return combat.isAttacking(card);
}
/**
* Extension of doesCreatureAttackAI() for "virtual" creatures that do not actually exist on the battlefield yet
* such as unanimated manlands.
* @param ai controller of creature
* @param card creature to be evaluated
* @return creature will be attack
*/
public static boolean doesSpecifiedCreatureAttackAI(final Player ai, final Card card) {
AiAttackController aiAtk = new AiAttackController(ai, card);
Combat combat = new Combat(ai);
aiAtk.declareAttackers(combat);
return combat.isAttacking(card);
}
/**
* Decide if a creature is going to be used as a blocker.
* @param ai controller of creature
* @param blocker creature to be evaluated
* @return creature will be a blocker
*/
public static boolean doesSpecifiedCreatureBlock(final Player ai, Card blocker) {
AiBlockController aiBlk = new AiBlockController(ai);
Combat combat = ai.getGame().getCombat();
if (combat == null) {
final Player opp = ai.getOpponent();
combat = new Combat(opp);
for (Card c : opp.getCreaturesInPlay()) {
if (CombatUtil.canAttackNextTurn(c, ai)) {
combat.addAttacker(c, ai);
}
}
} else {
if (combat.getAllBlockers().contains(blocker)) {
return true;
}
}
aiBlk.assignBlockers(combat, blocker, null);
if (!combat.getAllBlockers().contains(blocker)) {
return false;
} else {
combat.removeFromCombat(blocker);
return true;
}
}
/**
* getMostExpensivePermanentAI.

View File

@@ -3,7 +3,6 @@ package forge.ai.ability;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.ai.AiBlockController;
import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCost;
import forge.ai.SpellAbilityAi;
@@ -171,7 +170,7 @@ public class AnimateAi extends SpellAbilityAi {
if (ph.isPlayerTurn(aiPlayer) && !ComputerUtilCard.doesSpecifiedCreatureAttackAI(aiPlayer, animatedCopy)) {
return false;
}
if (ph.getPlayerTurn().isOpponentOf(aiPlayer) && !AiBlockController.shouldThisBlock(aiPlayer, animatedCopy)) {
if (ph.getPlayerTurn().isOpponentOf(aiPlayer) && !ComputerUtilCard.doesSpecifiedCreatureBlock(aiPlayer, animatedCopy)) {
return false;
}
}

View File

@@ -168,8 +168,8 @@ public class CountersPutAi extends SpellAbilityAi {
if (sa.isOutlast()) {
if (ph.is(PhaseType.MAIN2, ai)) { //applicable to non-attackers only
float chance = 0.8f;
if (!ai.getOpponent().getCreaturesInPlay().isEmpty()) {
chance /= 2; //needs a better way to check if target is required as a blocker
if (ComputerUtilCard.doesSpecifiedCreatureBlock(ai, source)) {
return false;
}
return chance > r.nextFloat();
} else {