mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Simulated AI: Fix multi-target spell simulation. (#2181)
* Simulated AI: Fix multi-target spell simulation. Removes an incorrect check that was comparing two semantically different things (number of possible to choose from vs. number of targets chosen). Adds a test using Incremental Growth, where number of possible targets is 5, but the spell requires only 3 to be chosen. * Fix the root issue and eliminate incorrect simulations. * Fix infinite loop with invalid targets. * Fix logic.
This commit is contained in:
@@ -137,4 +137,10 @@ public class SimulationTest {
|
||||
protected Card addCard(String name, Player p) {
|
||||
return addCardToZone(name, p, ZoneType.Battlefield);
|
||||
}
|
||||
|
||||
protected void addCards(String name, int count, Player p) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
addCardToZone(name, p, ZoneType.Battlefield);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,11 +95,8 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
addCard("Island", p);
|
||||
addCard("Island", p);
|
||||
addCard("Forest", p);
|
||||
addCard("Forest", p);
|
||||
addCard("Forest", p);
|
||||
addCards("Island", 2, p);
|
||||
addCards("Forest", 3, p);
|
||||
|
||||
Card tatyova = addCardToZone("Tatyova, Benthic Druid", p, ZoneType.Hand);
|
||||
addCardToZone("Forest", p, ZoneType.Hand);
|
||||
@@ -169,10 +166,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCards("Mountain", 4, p);
|
||||
Card spell = addCardToZone("Fiery Confluence", p, ZoneType.Hand);
|
||||
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
@@ -198,10 +192,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCards("Mountain", 4, p);
|
||||
Card spell = addCardToZone("Fiery Confluence", p, ZoneType.Hand);
|
||||
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
@@ -226,8 +217,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCards("Mountain", 2, p);
|
||||
Card spell = addCardToZone("Arc Trail", p, ZoneType.Hand);
|
||||
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
@@ -289,8 +279,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCards("Mountain", 2, p);
|
||||
Card abbot = addCardToZone("Abbot of Keral Keep", p, ZoneType.Hand);
|
||||
addCardToZone("Lightning Bolt", p, ZoneType.Hand);
|
||||
// Note: This assumes the top of library is revealed. If the AI is made
|
||||
@@ -321,9 +310,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCards("Mountain", 3, p);
|
||||
Card abbot = addCardToZone("Abbot of Keral Keep", p, ZoneType.Hand);
|
||||
// Note: This assumes the top of library is revealed. If the AI is made
|
||||
// smarter to not assume that, then this test can be updated to have
|
||||
@@ -426,8 +413,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Card blocker = addCard("Fugitive Wizard", opponent);
|
||||
Card attacker1 = addCard("Dwarven Trader", p);
|
||||
attacker1.setSickness(false);
|
||||
addCard("Swamp", p);
|
||||
addCard("Swamp", p);
|
||||
addCards("Swamp", 2, p);
|
||||
addCardToZone("Doom Blade", p, ZoneType.Hand);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN1, p);
|
||||
@@ -455,9 +441,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
|
||||
addCardToZone("Chaos Warp", p, ZoneType.Hand);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCard("Mountain", p);
|
||||
addCards("Mountain", 3, p);
|
||||
|
||||
addCard("Plains", opponent);
|
||||
addCard("Mountain", opponent);
|
||||
@@ -489,8 +473,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
addCard("Island", p);
|
||||
addCard("Island", p);
|
||||
addCards("Forest", 2, p);
|
||||
addCardToZone("Counterspell", p, ZoneType.Hand);
|
||||
addCardToZone("Unsummon", p, ZoneType.Hand);
|
||||
|
||||
@@ -605,4 +588,74 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
|
||||
// Still, this test case exercises the code path and ensures we don't crash in this case.
|
||||
AssertJUnit.assertEquals(1, picker.getNumSimulations());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void threeDistinctTargetSpell() {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
|
||||
addCardToZone("Incremental Growth", p, ZoneType.Hand);
|
||||
addCards("Forest", 5, p);
|
||||
addCard("Forest Bear", p);
|
||||
addCard("Flying Men", opponent);
|
||||
addCard("Runeclaw Bear", p);
|
||||
addCard("Water Elemental", opponent);
|
||||
addCard("Grizzly Bears", p);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
SpellAbilityPicker picker = new SpellAbilityPicker(game, p);
|
||||
SpellAbility sa = picker.chooseSpellAbilityToPlay(null);
|
||||
AssertJUnit.assertNotNull(sa);
|
||||
MultiTargetSelector.Targets targets = picker.getPlan().getSelectedDecision().targets;
|
||||
AssertJUnit.assertEquals(3, targets.size());
|
||||
AssertJUnit.assertTrue(targets.toString().contains("Forest Bear"));
|
||||
AssertJUnit.assertTrue(targets.toString().contains("Runeclaw Bear"));
|
||||
AssertJUnit.assertTrue(targets.toString().contains("Grizzly Bear"));
|
||||
// Expected 5*4*3=60 iterations (5 choices for first target, 4 for next, 3 for last.)
|
||||
AssertJUnit.assertEquals(60, picker.getNumSimulations());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void threeDistinctTargetSpellCantBeCast() {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
|
||||
addCardToZone("Incremental Growth", p, ZoneType.Hand);
|
||||
addCards("Forest", 5, p);
|
||||
addCard("Forest Bear", p);
|
||||
addCard("Flying Men", opponent);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
SpellAbilityPicker picker = new SpellAbilityPicker(game, p);
|
||||
SpellAbility sa = picker.chooseSpellAbilityToPlay(null);
|
||||
AssertJUnit.assertNull(sa);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctTargetChoicesWithTwoTargetSpell() {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
Player opponent = game.getPlayers().get(0);
|
||||
|
||||
addCardToZone("Rites of Reaping", p, ZoneType.Hand);
|
||||
addCard("Swamp", p);
|
||||
addCards("Forest", 5, p);
|
||||
addCard("Flying Men", opponent);
|
||||
addCard("Forest Bear", p);
|
||||
addCard("Water Elemental", opponent);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
SpellAbilityPicker picker = new SpellAbilityPicker(game, p);
|
||||
SpellAbility sa = picker.chooseSpellAbilityToPlay(null);
|
||||
AssertJUnit.assertNotNull(sa);
|
||||
MultiTargetSelector.Targets targets = picker.getPlan().getSelectedDecision().targets;
|
||||
AssertJUnit.assertEquals(2, targets.size());
|
||||
AssertJUnit.assertTrue(targets.toString().contains("Forest Bear"));
|
||||
AssertJUnit.assertTrue(targets.toString().contains("Flying Men"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user