AI: fixed that computer can't play commanders (#7955);

This commit is contained in:
Oleg Agafonov 2021-07-01 18:21:15 +04:00
parent d0ee17d661
commit 62d6675be6
4 changed files with 40 additions and 8 deletions

View file

@ -215,7 +215,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
logger.trace("Add Action [" + depth + "] " + node.getAbilities().toString() + " a: " + alpha + " b: " + beta); logger.trace("Add Action [" + depth + "] " + node.getAbilities().toString() + " a: " + alpha + " b: " + beta);
} }
Game game = node.getGame(); Game game = node.getGame();
if (ALLOW_INTERRUPT if (COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS
&& Thread.interrupted()) { && Thread.interrupted()) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
logger.debug("interrupted"); logger.debug("interrupted");
@ -435,7 +435,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
pool.execute(task); pool.execute(task);
try { try {
int maxSeconds = maxThink; int maxSeconds = maxThink;
if (!ALLOW_INTERRUPT) { if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS) {
maxSeconds = 3600; maxSeconds = 3600;
} }
logger.debug("maxThink: " + maxSeconds + " seconds "); logger.debug("maxThink: " + maxSeconds + " seconds ");
@ -460,7 +460,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
} }
protected int simulatePriority(SimulationNode2 node, Game game, int depth, int alpha, int beta) { protected int simulatePriority(SimulationNode2 node, Game game, int depth, int alpha, int beta) {
if (ALLOW_INTERRUPT if (COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS
&& Thread.interrupted()) { && Thread.interrupted()) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
logger.info("interrupted"); logger.info("interrupted");
@ -480,7 +480,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
int bestValSubNodes = Integer.MIN_VALUE; int bestValSubNodes = Integer.MIN_VALUE;
for (Ability action : allActions) { for (Ability action : allActions) {
counter++; counter++;
if (ALLOW_INTERRUPT if (COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS
&& Thread.interrupted()) { && Thread.interrupted()) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
logger.info("Sim Prio [" + depth + "] -- interrupted"); logger.info("Sim Prio [" + depth + "] -- interrupted");

View file

@ -70,7 +70,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
private long lastThinkTime = 0; // msecs for last AI actions calc private long lastThinkTime = 0; // msecs for last AI actions calc
protected int PASSIVITY_PENALTY = 5; // Penalty value for doing nothing if some actions are available protected int PASSIVITY_PENALTY = 5; // Penalty value for doing nothing if some actions are available
protected boolean ALLOW_INTERRUPT = true; // change this for test to false / debugging purposes to false to switch off interrupts while debugging
// debug only: set TRUE to debug simulation's code/games (on false sim thread will be stopped after few secs by timeout)
protected boolean COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS = false;
private transient Map<Mana, Card> unplayable = new TreeMap<>(); private transient Map<Mana, Card> unplayable = new TreeMap<>();
private transient List<Card> playableNonInstant = new ArrayList<>(); private transient List<Card> playableNonInstant = new ArrayList<>();

View file

@ -6,14 +6,15 @@ import mage.cards.AdventureCard;
import mage.constants.CommanderCardType; import mage.constants.CommanderCardType;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.GameState;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestCommander4Players; import org.mage.test.serverside.base.CardTestCommander4PlayersWithAIHelps;
/** /**
* @author JayDi85 * @author JayDi85
*/ */
public class CommandersCastTest extends CardTestCommander4Players { public class CommandersCastTest extends CardTestCommander4PlayersWithAIHelps {
@Test @Test
public void test_CastToBattlefieldOneTime() { public void test_CastToBattlefieldOneTime() {
@ -611,4 +612,32 @@ public class CommandersCastTest extends CardTestCommander4Players {
assertPermanentCount(playerA, "Swamp", 1); assertPermanentCount(playerA, "Swamp", 1);
assertGraveyardCount(playerA, "Uro, Titan of Nature's Wrath", 1); // sacrificed assertGraveyardCount(playerA, "Uro, Titan of Nature's Wrath", 1); // sacrificed
} }
@Test
public void test_AI_MustPlayCommander() {
// Player order: A -> D -> C -> B
addCard(Zone.COMMAND, playerA, "Balduvian Bears", 1); // {1}{G}, 2/2, commander
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
// possible bug: wrong copy of commander objects
runCode("test", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
GameState copied = game.getState().copy();
Assert.assertEquals("original commander must have 1 ability", 1, game.getState().getCommand().get(0).getAbilities().size());
Assert.assertEquals("copied commander must have 1 ability", 1, copied.getCommand().get(0).getAbilities().size());
});
// ai must play commander
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}", 2);
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertCommandZoneCount(playerA, "Balduvian Bears", 0);
assertPermanentCount(playerA, "Balduvian Bears", 1);
assertTappedCount("Forest", true, 2);
}
} }

View file

@ -104,9 +104,10 @@ public class Commander implements CommandObject {
} }
private Commander(final Commander commander) { private Commander(final Commander commander) {
this.sourceObject = commander.sourceObject; this.sourceObject = commander.sourceObject.copy();
this.copy = commander.copy; this.copy = commander.copy;
this.copyFrom = (commander.copyFrom != null ? commander.copyFrom.copy() : null); this.copyFrom = (commander.copyFrom != null ? commander.copyFrom.copy() : null);
this.abilities.addAll(commander.abilities.copy());
} }
@Override @Override