mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
- Improvements and cleanup in AiAttackController.
This commit is contained in:
@@ -68,8 +68,7 @@ public class AiAttackController {
|
|||||||
private final Player ai;
|
private final Player ai;
|
||||||
private Player defendingOpponent;
|
private Player defendingOpponent;
|
||||||
|
|
||||||
private int aiAggression = 0; // added by Masher, how aggressive the ai is
|
private int aiAggression = 0; // added by Masher, how aggressive the ai is attack will be depending on circumstances
|
||||||
// attack will be depending on circumstances
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,7 +203,8 @@ public class AiAttackController {
|
|||||||
if (ComputerUtilCombat.poisonIfUnblocked(attacker, opp) > 0) {
|
if (ComputerUtilCombat.poisonIfUnblocked(attacker, opp) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (this.attackers.size() == 1 && attacker.hasKeyword("Exalted") && ComputerUtilCombat.predictDamageTo(opp, 1, attacker, true) > 0) {
|
if (this.attackers.size() == 1 && attacker.hasKeyword("Exalted")
|
||||||
|
&& ComputerUtilCombat.predictDamageTo(opp, 1, attacker, true) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,27 +224,26 @@ public class AiAttackController {
|
|||||||
possibleBlockers = CardLists.filter(possibleBlockers, new Predicate<Card>() {
|
possibleBlockers = CardLists.filter(possibleBlockers, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
return canBlockAnAttacker(c, attackers);
|
return canBlockAnAttacker(c, attackers, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return possibleBlockers;
|
return possibleBlockers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static boolean canBlockAnAttacker(final Card c, final List<Card> attackers) {
|
public final static boolean canBlockAnAttacker(final Card c, final List<Card> attackers, final boolean nextTurn) {
|
||||||
final List<Card> attackerList = new ArrayList<Card>(attackers);
|
final List<Card> attackerList = new ArrayList<Card>(attackers);
|
||||||
if (!c.isCreature()) {
|
if (!c.isCreature()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (final Card attacker : attackerList) {
|
for (final Card attacker : attackerList) {
|
||||||
if (CombatUtil.canBlock(attacker, c)) {
|
if (CombatUtil.canBlock(attacker, c, nextTurn)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this checks to make sure that the computer player
|
// this checks to make sure that the computer player doesn't lose when the human player attacks
|
||||||
// doesn't lose when the human player attacks
|
|
||||||
// this method is used by getAttackers()
|
// this method is used by getAttackers()
|
||||||
public final List<Card> notNeededAsBlockers(final Player ai, final List<Card> attackers) {
|
public final List<Card> notNeededAsBlockers(final Player ai, final List<Card> attackers) {
|
||||||
final List<Card> notNeededAsBlockers = new ArrayList<Card>(attackers);
|
final List<Card> notNeededAsBlockers = new ArrayList<Card>(attackers);
|
||||||
@@ -254,13 +253,20 @@ public class AiAttackController {
|
|||||||
if (ai.getGame().getPhaseHandler().getNextTurn().equals(ai)) {
|
if (ai.getGame().getPhaseHandler().getNextTurn().equals(ai)) {
|
||||||
return attackers;
|
return attackers;
|
||||||
}
|
}
|
||||||
|
List<Card> opponentsAttackers = new ArrayList<Card>(oppList);
|
||||||
|
opponentsAttackers = CardLists.filter(opponentsAttackers, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
return ComputerUtilCombat.canAttackNextTurn(c) && c.getNetCombatDamage() > 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
for (final Card c : this.myList) {
|
for (final Card c : this.myList) {
|
||||||
if (c.getName().equals("Masako the Humorless")) {
|
if (c.getName().equals("Masako the Humorless")) {
|
||||||
// "Tapped creatures you control can block as though they were untapped."
|
// "Tapped creatures you control can block as though they were untapped."
|
||||||
return attackers;
|
return attackers;
|
||||||
}
|
}
|
||||||
if (!attackers.contains(c)) { // this creature can't attack anyway
|
if (!attackers.contains(c)) { // this creature can't attack anyway
|
||||||
if (canBlockAnAttacker(c, this.oppList)) {
|
if (canBlockAnAttacker(c, opponentsAttackers, false)) {
|
||||||
fixedBlockers++;
|
fixedBlockers++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -268,16 +274,16 @@ public class AiAttackController {
|
|||||||
if (c.hasKeyword("Vigilance")) {
|
if (c.hasKeyword("Vigilance")) {
|
||||||
vigilantes.add(c);
|
vigilantes.add(c);
|
||||||
notNeededAsBlockers.remove(c); // they will be re-added later
|
notNeededAsBlockers.remove(c); // they will be re-added later
|
||||||
if (canBlockAnAttacker(c, this.oppList)) {
|
if (canBlockAnAttacker(c, opponentsAttackers, false)) {
|
||||||
fixedBlockers++;
|
fixedBlockers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CardLists.sortByPowerAsc(attackers);
|
CardLists.sortByPowerAsc(attackers);
|
||||||
int blockersNeeded = this.oppList.size();
|
int blockersNeeded = opponentsAttackers.size();
|
||||||
|
|
||||||
// don't hold back creatures that can't block any of the human creatures
|
// don't hold back creatures that can't block any of the human creatures
|
||||||
final List<Card> list = getPossibleBlockers(attackers, this.oppList);
|
final List<Card> list = getPossibleBlockers(attackers, opponentsAttackers);
|
||||||
|
|
||||||
//Calculate the amount of creatures necessary
|
//Calculate the amount of creatures necessary
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
@@ -313,9 +319,7 @@ public class AiAttackController {
|
|||||||
final boolean finestHour = opp.isCardInPlay("Finest Hour");
|
final boolean finestHour = opp.isCardInPlay("Finest Hour");
|
||||||
|
|
||||||
if ((blockersNeeded == 0 || finestHour) && !this.oppList.isEmpty()) {
|
if ((blockersNeeded == 0 || finestHour) && !this.oppList.isEmpty()) {
|
||||||
//
|
// total attack = biggest creature + exalted, *2 if Rafiq is in play
|
||||||
// total attack = biggest creature + exalted, *2 if Rafiq is in
|
|
||||||
// play
|
|
||||||
int humanBasePower = getAttack(this.oppList.get(0)) + humanExaltedBonus;
|
int humanBasePower = getAttack(this.oppList.get(0)) + humanExaltedBonus;
|
||||||
if (finestHour) {
|
if (finestHour) {
|
||||||
// For Finest Hour, one creature could attack and get the
|
// For Finest Hour, one creature could attack and get the
|
||||||
@@ -326,7 +330,7 @@ public class AiAttackController {
|
|||||||
: humanBasePower;
|
: humanBasePower;
|
||||||
if (ai.getLife() - 3 <= totalExaltedAttack) {
|
if (ai.getLife() - 3 <= totalExaltedAttack) {
|
||||||
// We will lose if there is an Exalted attack -- keep one blocker
|
// We will lose if there is an Exalted attack -- keep one blocker
|
||||||
if ((blockersNeeded == 0) && !notNeededAsBlockers.isEmpty()) {
|
if (blockersNeeded == 0 && !notNeededAsBlockers.isEmpty()) {
|
||||||
notNeededAsBlockers.remove(0);
|
notNeededAsBlockers.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,8 +366,7 @@ public class AiAttackController {
|
|||||||
totalPoison += ComputerUtilCombat.poisonIfUnblocked(attacker, ai);
|
totalPoison += ComputerUtilCombat.poisonIfUnblocked(attacker, ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalAttack > 0 && ai.getLife() <= totalAttack
|
if (totalAttack > 0 && ai.getLife() <= totalAttack && !ai.cantLoseForZeroOrLessLife()) {
|
||||||
&& !ai.cantLoseForZeroOrLessLife()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return ai.getPoisonCounters() + totalPoison > 9;
|
return ai.getPoisonCounters() + totalPoison > 9;
|
||||||
@@ -371,8 +374,7 @@ public class AiAttackController {
|
|||||||
|
|
||||||
private boolean doAssault(final Player ai) {
|
private boolean doAssault(final Player ai) {
|
||||||
// Beastmaster Ascension
|
// Beastmaster Ascension
|
||||||
if (ai.isCardInPlay("Beastmaster Ascension")
|
if (ai.isCardInPlay("Beastmaster Ascension") && this.attackers.size() > 1) {
|
||||||
&& (this.attackers.size() > 1)) {
|
|
||||||
final CardCollectionView beastions = ai.getCardsIn(ZoneType.Battlefield, "Beastmaster Ascension");
|
final CardCollectionView beastions = ai.getCardsIn(ZoneType.Battlefield, "Beastmaster Ascension");
|
||||||
int minCreatures = 7;
|
int minCreatures = 7;
|
||||||
for (final Card beastion : beastions) {
|
for (final Card beastion : beastions) {
|
||||||
@@ -445,12 +447,12 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ComputerUtilCombat.sumDamageIfUnblocked(unblockedAttackers, opp) + ComputerUtil.possibleNonCombatDamage(ai)
|
if (ComputerUtilCombat.sumDamageIfUnblocked(unblockedAttackers, opp) + ComputerUtil.possibleNonCombatDamage(ai)
|
||||||
+ trampleDamage>= opp.getLife()
|
+ trampleDamage >= opp.getLife()
|
||||||
&& !((opp.cantLoseForZeroOrLessLife() || ai.cantWin()) && (opp.getLife() < 1))) {
|
&& !((opp.cantLoseForZeroOrLessLife() || ai.cantWin()) && opp.getLife() < 1)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ComputerUtilCombat.sumPoisonIfUnblocked(unblockedAttackers, opp) >= (10 - opp.getPoisonCounters())) {
|
if (ComputerUtilCombat.sumPoisonIfUnblocked(unblockedAttackers, opp) >= 10 - opp.getPoisonCounters()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +545,7 @@ public class AiAttackController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (bAssault) {
|
if (bAssault) {
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println("Assault");
|
System.out.println("Assault");
|
||||||
CardLists.sortByPowerDesc(attackersLeft);
|
CardLists.sortByPowerDesc(attackersLeft);
|
||||||
for (Card attacker : attackersLeft) {
|
for (Card attacker : attackersLeft) {
|
||||||
@@ -557,7 +559,7 @@ public class AiAttackController {
|
|||||||
// Cards that are remembered to attack anyway (e.g. temporarily stolen creatures)
|
// Cards that are remembered to attack anyway (e.g. temporarily stolen creatures)
|
||||||
if (ai.getController() instanceof PlayerControllerAi) {
|
if (ai.getController() instanceof PlayerControllerAi) {
|
||||||
// Only do this if |ai| is actually an AI - as we could be trying to predict how the human will attack.
|
// Only do this if |ai| is actually an AI - as we could be trying to predict how the human will attack.
|
||||||
AiCardMemory aiMemory = ((PlayerControllerAi)ai.getController()).getAi().getCardMemory();
|
AiCardMemory aiMemory = ((PlayerControllerAi) ai.getController()).getAi().getCardMemory();
|
||||||
for (Card attacker : this.attackers) {
|
for (Card attacker : this.attackers) {
|
||||||
if (aiMemory.isRememberedCard(attacker, AiCardMemory.MemorySet.MANDATORY_ATTACKERS)) {
|
if (aiMemory.isRememberedCard(attacker, AiCardMemory.MemorySet.MANDATORY_ATTACKERS)) {
|
||||||
combat.addAttacker(attacker, defender);
|
combat.addAttacker(attacker, defender);
|
||||||
@@ -589,11 +591,11 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
if (exalted) {
|
if (exalted) {
|
||||||
CardLists.sortByPowerDesc(this.attackers);
|
CardLists.sortByPowerDesc(this.attackers);
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println("Exalted");
|
System.out.println("Exalted");
|
||||||
this.aiAggression = 6;
|
this.aiAggression = 6;
|
||||||
for (Card attacker : this.attackers) {
|
for (Card attacker : this.attackers) {
|
||||||
if (CombatUtil.canAttack(attacker, defender) && this.shouldAttack(ai, attacker, this.blockers, combat)) {
|
if (CombatUtil.canAttack(attacker, defender) && this.shouldAttack(ai, attacker, this.blockers, combat)) {
|
||||||
combat.addAttacker(attacker, defender);
|
combat.addAttacker(attacker, defender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -612,20 +614,30 @@ public class AiAttackController {
|
|||||||
// examine the potential forces
|
// examine the potential forces
|
||||||
final List<Card> nextTurnAttackers = new ArrayList<Card>();
|
final List<Card> nextTurnAttackers = new ArrayList<Card>();
|
||||||
int candidateCounterAttackDamage = 0;
|
int candidateCounterAttackDamage = 0;
|
||||||
|
|
||||||
|
final Player opp = this.defendingOpponent;
|
||||||
|
// get the potential damage and strength of the AI forces
|
||||||
|
final List<Card> candidateAttackers = new ArrayList<Card>();
|
||||||
|
int candidateUnblockedDamage = 0;
|
||||||
|
for (final Card pCard : this.myList) {
|
||||||
|
// if the creature can attack then it's a potential attacker this
|
||||||
|
// turn, assume summoning sickness creatures will be able to
|
||||||
|
if (ComputerUtilCombat.canAttackNextTurn(pCard) && pCard.getNetCombatDamage() > 0) {
|
||||||
|
candidateAttackers.add(pCard);
|
||||||
|
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null, false);
|
||||||
|
computerForces += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (final Card pCard : this.oppList) {
|
for (final Card pCard : this.oppList) {
|
||||||
// if the creature can attack next turn add it to counter attackers
|
// if the creature can attack next turn add it to counter attackers list
|
||||||
// list
|
if (ComputerUtilCombat.canAttackNextTurn(pCard) && pCard.getNetCombatDamage() > 0) {
|
||||||
if (ComputerUtilCombat.canAttackNextTurn(pCard)) {
|
|
||||||
nextTurnAttackers.add(pCard);
|
nextTurnAttackers.add(pCard);
|
||||||
if (pCard.getNetCombatDamage() > 0) {
|
candidateCounterAttackDamage += pCard.getNetCombatDamage();
|
||||||
candidateCounterAttackDamage += pCard.getNetCombatDamage();
|
humanForces += 1; // player forces they might use to attack
|
||||||
humanForces += 1; // player forces they might use to attack
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// increment player forces that are relevant to an attritional
|
// increment player forces that are relevant to an attritional attack - includes walls
|
||||||
// attack - includes walls
|
if (canBlockAnAttacker(pCard, candidateAttackers, true)) {
|
||||||
if (CombatUtil.canBlock(pCard, true)) {
|
|
||||||
humanForcesForAttritionalAttack += 1;
|
humanForcesForAttritionalAttack += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -636,22 +648,6 @@ public class AiAttackController {
|
|||||||
aiLifeToPlayerDamageRatio = (double) ai.getLife() / candidateCounterAttackDamage;
|
aiLifeToPlayerDamageRatio = (double) ai.getLife() / candidateCounterAttackDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Player opp = this.defendingOpponent;
|
|
||||||
// get the potential damage and strength of the AI forces
|
|
||||||
final List<Card> candidateAttackers = new ArrayList<Card>();
|
|
||||||
int candidateUnblockedDamage = 0;
|
|
||||||
for (final Card pCard : this.myList) {
|
|
||||||
// if the creature can attack then it's a potential attacker this
|
|
||||||
// turn, assume summoning sickness creatures will be able to
|
|
||||||
if (ComputerUtilCombat.canAttackNextTurn(pCard)) {
|
|
||||||
candidateAttackers.add(pCard);
|
|
||||||
if (pCard.getNetCombatDamage() > 0) {
|
|
||||||
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null, false);
|
|
||||||
computerForces += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the potential damage ratio the AI can cause
|
// find the potential damage ratio the AI can cause
|
||||||
double humanLifeToDamageRatio = 1000000;
|
double humanLifeToDamageRatio = 1000000;
|
||||||
if (candidateUnblockedDamage > 0) {
|
if (candidateUnblockedDamage > 0) {
|
||||||
@@ -751,8 +747,7 @@ public class AiAttackController {
|
|||||||
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, null, false);
|
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife()
|
if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife() && opp.canLoseLife()) {
|
||||||
&& opp.canLoseLife()) {
|
|
||||||
turnsUntilDeathByUnblockable = 1 + (opp.getLife() - unblockableDamage) / nextUnblockableDamage;
|
turnsUntilDeathByUnblockable = 1 + (opp.getLife() - unblockableDamage) / nextUnblockableDamage;
|
||||||
}
|
}
|
||||||
if (opp.canLoseLife()) {
|
if (opp.canLoseLife()) {
|
||||||
@@ -796,7 +791,7 @@ public class AiAttackController {
|
|||||||
if ( LOG_AI_ATTACKS )
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println("Normal attack");
|
System.out.println("Normal attack");
|
||||||
|
|
||||||
attackersLeft = this.notNeededAsBlockers(ai, attackersLeft);
|
attackersLeft = notNeededAsBlockers(ai, attackersLeft);
|
||||||
attackersLeft = sortAttackers(attackersLeft);
|
attackersLeft = sortAttackers(attackersLeft);
|
||||||
|
|
||||||
if ( LOG_AI_ATTACKS )
|
if ( LOG_AI_ATTACKS )
|
||||||
@@ -971,8 +966,7 @@ public class AiAttackController {
|
|||||||
canBeKilledByOne = true;
|
canBeKilledByOne = true;
|
||||||
isWorthLessThanAllKillers = false;
|
isWorthLessThanAllKillers = false;
|
||||||
hasCombatEffect = false;
|
hasCombatEffect = false;
|
||||||
}
|
} else if (ComputerUtilCard.canBeBlockedProfitably(defendingOpponent, attacker)) {
|
||||||
else if (ComputerUtilCard.canBeBlockedProfitably(defendingOpponent, attacker)) {
|
|
||||||
canKillAllDangerous = false;
|
canKillAllDangerous = false;
|
||||||
canBeKilled = true;
|
canBeKilled = true;
|
||||||
}
|
}
|
||||||
@@ -980,7 +974,7 @@ public class AiAttackController {
|
|||||||
// if the creature cannot block and can kill all opponents they might as
|
// if the creature cannot block and can kill all opponents they might as
|
||||||
// well attack, they do nothing staying back
|
// well attack, they do nothing staying back
|
||||||
if (canKillAll && isWorthLessThanAllKillers && !CombatUtil.canBlock(attacker)) {
|
if (canKillAll && isWorthLessThanAllKillers && !CombatUtil.canBlock(attacker)) {
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println(attacker.getName() + " = attacking because they can't block, expecting to kill or damage player");
|
System.out.println(attacker.getName() + " = attacking because they can't block, expecting to kill or damage player");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -997,44 +991,42 @@ public class AiAttackController {
|
|||||||
switch (this.aiAggression) {
|
switch (this.aiAggression) {
|
||||||
case 6: // Exalted: expecting to at least kill a creature of equal value or not be blocked
|
case 6: // Exalted: expecting to at least kill a creature of equal value or not be blocked
|
||||||
if ((canKillAll && isWorthLessThanAllKillers) || !canBeBlocked) {
|
if ((canKillAll && isWorthLessThanAllKillers) || !canBeBlocked) {
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println(attacker.getName() + " = attacking expecting to kill creature, or is unblockable");
|
System.out.println(attacker.getName() + " = attacking expecting to kill creature, or is unblockable");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // all out attacking
|
case 5: // all out attacking
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println(attacker.getName() + " = all out attacking");
|
System.out.println(attacker.getName() + " = all out attacking");
|
||||||
return true;
|
return true;
|
||||||
case 4: // expecting to at least trade with something
|
case 4: // expecting to at least trade with something
|
||||||
if (canKillAll || (canKillAllDangerous && !canBeKilledByOne) || !canBeBlocked) {
|
if (canKillAll || (canKillAllDangerous && !canBeKilledByOne) || !canBeBlocked) {
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println(attacker.getName() + " = attacking expecting to at least trade with something");
|
System.out.println(attacker.getName() + " = attacking expecting to at least trade with something");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // expecting to at least kill a creature of equal value, not be
|
case 3: // expecting to at least kill a creature of equal value or not be blocked
|
||||||
// blocked
|
|
||||||
if ((canKillAll && isWorthLessThanAllKillers)
|
if ((canKillAll && isWorthLessThanAllKillers)
|
||||||
|| ((canKillAllDangerous || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne)
|
|| ((canKillAllDangerous || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne)
|
||||||
|| !canBeBlocked) {
|
|| !canBeBlocked) {
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println(attacker.getName() + " = attacking expecting to kill creature or cause damage, or is unblockable");
|
System.out.println(attacker.getName() + " = attacking expecting to kill creature or cause damage, or is unblockable");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // attack expecting to attract a group block or destroying a
|
case 2: // attack expecting to attract a group block or destroying a single blocker and surviving
|
||||||
// single blocker and surviving
|
if (!canBeBlocked || ((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne &&
|
||||||
if ((((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne) || !canBeBlocked) &&
|
(canKillAllDangerous || !canBeKilled))) {
|
||||||
(canKillAllDangerous || !canBeKilled)) {
|
if (LOG_AI_ATTACKS)
|
||||||
if ( LOG_AI_ATTACKS )
|
|
||||||
System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block");
|
System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // unblockable creatures only
|
case 1: // unblockable creatures only
|
||||||
if (!canBeBlocked || (numberOfPossibleBlockers == 1 && canKillAll && !canBeKilledByOne)) {
|
if (!canBeBlocked || (numberOfPossibleBlockers == 1 && canKillAll && !canBeKilledByOne)) {
|
||||||
if ( LOG_AI_ATTACKS )
|
if (LOG_AI_ATTACKS)
|
||||||
System.out.println(attacker.getName() + " = attacking expecting not to be blocked");
|
System.out.println(attacker.getName() + " = attacking expecting not to be blocked");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user