mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
- Improved AI chump-blocking Tramplers.
This commit is contained in:
@@ -567,26 +567,56 @@ public class ComputerUtilBlock {
|
|||||||
private static Combat makeChumpBlocks(final Player ai, final Combat combat) {
|
private static Combat makeChumpBlocks(final Player ai, final Combat combat) {
|
||||||
|
|
||||||
List<Card> currentAttackers = new ArrayList<Card>(ComputerUtilBlock.getAttackersLeft());
|
List<Card> currentAttackers = new ArrayList<Card>(ComputerUtilBlock.getAttackersLeft());
|
||||||
List<Card> chumpBlockers;
|
|
||||||
|
|
||||||
for (final Card attacker : ComputerUtilBlock.getAttackersLeft()) {
|
return makeChumpBlocks(ai, combat, currentAttackers);
|
||||||
|
}
|
||||||
if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")
|
|
||||||
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
private static Combat makeChumpBlocks(final Player ai, final Combat combat, List<Card> attackers) {
|
||||||
continue;
|
|
||||||
}
|
if (attackers.isEmpty() || !ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
|
return combat;
|
||||||
chumpBlockers = ComputerUtilBlock
|
|
||||||
.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true);
|
|
||||||
if ((chumpBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
|
||||||
final Card blocker = ComputerUtilCard.getWorstCreatureAI(chumpBlockers);
|
|
||||||
combat.addBlocker(attacker, blocker);
|
|
||||||
currentAttackers.remove(attacker);
|
|
||||||
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ComputerUtilBlock.setAttackersLeft(new ArrayList<Card>(currentAttackers));
|
|
||||||
return combat;
|
Card attacker = attackers.get(0);
|
||||||
|
|
||||||
|
if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")
|
||||||
|
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||||
|
attackers.remove(0);
|
||||||
|
return makeChumpBlocks(ai, combat, attackers);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Card> chumpBlockers = ComputerUtilBlock
|
||||||
|
.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true);
|
||||||
|
if (!chumpBlockers.isEmpty()) {
|
||||||
|
final Card blocker = ComputerUtilCard.getWorstCreatureAI(chumpBlockers);
|
||||||
|
|
||||||
|
// check if it's better to block a creature with lower power and without trample
|
||||||
|
if (attacker.hasKeyword("Trample")) {
|
||||||
|
final int damageAbsorbed = blocker.getLethalDamage();
|
||||||
|
if (attacker.getNetCombatDamage() > damageAbsorbed) {
|
||||||
|
for (Card other : attackers) {
|
||||||
|
if (other.equals(attacker)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (other.getNetCombatDamage() >= damageAbsorbed
|
||||||
|
&& !other.hasKeyword("Trample")
|
||||||
|
&& CombatUtil.canBlock(other, blocker, combat)) {
|
||||||
|
combat.addBlocker(other, blocker);
|
||||||
|
ComputerUtilBlock.getAttackersLeft().remove(other);
|
||||||
|
ComputerUtilBlock.getBlockedButUnkilled().add(other);
|
||||||
|
attackers.remove(other);
|
||||||
|
return makeChumpBlocks(ai, combat, attackers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
combat.addBlocker(attacker, blocker);
|
||||||
|
ComputerUtilBlock.getAttackersLeft().remove(attacker);
|
||||||
|
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
||||||
|
}
|
||||||
|
attackers.remove(0);
|
||||||
|
return makeChumpBlocks(ai, combat, attackers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinforce blockers blocking attackers with trample (should only be made
|
// Reinforce blockers blocking attackers with trample (should only be made
|
||||||
@@ -777,13 +807,7 @@ public class ComputerUtilBlock {
|
|||||||
List<Card> blockers;
|
List<Card> blockers;
|
||||||
List<Card> chumpBlockers;
|
List<Card> chumpBlockers;
|
||||||
|
|
||||||
ComputerUtilBlock.setDiff((ai.getLife() * 2) - 5); // This
|
ComputerUtilBlock.setDiff((ai.getLife() * 2) - 5); // This is the minimal gain for an unnecessary trade
|
||||||
// is
|
|
||||||
// the
|
|
||||||
// minimal gain
|
|
||||||
// for an
|
|
||||||
// unnecessary
|
|
||||||
// trade
|
|
||||||
|
|
||||||
// remove all attackers that can't be blocked anyway
|
// remove all attackers that can't be blocked anyway
|
||||||
for (final Card a : ComputerUtilBlock.getAttackers()) {
|
for (final Card a : ComputerUtilBlock.getAttackers()) {
|
||||||
@@ -810,15 +834,11 @@ public class ComputerUtilBlock {
|
|||||||
combat = ComputerUtilBlock.makeGoodBlocks(ai, combat);
|
combat = ComputerUtilBlock.makeGoodBlocks(ai, combat);
|
||||||
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose
|
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose necessary trade blocks
|
||||||
// necessary
|
|
||||||
// trade blocks
|
|
||||||
}
|
}
|
||||||
// if life is in danger
|
// if life is in danger
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose
|
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose necessary chump blocks
|
||||||
// necessary
|
|
||||||
// chump blocks
|
|
||||||
}
|
}
|
||||||
// if life is still in danger
|
// if life is still in danger
|
||||||
// Reinforce blockers blocking attackers with trample if life is still
|
// Reinforce blockers blocking attackers with trample if life is still
|
||||||
@@ -836,22 +856,14 @@ public class ComputerUtilBlock {
|
|||||||
// ==
|
// ==
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
lifeInDanger = true;
|
lifeInDanger = true;
|
||||||
combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset
|
combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset every block assignment
|
||||||
// every
|
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose necessary trade blocks
|
||||||
// block
|
|
||||||
// assignment
|
|
||||||
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose
|
|
||||||
// necessary
|
|
||||||
// trade blocks
|
|
||||||
// if life is in danger
|
// if life is in danger
|
||||||
combat = ComputerUtilBlock.makeGoodBlocks(ai, combat);
|
combat = ComputerUtilBlock.makeGoodBlocks(ai, combat);
|
||||||
|
// choose necessary chump blocks if life is still in danger
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose
|
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat);
|
||||||
// necessary
|
|
||||||
// chump
|
|
||||||
}
|
}
|
||||||
// blocks if life is still in
|
|
||||||
// danger
|
|
||||||
// Reinforce blockers blocking attackers with trample if life is
|
// Reinforce blockers blocking attackers with trample if life is
|
||||||
// still in danger
|
// still in danger
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
@@ -861,19 +873,12 @@ public class ComputerUtilBlock {
|
|||||||
combat = ComputerUtilBlock.reinforceBlockersToKill(ai, combat);
|
combat = ComputerUtilBlock.reinforceBlockersToKill(ai, combat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// == 3. If the AI life would be in serious danger make an even safer
|
// == 3. If the AI life would be in serious danger make an even safer approach ==
|
||||||
// approach ==
|
if (lifeInDanger && ComputerUtilCombat.lifeInSeriousDanger(ai, combat)) {
|
||||||
if (ComputerUtilCombat.lifeInSeriousDanger(ai, combat)) {
|
combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset every block assignment
|
||||||
combat = ComputerUtilBlock.resetBlockers(combat, possibleBlockers); // reset
|
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose chump blocks
|
||||||
// every
|
|
||||||
// block
|
|
||||||
// assignment
|
|
||||||
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose chump
|
|
||||||
// blocks
|
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose
|
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose necessary trade
|
||||||
// necessary
|
|
||||||
// trade
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user