mirror of
https://github.com/magefree/mage.git
synced 2025-12-27 22:12:03 -08:00
AI: improved performance on too many possible targets (fix game freezes and server crashes - see #9539, #9438, #9518, related to #11285, #5023);
This commit is contained in:
parent
384ce67cc3
commit
2833460e59
10 changed files with 397 additions and 234 deletions
|
|
@ -6,7 +6,6 @@ import mage.constants.PhaseStep;
|
|||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBaseAI;
|
||||
|
||||
|
|
@ -21,7 +20,6 @@ import java.util.List;
|
|||
* TODO: add tests and implement best choice selection on timeout
|
||||
* (AI must make any good/bad choice on timeout with game log - not a skip)
|
||||
* <p>
|
||||
* TODO: AI do not support game simulations for target options in triggered
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
|
@ -106,28 +104,24 @@ public class SimulationPerformanceAITest extends CardTestPlayerBaseAI {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore // enable after triggered supported or need performance test
|
||||
public void test_ManyTargetOptions_Triggered_Single() {
|
||||
// 2 damage to bear and 3 damage to player B
|
||||
runManyTargetOptionsInTrigger("1 target creature", 1, 1, false, 20 - 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // enable after triggered supported or need performance test
|
||||
public void test_ManyTargetOptions_Triggered_Few() {
|
||||
// 4 damage to x2 bears and 1 damage to player B
|
||||
runManyTargetOptionsInTrigger("2 target creatures", 2, 2, false, 20 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // enable after triggered supported or need performance test
|
||||
public void test_ManyTargetOptions_Triggered_Many() {
|
||||
// 4 damage to x2 bears and 1 damage to player B
|
||||
runManyTargetOptionsInTrigger("5 target creatures", 5, 2, false, 20 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // enable after triggered supported or need performance test
|
||||
public void test_ManyTargetOptions_Triggered_TooMuch() {
|
||||
// warning, can be slow
|
||||
|
||||
|
|
@ -139,7 +133,6 @@ public class SimulationPerformanceAITest extends CardTestPlayerBaseAI {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore // enable after triggered supported or need performance test
|
||||
public void test_ManyTargetOptions_Triggered_TargetGroups() {
|
||||
// make sure targets optimization can find unique creatures, e.g. damaged
|
||||
|
||||
|
|
@ -213,4 +206,29 @@ public class SimulationPerformanceAITest extends CardTestPlayerBaseAI {
|
|||
// 4 damage to x2 bears and 1 damage to damaged bear
|
||||
runManyTargetOptionsInActivate("5 target creatures with one damaged", 5, 3, true, 20);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ElderDeepFiend_TooManyUpToChoices() {
|
||||
// bug: game freeze with 100% CPU usage
|
||||
// https://github.com/magefree/mage/issues/9518
|
||||
int cardsCount = 2; // 2+ cards will generate too much target options for simulations
|
||||
|
||||
// Boulderfall deals 5 damage divided as you choose among any number of targets.
|
||||
// Flash
|
||||
// Emerge {5}{U}{U} (You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's mana value.)
|
||||
// When you cast this spell, tap up to four target permanents.
|
||||
addCard(Zone.HAND, playerA, "Elder Deep-Fiend", cardsCount); // {8}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 8 * cardsCount);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Kitesail Corsair", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Alpha Tyrranax", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Abbey Griffin", 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Elder Deep-Fiend", cardsCount); // ai must cast it
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
package org.mage.test.AI.basic;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
|
||||
|
||||
/**
|
||||
* Make sure AI can simulate priority with triggers resolve
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class SimulationTriggersAITest extends CardTestPlayerBaseWithAIHelps {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// TODO: trigger's target options supported on priority sim, but do not used for some reason
|
||||
// see addTargetOptions, node.children, ComputerPlayer6->targets, etc
|
||||
public void test_DeepglowSkate_MustBeSimulated() {
|
||||
// make sure targets choosing on trigger use same game sims and best results
|
||||
|
||||
// When Deepglow Skate enters the battlefield, double the number of each kind of counter on any number
|
||||
// of target permanents.
|
||||
addCard(Zone.HAND, playerA, "Deepglow Skate", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Adversary of Tyrants", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Caller of the Pride", 1); // x4 loyalty
|
||||
//
|
||||
// This creature enters with a -1/-1 counter on it.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bloodied Ghost", 1); // 3/3
|
||||
//
|
||||
// Players can't activate planeswalkers' loyalty abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "The Immortal Sun", 1); // disable planeswalkers usage by AI
|
||||
|
||||
// AI must cast boost and ignore doubling of -1/-1 counters on own creatures due bad score
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Deepglow Skate", 1);
|
||||
assertCounterCount(playerA, "Ajani, Adversary of Tyrants", CounterType.LOYALTY, 4 * 2);
|
||||
assertCounterCount(playerA, "Ajani, Caller of the Pride", CounterType.LOYALTY, 4 * 2);
|
||||
assertCounterCount(playerA, "Bloodied Ghost", CounterType.M1M1, 1); // make sure AI will not double bad counters
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_DeepglowSkate_PerformanceOnTooManyChoices() {
|
||||
// bug: game freeze with 100% CPU usage
|
||||
// https://github.com/magefree/mage/issues/9438
|
||||
int cardsCount = 2; // 2+ cards will generate too much target options for simulations
|
||||
int boostMultiplier = (int) Math.pow(2, cardsCount);
|
||||
|
||||
// When Deepglow Skate enters the battlefield, double the number of each kind of counter on any number
|
||||
// of target permanents.
|
||||
addCard(Zone.HAND, playerA, "Deepglow Skate", cardsCount); // {4}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5 * cardsCount);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Adversary of Tyrants", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Caller of the Pride", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ajani Goldmane", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ajani, Inspiring Leader", 1); // x5 loyalty
|
||||
//
|
||||
// Players can't activate planeswalkers' loyalty abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "The Immortal Sun", 1); // disable planeswalkers usage by AI
|
||||
|
||||
// AI must cast multiple booster spells and double only own counters and only good
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Deepglow Skate", cardsCount);
|
||||
assertCounterCount(playerA, "Ajani, Adversary of Tyrants", CounterType.LOYALTY, 4 * boostMultiplier);
|
||||
assertCounterCount(playerA, "Ajani, Caller of the Pride", CounterType.LOYALTY, 4 * boostMultiplier);
|
||||
assertCounterCount(playerB, "Ajani Goldmane", CounterType.LOYALTY, 4);
|
||||
assertCounterCount(playerB, "Ajani, Inspiring Leader", CounterType.LOYALTY, 5);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue