diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 58b67361236..7e5f7144482 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -1735,6 +1735,7 @@ public class ComputerUtilCombat { final int attackerLife = getDamageToKill(attacker, false) + predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities); + // AI should be less worried about Deathtouch if (blocker.hasDoubleStrike()) { if (defenderDamage > 0 && (hasKeyword(blocker, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) { return true; @@ -1964,6 +1965,7 @@ public class ComputerUtilCombat { final int attackerLife = getDamageToKill(attacker, false) + predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities); + // AI should be less worried about deathtouch if (attacker.hasDoubleStrike()) { if (attackerDamage >= defenderLife) { return true; diff --git a/forge-gui-desktop/src/test/java/forge/ai/attacking/BasicAttackTests.java b/forge-gui-desktop/src/test/java/forge/ai/attacking/BasicAttackTests.java new file mode 100644 index 00000000000..ec17d0251e3 --- /dev/null +++ b/forge-gui-desktop/src/test/java/forge/ai/attacking/BasicAttackTests.java @@ -0,0 +1,138 @@ +package forge.ai.attacking; + +import forge.ai.PlayerControllerAi; +import forge.ai.simulation.SimulationTest; +import forge.game.Game; +import forge.game.card.Card; +import forge.game.combat.Combat; +import forge.game.phase.PhaseType; +import forge.game.player.Player; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +public class BasicAttackTests extends SimulationTest { + + @Test + public void assaultForLethal() { + Game game = initAndCreateGame(); + Player attacker = game.getPlayers().get(1); + Player defender = game.getPlayers().get(0); + + defender.setLife(10, null); + + String bears = "Grizzly Bears"; + + // Add 5 bears and make sure they can attack + Card bear1 = addCard(bears, attacker); + Card bear2 = addCard(bears, attacker); + Card bear3 = addCard(bears, attacker); + Card bear4 = addCard(bears, attacker); + Card bear5 = addCard(bears, attacker); + + // Make sure the bears can attack + bear1.setSickness(false); + bear2.setSickness(false); + bear3.setSickness(false); + bear4.setSickness(false); + bear5.setSickness(false); + + game.getPhaseHandler().devModeSet(PhaseType.MAIN1, attacker); + game.getAction().checkStateEffects(true); + + // Get the simulated game state after AI has declared attackers + Combat combat = ((PlayerControllerAi)attacker.getController()).getAi().getPredictedCombat(); + + // Check how many creatures are attacking + int attackingCreatures = combat.getAttackers().size(); + AssertJUnit.assertEquals("AI should attack with all 5 bears for lethal", 5, attackingCreatures); + } + + @Test + public void assaultWhenAheadIncludesTrade() { + Game game = initAndCreateGame(); + Player attacker = game.getPlayers().get(1); + Player defender = game.getPlayers().get(0); + + defender.setLife(10, null); + + String bears = "Grizzly Bears"; + + Card bear1 = addCard(bears, attacker); + Card bear2 = addCard(bears, attacker); + addCard(bears, defender); + + // Make sure the bears can attack + bear1.setSickness(false); + bear2.setSickness(false); + + game.getPhaseHandler().devModeSet(PhaseType.MAIN1, attacker); + game.getAction().checkStateEffects(true); + + // Get the simulated game state after AI has declared attackers + Combat combat = ((PlayerControllerAi)attacker.getController()).getAi().getPredictedCombat(); + + // Check how many creatures are attacking + int attackingCreatures = combat.getAttackers().size(); + AssertJUnit.assertEquals("AI should attack with all 2 bears", 2, attackingCreatures); + } + + @Test + public void assaultWhenAheadAgainstDeathtouch() { + Game game = initAndCreateGame(); + Player attacker = game.getPlayers().get(1); + Player defender = game.getPlayers().get(0); + + defender.setLife(10, null); + + String bears = "Grizzly Bears"; + String deathtouch = "Ankle Biter"; + + Card bear1 = addCard(bears, attacker); + Card bear2 = addCard(bears, attacker); + Card bear3 = addCard(bears, attacker); + addCard(deathtouch, defender); + + // Make sure the bears can attack + bear1.setSickness(false); + bear2.setSickness(false); + bear3.setSickness(false); + + game.getPhaseHandler().devModeSet(PhaseType.MAIN1, attacker); + game.getAction().checkStateEffects(true); + + // Get the simulated game state after AI has declared attackers + Combat combat = ((PlayerControllerAi)attacker.getController()).getAi().getPredictedCombat(); + + // Check how many creatures are attacking + int attackingCreatures = combat.getAttackers().size(); + AssertJUnit.assertEquals("AI should attack with all 3 bears", 3, attackingCreatures); + } + + @Test + public void noAttackAgainstDeathtouchTrade() { + Game game = initAndCreateGame(); + Player attacker = game.getPlayers().get(1); + Player defender = game.getPlayers().get(0); + + defender.setLife(10, null); + + String bears = "Grizzly Bears"; + String deathtouch = "Ankle Biter"; + + Card bear1 = addCard(bears, attacker); + addCard(deathtouch, defender); + + // Make sure the bears can attack + bear1.setSickness(false); + + game.getPhaseHandler().devModeSet(PhaseType.MAIN1, attacker); + game.getAction().checkStateEffects(true); + + // Get the simulated game state after AI has declared attackers + Combat combat = ((PlayerControllerAi)attacker.getController()).getAi().getPredictedCombat(); + + // Check how many creatures are attacking + int attackingCreatures = combat.getAttackers().size(); + AssertJUnit.assertEquals("AI should not attack", 0, attackingCreatures); + } +} diff --git a/forge-gui-desktop/src/test/java/forge/ai/blocking/BasicBlockTests.java b/forge-gui-desktop/src/test/java/forge/ai/blocking/BasicBlockTests.java new file mode 100644 index 00000000000..abe0ae74037 --- /dev/null +++ b/forge-gui-desktop/src/test/java/forge/ai/blocking/BasicBlockTests.java @@ -0,0 +1,49 @@ +package forge.ai.blocking; + +import forge.ai.ComputerUtilCard; +import forge.ai.PlayerControllerAi; +import forge.ai.simulation.SimulationTest; +import forge.game.Game; +import forge.game.card.Card; +import forge.game.combat.Combat; +import forge.game.phase.PhaseType; +import forge.game.player.Player; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +public class BasicBlockTests extends SimulationTest { + + @Test + public void noBlockingVsDeathtouch() { + Game game = initAndCreateGame(); + Player attacker = game.getPlayers().get(1); + Player defender = game.getPlayers().get(0); + + defender.setLife(10, null); + + String bears = "Grizzly Bears"; + String deathtouch = "Ankle Biter"; + + Card bear1 = addCard(bears, defender); + Card dtAttacker = addCard(deathtouch, attacker); + + int bearEvaluation = ComputerUtilCard.evaluateCreature(bear1); + int dtEvaluation = ComputerUtilCard.evaluateCreature(dtAttacker); + + // Make sure the bears can attack + bear1.setSickness(false); + + game.getPhaseHandler().devModeSet(PhaseType.MAIN1, attacker); + game.getAction().checkStateEffects(true); + + // Get the simulated game state after AI has declared attackers + Combat combat = ((PlayerControllerAi)attacker.getController()).getAi().getPredictedCombat(); + combat.addAttacker(dtAttacker, defender); + ((PlayerControllerAi)attacker.getController()).getAi().declareBlockersFor(defender, combat); + + // Check how many creatures are attacking + int blockers = combat.getBlockers(dtAttacker).size(); + AssertJUnit.assertEquals("AI should not block", 0, blockers); + } + +}