From dac8f2dfe8b0bd9fbaae57a156a60825c322f6ef Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 10 Mar 2018 19:59:59 +0100 Subject: [PATCH] Fixed a bug of AI not handling pass action correctly so the AI got passive. Added AI possibility to act after blockers are declared (eg boost for blocking or blocked creatures). --- .../src/mage/player/ai/ComputerPlayer6.java | 6 +-- .../src/mage/player/ai/ComputerPlayer7.java | 6 +++ .../mage/test/AI/basic/CastCreaturesTest.java | 41 ++++++++++++++++++- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index e313d6b763..287b31752c 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -522,7 +522,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ { continue; } if (!sim.checkIfGameIsOver() - && action.isUsesStack()) { + && (action.isUsesStack() || action instanceof PassAbility)) { // only pass if the last action uses the stack UUID nextPlayerId = sim.getPlayerList().get(); do { @@ -533,8 +533,8 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ { SimulationNode2 newNode = new SimulationNode2(node, sim, action, depth, currentPlayer.getId()); sim.checkStateAndTriggered(); int val; - if (action instanceof PassAbility) { - // Stop to simulate deeper if PassAbility + if (action instanceof PassAbility && sim.getStack().isEmpty()) { + // Stop to simulate deeper if PassAbility and stack is empty val = GameStateEvaluator2.evaluate(this.getId(), sim); } else { val = addActions(newNode, depth - 1, alpha, beta); diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java index 71c7da0196..baadef5366 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java @@ -109,6 +109,12 @@ public class ComputerPlayer7 extends ComputerPlayer6 { } return false; case DECLARE_BLOCKERS: + printOutState(game); + if (actions.isEmpty()) { + calculateActions(game); + } + act(game); + return true; case FIRST_COMBAT_DAMAGE: case COMBAT_DAMAGE: case END_COMBAT: diff --git a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java index fd1195e28b..7a622b726b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java @@ -29,7 +29,6 @@ package org.mage.test.AI.basic; import mage.constants.PhaseStep; import mage.constants.Zone; -import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBaseAI; @@ -58,7 +57,6 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI { * first creature */ @Test - @Ignore // TODO: find out why sometimes Produces error probably because of wrong mana usage of the AI - Not solved yet public void testSimpleCast2() { addCard(Zone.HAND, playerA, "Silvercoat Lion"); @@ -194,4 +192,43 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI { assertPermanentCount(playerA, "Bog Wraith", 1); } + + /** + * Tests that the creature is cast if enough mana is available. + * + * Once Ammit Eternal is cast against a computer AI opponent, the AI just + * decides to sit there and only play basic lands. I've sat there and decked + * it because it just plays lands. It's like it views giving the Ammit + * Eternal -1/-1 counters as a good thing for me, so it never casts any + * spells once Ammit Eternal hits the battlefield. + */ + @Test + public void testSimpleCastWithAmmitEternal() { + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.HAND, playerA, "Plains", 2); + addCard(Zone.LIBRARY, playerA, "Plains", 2); + skipInitShuffling(); + + // Afflict 3 (Whenever this creature becomes blocked, defending player loses 3 life.) + // Whenever an opponent casts a spell, put a -1/-1 counter on Ammit Eternal. + // Whenever Ammit Eternal deals combat damage to a player, remove all -1/-1 counters from it. + addCard(Zone.HAND, playerB, "Ammit Eternal"); // Creature {2}{B} 5/5 + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Ammit Eternal"); + setStopAt(3, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerB, "Ammit Eternal", 1); + + assertPermanentCount(playerA, "Plains", 2); + assertHandCount(playerA, "Plains", 1); + assertHandCount(playerA, "Silvercoat Lion", 0); + assertPermanentCount(playerA, 3); + + assertPermanentCount(playerA, "Silvercoat Lion", 1); + + assertPowerToughness(playerB, "Ammit Eternal", 4, 4); + } + }