mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- Re-factored AiBlockController.shouldThisBlock() into ComputerUtilCard.doesSpecifiedCreatureBlock()
- Changed Outlast AI to use doesSpecifiedCreatureBlock()
This commit is contained in:
@@ -927,23 +927,6 @@ public class AiBlockController {
|
|||||||
return first;
|
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)
|
* Check if an attacker can be blocked profitably (ie. kill attacker)
|
||||||
* @param ai controller of attacking creature
|
* @param ai controller of attacking creature
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import forge.game.Game;
|
|||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.*;
|
import forge.game.card.*;
|
||||||
import forge.game.combat.Combat;
|
import forge.game.combat.Combat;
|
||||||
|
import forge.game.combat.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;
|
||||||
@@ -627,12 +628,51 @@ public class ComputerUtilCard {
|
|||||||
aiAtk.declareAttackers(combat);
|
aiAtk.declareAttackers(combat);
|
||||||
return combat.isAttacking(card);
|
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) {
|
public static boolean doesSpecifiedCreatureAttackAI(final Player ai, final Card card) {
|
||||||
AiAttackController aiAtk = new AiAttackController(ai, card);
|
AiAttackController aiAtk = new AiAttackController(ai, card);
|
||||||
Combat combat = new Combat(ai);
|
Combat combat = new Combat(ai);
|
||||||
aiAtk.declareAttackers(combat);
|
aiAtk.declareAttackers(combat);
|
||||||
return combat.isAttacking(card);
|
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.
|
* getMostExpensivePermanentAI.
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package forge.ai.ability;
|
|||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.ai.AiBlockController;
|
|
||||||
import forge.ai.ComputerUtilCard;
|
import forge.ai.ComputerUtilCard;
|
||||||
import forge.ai.ComputerUtilCost;
|
import forge.ai.ComputerUtilCost;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
@@ -171,7 +170,7 @@ public class AnimateAi extends SpellAbilityAi {
|
|||||||
if (ph.isPlayerTurn(aiPlayer) && !ComputerUtilCard.doesSpecifiedCreatureAttackAI(aiPlayer, animatedCopy)) {
|
if (ph.isPlayerTurn(aiPlayer) && !ComputerUtilCard.doesSpecifiedCreatureAttackAI(aiPlayer, animatedCopy)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ph.getPlayerTurn().isOpponentOf(aiPlayer) && !AiBlockController.shouldThisBlock(aiPlayer, animatedCopy)) {
|
if (ph.getPlayerTurn().isOpponentOf(aiPlayer) && !ComputerUtilCard.doesSpecifiedCreatureBlock(aiPlayer, animatedCopy)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,8 +168,8 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
if (sa.isOutlast()) {
|
if (sa.isOutlast()) {
|
||||||
if (ph.is(PhaseType.MAIN2, ai)) { //applicable to non-attackers only
|
if (ph.is(PhaseType.MAIN2, ai)) { //applicable to non-attackers only
|
||||||
float chance = 0.8f;
|
float chance = 0.8f;
|
||||||
if (!ai.getOpponent().getCreaturesInPlay().isEmpty()) {
|
if (ComputerUtilCard.doesSpecifiedCreatureBlock(ai, source)) {
|
||||||
chance /= 2; //needs a better way to check if target is required as a blocker
|
return false;
|
||||||
}
|
}
|
||||||
return chance > r.nextFloat();
|
return chance > r.nextFloat();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user