Fixed AI freeze with non available targets

This commit is contained in:
Oleg Agafonov 2019-12-21 18:10:29 +04:00
parent 394d9716ca
commit bd71c98e3e
6 changed files with 174 additions and 28 deletions

View file

@ -0,0 +1,101 @@
package org.mage.test.AI.basic;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class TargetRequiredTest extends CardTestPlayerBase {
/*
Redcap must sacrifice target land -- it's required target, but AI don't known about that
(target can be copied as new target in effect's code)
*/
@Test
public void test_chooseBadTargetOnSacrifice_WithTargets_User() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
addTarget(playerA, "Mountain");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerA, "Mountain", 1);
assertPermanentCount(playerA, "Mountain", 3 - 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
@Test
public void test_chooseBadTargetOnSacrifice_WithTargets_AI() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
//addTarget(playerA, "Mountain"); AI must select targets
//setStrictChooseMode(true); AI must select targets
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerA, "Mountain", 1);
assertPermanentCount(playerA, "Mountain", 3 - 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
@Test
public void test_chooseBadTargetOnSacrifice_WithoutTargets_User() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Atarka Monument", 1); // {T}: Add {R} or {G}.
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
//addTarget(playerA, "Mountain"); no lands to sacrifice
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
@Test
public void test_chooseBadTargetOnSacrifice_WithoutTargets_AI() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Atarka Monument", 1); // {T}: Add {R} or {G}.
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
//addTarget(playerA, "Mountain"); no lands to sacrifice
//setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
}

View file

@ -22,7 +22,10 @@ import org.mage.test.utils.DeckTestUtils;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* Intended to test Mage server under different load patterns.
@ -188,7 +191,7 @@ public class LoadTest {
}
}
public void playTwoAIGame(String deckColors, String deckAllowedSets) {
public void playTwoAIGame(String gameName, String deckColors, String deckAllowedSets) {
Assert.assertFalse("need deck colors", deckColors.isEmpty());
Assert.assertFalse("need allowed sets", deckAllowedSets.isEmpty());
@ -197,7 +200,7 @@ public class LoadTest {
// game by monitor
GameTypeView gameType = monitor.session.getGameTypes().get(0);
MatchOptions gameOptions = createSimpleGameOptionsForAI(gameType, monitor.session);
MatchOptions gameOptions = createSimpleGameOptionsForAI(gameType, monitor.session, gameName);
TableView game = monitor.session.createTable(monitor.roomID, gameOptions);
UUID tableId = game.getTableId();
@ -218,7 +221,11 @@ public class LoadTest {
checkGame = monitor.getTable(tableId);
TableState state = checkGame.get().getTableState();
logger.warn((gameView != null ? "Turn " + gameView.getTurn() + ", " + gameView.getStep().toString() + " - " : "") + state);
logger.warn(checkGame.get().getTableName()
+ (gameView != null ? ", turn " + gameView.getTurn() + ", " + gameView.getStep().toString() : "")
+ (gameView != null ? ", active " + gameView.getActivePlayerName() : "")
+ ", " + state);
if (state == TableState.FINISHED) {
break;
@ -246,25 +253,34 @@ public class LoadTest {
@Test
@Ignore
public void test_TwoAIPlayGame_One() {
playTwoAIGame("GR", "GRN");
playTwoAIGame("Single AI game", "GR", "GRN");
}
@Test
@Ignore
public void test_TwoAIPlayGame_Multiple() {
// save random seeds for repeated results
int gamesAmount = 1000;
int singleGameSID = -1554824422; // for one game test with same deck
int singleGamePlaysAmount = 1000; // multiple run of one game test
// save random seeds for repeated results (in decks generating)
List<Integer> seedsList = new ArrayList<>();
for (int i = 1; i <= gamesAmount; i++) {
seedsList.add(RandomUtil.nextInt());
if (singleGameSID != 0) {
for (int i = 1; i <= singleGamePlaysAmount; i++) {
seedsList.add(singleGameSID);
}
} else {
int gamesAmount = 1000;
for (int i = 1; i <= gamesAmount; i++) {
seedsList.add(RandomUtil.nextInt());
}
}
for (int i = 1; i <= gamesAmount; i++) {
for (int i = 0; i <= seedsList.size() - 1; i++) {
long randomSeed = seedsList.get(i);
logger.info("Game " + i + " of " + gamesAmount + ", RANDOM seed: " + randomSeed);
logger.info("Game " + (i + 1) + " of " + seedsList.size() + ", RANDOM seed: " + randomSeed);
RandomUtil.setSeed(randomSeed);
playTwoAIGame("WGUBR", "ELD");
playTwoAIGame("AI game #" + (i + 1), "WGUBR", "ELD");
}
}
@ -454,8 +470,8 @@ public class LoadTest {
return createSimpleGameOptions("Bots test game", gameTypeView, session, PlayerType.HUMAN);
}
private MatchOptions createSimpleGameOptionsForAI(GameTypeView gameTypeView, Session session) {
return createSimpleGameOptions("AI test game", gameTypeView, session, PlayerType.COMPUTER_MAD);
private MatchOptions createSimpleGameOptionsForAI(GameTypeView gameTypeView, Session session, String gameName) {
return createSimpleGameOptions(gameName, gameTypeView, session, PlayerType.COMPUTER_MAD);
}
private class LoadPlayer {