mirror of
https://github.com/correl/mage.git
synced 2024-11-25 11:09:53 +00:00
AI: fixed that computer can't play commanders (#7955);
This commit is contained in:
parent
d0ee17d661
commit
62d6675be6
4 changed files with 40 additions and 8 deletions
|
@ -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");
|
||||||
|
|
|
@ -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<>();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue