mirror of
https://github.com/magefree/mage.git
synced 2025-12-23 03:51:58 -08:00
Test framework improves:
* Added AI commands support to play attacker and blocker steps; * Fixed double triggers of blocker declared event (if block command used with block requirement effect);
This commit is contained in:
parent
44adbae263
commit
a7ac35a82d
5 changed files with 221 additions and 34 deletions
|
|
@ -52,6 +52,40 @@ public class TestFrameworkCanPlayAITest extends CardTestPlayerBaseWithAIHelps {
|
||||||
assertPermanentCount(playerB, "Balduvian Bears", 5 - 3);
|
assertPermanentCount(playerB, "Balduvian Bears", 5 - 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_AI_Attack() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
|
||||||
|
|
||||||
|
// AI must attack
|
||||||
|
aiPlayStep(1, PhaseStep.DECLARE_ATTACKERS, playerA);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertLife(playerB, 20 - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_AI_Block() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
|
||||||
|
|
||||||
|
// AI must block
|
||||||
|
attack(1, playerA, "Balduvian Bears");
|
||||||
|
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, 1);
|
||||||
|
assertGraveyardCount(playerB, 1);
|
||||||
|
assertLife(playerB, 20);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore // AI can't play blade cause score system give priority for boost instead restriction effects like goad
|
@Ignore // AI can't play blade cause score system give priority for boost instead restriction effects like goad
|
||||||
public void test_AI_GoadedByBloodthirstyBlade_Normal() {
|
public void test_AI_GoadedByBloodthirstyBlade_Normal() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
package org.mage.test.cards.requirement;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
public class BecomeBlockTriggersAITest extends CardTestPlayerBaseWithAIHelps {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_Manual_AutoBlock() {
|
||||||
|
removeAllCardsFromHand(playerA);
|
||||||
|
removeAllCardsFromHand(playerB);
|
||||||
|
|
||||||
|
// All creatures able to block Nessian Boar do so.
|
||||||
|
// Whenever Nessian Boar becomes blocked by a creature, that creature’s controller draws a card.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Nessian Boar", 1);
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
|
||||||
|
|
||||||
|
// auto-block by requirement effect
|
||||||
|
attack(1, playerA, "Nessian Boar");
|
||||||
|
//block(1, playerB, "Balduvian Bears", "Nessian Boar");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, 0);
|
||||||
|
assertGraveyardCount(playerB, 1);
|
||||||
|
assertHandCount(playerA, 0);
|
||||||
|
assertHandCount(playerB, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_Manual_CantBlockAgain() {
|
||||||
|
removeAllCardsFromHand(playerA);
|
||||||
|
removeAllCardsFromHand(playerB);
|
||||||
|
|
||||||
|
// All creatures able to block Nessian Boar do so.
|
||||||
|
// Whenever Nessian Boar becomes blocked by a creature, that creature’s controller draws a card.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Nessian Boar", 1);
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
|
||||||
|
|
||||||
|
// auto-block by requirement effect
|
||||||
|
attack(1, playerA, "Nessian Boar");
|
||||||
|
// try to block manually, but it must raise error
|
||||||
|
block(1, playerB, "Balduvian Bears", "Nessian Boar");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
try {
|
||||||
|
execute();
|
||||||
|
Assert.fail("Expected exception, but not raise");
|
||||||
|
} catch (UnsupportedOperationException ue) {
|
||||||
|
Assert.assertEquals("Balduvian Bears cannot block Nessian Boar it is already blocking the maximum amount of creatures.", ue.getMessage());
|
||||||
|
}
|
||||||
|
//assertAllCommandsUsed(); // must have 1 missing command (block)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_AI_CantBlockAgain() {
|
||||||
|
removeAllCardsFromHand(playerA);
|
||||||
|
removeAllCardsFromHand(playerB);
|
||||||
|
|
||||||
|
// All creatures able to block Nessian Boar do so.
|
||||||
|
// Whenever Nessian Boar becomes blocked by a creature, that creature’s controller draws a card.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Nessian Boar", 1);
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
|
||||||
|
|
||||||
|
// auto-block by requirement effect
|
||||||
|
attack(1, playerA, "Nessian Boar");
|
||||||
|
// AI can't block same creature twice
|
||||||
|
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, 0);
|
||||||
|
assertGraveyardCount(playerB, 1);
|
||||||
|
assertHandCount(playerA, 0);
|
||||||
|
assertHandCount(playerB, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package org.mage.test.cards.requirement;
|
package org.mage.test.cards.requirement;
|
||||||
|
|
||||||
import mage.constants.PhaseStep;
|
import mage.constants.PhaseStep;
|
||||||
|
|
@ -10,7 +9,6 @@ import static junit.framework.TestCase.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2, icetc
|
* @author LevelX2, icetc
|
||||||
*/
|
*/
|
||||||
public class BlockRequirementTest extends CardTestPlayerBase {
|
public class BlockRequirementTest extends CardTestPlayerBase {
|
||||||
|
|
@ -91,7 +89,7 @@ public class BlockRequirementTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Elemental Uprising - "it must be blocked this turn if able", not working
|
* Elemental Uprising - "it must be blocked this turn if able", not working
|
||||||
*
|
* <p>
|
||||||
* The bug just happened for me today as well - the problem is "must be
|
* The bug just happened for me today as well - the problem is "must be
|
||||||
* blocked" is not being enforced correctly. During opponent's main phase
|
* blocked" is not being enforced correctly. During opponent's main phase
|
||||||
* they cast Elemental Uprising targeting an untapped land. They attacked
|
* they cast Elemental Uprising targeting an untapped land. They attacked
|
||||||
|
|
@ -186,7 +184,7 @@ public class BlockRequirementTest extends CardTestPlayerBase {
|
||||||
attack(1, playerA, "Breaker of Armies");
|
attack(1, playerA, "Breaker of Armies");
|
||||||
|
|
||||||
// not allowed due to Breaker of Armies having menace
|
// not allowed due to Breaker of Armies having menace
|
||||||
block(1, playerB, "Hill Giant", "Breaker of Armies");
|
//block(1, playerB, "Hill Giant", "Breaker of Armies"); // auto-block from requrement effect must add blocker without command
|
||||||
|
|
||||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,12 @@ public class TestPlayer implements Player {
|
||||||
computerPlayer.setTestPlayerLink(this);
|
computerPlayer.setTestPlayerLink(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TestPlayer(TestComputerPlayerMonteCarlo computerPlayer) {
|
||||||
|
this.computerPlayer = computerPlayer;
|
||||||
|
AIPlayer = false;
|
||||||
|
computerPlayer.setTestPlayerLink(this);
|
||||||
|
}
|
||||||
|
|
||||||
public TestPlayer(final TestPlayer testPlayer) {
|
public TestPlayer(final TestPlayer testPlayer) {
|
||||||
this.AIPlayer = testPlayer.AIPlayer;
|
this.AIPlayer = testPlayer.AIPlayer;
|
||||||
this.AICanChooseInStrictMode = testPlayer.AICanChooseInStrictMode;
|
this.AICanChooseInStrictMode = testPlayer.AICanChooseInStrictMode;
|
||||||
|
|
@ -1411,6 +1417,16 @@ public class TestPlayer implements Player {
|
||||||
boolean madeAttackByAction = false;
|
boolean madeAttackByAction = false;
|
||||||
for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext(); ) {
|
for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext(); ) {
|
||||||
PlayerAction action = it.next();
|
PlayerAction action = it.next();
|
||||||
|
|
||||||
|
// aiXXX commands
|
||||||
|
if (action.getTurnNum() == game.getTurnNum() && action.getAction().equals(AI_PREFIX + AI_COMMAND_PLAY_STEP)) {
|
||||||
|
mustAttackByAction = true;
|
||||||
|
madeAttackByAction = true;
|
||||||
|
this.computerPlayer.selectAttackers(game, attackingPlayerId);
|
||||||
|
it.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) {
|
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) {
|
||||||
mustAttackByAction = true;
|
mustAttackByAction = true;
|
||||||
String command = action.getAction();
|
String command = action.getAction();
|
||||||
|
|
@ -1473,7 +1489,7 @@ public class TestPlayer implements Player {
|
||||||
this.chooseStrictModeFailed("attacker", game, "select attackers must use attack command but don't");
|
this.chooseStrictModeFailed("attacker", game, "select attackers must use attack command but don't");
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI play if no actions available
|
// AI FULL play if no actions available
|
||||||
if (!mustAttackByAction && this.AIPlayer) {
|
if (!mustAttackByAction && this.AIPlayer) {
|
||||||
this.computerPlayer.selectAttackers(game, attackingPlayerId);
|
this.computerPlayer.selectAttackers(game, attackingPlayerId);
|
||||||
}
|
}
|
||||||
|
|
@ -1486,14 +1502,22 @@ public class TestPlayer implements Player {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectBlockers(Game game, UUID defendingPlayerId) {
|
public void selectBlockers(Game game, UUID defendingPlayerId) {
|
||||||
|
|
||||||
List<PlayerAction> tempActions = new ArrayList<>(actions);
|
List<PlayerAction> tempActions = new ArrayList<>(actions);
|
||||||
|
|
||||||
UUID opponentId = game.getOpponents(computerPlayer.getId()).iterator().next();
|
UUID opponentId = game.getOpponents(computerPlayer.getId()).iterator().next();
|
||||||
// Map of Blocker reference -> list of creatures blocked
|
Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesList = getBlockedCreaturesByCreatureList(game);
|
||||||
Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesByCreature = new HashMap<>();
|
|
||||||
boolean mustBlockByAction = false;
|
boolean mustBlockByAction = false;
|
||||||
for (PlayerAction action : tempActions) {
|
for (PlayerAction action : tempActions) {
|
||||||
|
|
||||||
|
// aiXXX commands
|
||||||
|
if (action.getTurnNum() == game.getTurnNum() && action.getAction().equals(AI_PREFIX + AI_COMMAND_PLAY_STEP)) {
|
||||||
|
mustBlockByAction = true;
|
||||||
|
this.computerPlayer.selectBlockers(game, defendingPlayerId);
|
||||||
|
actions.remove(action);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("block:")) {
|
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("block:")) {
|
||||||
mustBlockByAction = true;
|
mustBlockByAction = true;
|
||||||
String command = action.getAction();
|
String command = action.getAction();
|
||||||
|
|
@ -1510,7 +1534,8 @@ public class TestPlayer implements Player {
|
||||||
String attackerName = groups[1];
|
String attackerName = groups[1];
|
||||||
Permanent attacker = findPermanent(new FilterAttackingCreature(), attackerName, opponentId, game);
|
Permanent attacker = findPermanent(new FilterAttackingCreature(), attackerName, opponentId, game);
|
||||||
Permanent blocker = findPermanent(new FilterControlledPermanent(), blockerName, computerPlayer.getId(), game);
|
Permanent blocker = findPermanent(new FilterControlledPermanent(), blockerName, computerPlayer.getId(), game);
|
||||||
if (canBlockAnother(game, blocker, attacker, blockedCreaturesByCreature)) {
|
|
||||||
|
if (canBlockAnother(game, blocker, attacker, blockedCreaturesList)) {
|
||||||
computerPlayer.declareBlocker(defendingPlayerId, blocker.getId(), attacker.getId(), game);
|
computerPlayer.declareBlocker(defendingPlayerId, blocker.getId(), attacker.getId(), game);
|
||||||
actions.remove(action);
|
actions.remove(action);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1518,40 +1543,74 @@ public class TestPlayer implements Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkMultipleBlockers(game, blockedCreaturesByCreature);
|
checkMultipleBlockers(game, blockedCreaturesList);
|
||||||
|
|
||||||
// AI play if no actions available
|
// AI FULL play if no actions available
|
||||||
if (!mustBlockByAction && this.AIPlayer) {
|
if (!mustBlockByAction && this.AIPlayer) {
|
||||||
this.computerPlayer.selectBlockers(game, defendingPlayerId);
|
this.computerPlayer.selectBlockers(game, defendingPlayerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if a creature can block at least one more creature
|
private Map<MageObjectReference, List<MageObjectReference>> getBlockedCreaturesByCreatureList(Game game) {
|
||||||
private boolean canBlockAnother(Game game, Permanent blocker, Permanent attacker, Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesByCreature) {
|
// collect already declared blockers info (e.g. after auto-adding on block requirements)
|
||||||
|
// blocker -> blocked attackers
|
||||||
|
Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesByCreature = new HashMap<>();
|
||||||
|
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
|
||||||
|
for (UUID combatBlockerId : combatGroup.getBlockers()) {
|
||||||
|
Permanent blocker = game.getPermanent(combatBlockerId);
|
||||||
|
if (blocker != null) {
|
||||||
|
// collect all blocked attackers
|
||||||
|
List<MageObjectReference> blocked = getBlockedAttackers(game, blocker, blockedCreaturesByCreature);
|
||||||
|
for (UUID combatAttackerId : combatGroup.getAttackers()) {
|
||||||
|
Permanent combatAttacker = game.getPermanent(combatAttackerId);
|
||||||
|
if (combatAttacker != null) {
|
||||||
|
blocked.add(new MageObjectReference(combatAttacker, game));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blockedCreaturesByCreature;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MageObjectReference> getBlockedAttackers(Game game, Permanent blocker, Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesByCreature) {
|
||||||
|
// finds creatures list blocked by blocker permanent
|
||||||
MageObjectReference blockerRef = new MageObjectReference(blocker, game);
|
MageObjectReference blockerRef = new MageObjectReference(blocker, game);
|
||||||
// See if we already reference this blocker
|
|
||||||
for (MageObjectReference r : blockedCreaturesByCreature.keySet()) {
|
for (MageObjectReference r : blockedCreaturesByCreature.keySet()) {
|
||||||
if (r.equals(blockerRef)) {
|
if (r.equals(blockerRef)) {
|
||||||
// Use the existing reference if we do
|
// already exist
|
||||||
blockerRef = r;
|
blockerRef = r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!blockedCreaturesByCreature.containsKey(blockerRef)) {
|
||||||
|
blockedCreaturesByCreature.put(blockerRef, new ArrayList<>());
|
||||||
|
}
|
||||||
List<MageObjectReference> blocked = blockedCreaturesByCreature.getOrDefault(blockerRef, new ArrayList<>());
|
List<MageObjectReference> blocked = blockedCreaturesByCreature.getOrDefault(blockerRef, new ArrayList<>());
|
||||||
|
return blocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canBlockAnother(Game game, Permanent blocker, Permanent attacker, Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesByCreature) {
|
||||||
|
// check if blocker can block one more attacker and adds it
|
||||||
|
List<MageObjectReference> blocked = getBlockedAttackers(game, blocker, blockedCreaturesByCreature);
|
||||||
int numBlocked = blocked.size();
|
int numBlocked = blocked.size();
|
||||||
|
|
||||||
// Can't block any more creatures
|
// Can't block any more creatures
|
||||||
if (++numBlocked > blocker.getMaxBlocks()) {
|
if (++numBlocked > blocker.getMaxBlocks()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the attacker reference to the list of creatures this creature is blocking
|
// Add the attacker reference to the list of creatures this creature is blocking
|
||||||
blocked.add(new MageObjectReference(attacker, game));
|
blocked.add(new MageObjectReference(attacker, game));
|
||||||
blockedCreaturesByCreature.put(blockerRef, blocked);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for Menace type abilities - if creatures can be blocked by >X or <Y only
|
|
||||||
private void checkMultipleBlockers(Game game, Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesByCreature) {
|
private void checkMultipleBlockers(Game game, Map<MageObjectReference, List<MageObjectReference>> blockedCreaturesByCreature) {
|
||||||
|
// Check for Menace type abilities - if creatures can be blocked by >X or <Y only
|
||||||
|
|
||||||
// Stores the total number of blockers for each attacker
|
// Stores the total number of blockers for each attacker
|
||||||
Map<MageObjectReference, Integer> blockersForAttacker = new HashMap<>();
|
Map<MageObjectReference, Integer> blockersForAttacker = new HashMap<>();
|
||||||
|
|
||||||
// Calculate the number of blockers each attacker has
|
// Calculate the number of blockers each attacker has
|
||||||
for (List<MageObjectReference> attackers : blockedCreaturesByCreature.values()) {
|
for (List<MageObjectReference> attackers : blockedCreaturesByCreature.values()) {
|
||||||
for (MageObjectReference mr : attackers) {
|
for (MageObjectReference mr : attackers) {
|
||||||
|
|
@ -1559,6 +1618,7 @@ public class TestPlayer implements Player {
|
||||||
blockersForAttacker.put(mr, blockers + 1);
|
blockersForAttacker.put(mr, blockers + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check each attacker is blocked by an allowed amount of creatures
|
// Check each attacker is blocked by an allowed amount of creatures
|
||||||
for (Map.Entry<MageObjectReference, Integer> entry : blockersForAttacker.entrySet()) {
|
for (Map.Entry<MageObjectReference, Integer> entry : blockersForAttacker.entrySet()) {
|
||||||
Permanent attacker = entry.getKey().getPermanent(game);
|
Permanent attacker = entry.getKey().getPermanent(game);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import mage.game.command.CommandObject;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.PermanentCard;
|
import mage.game.permanent.PermanentCard;
|
||||||
import mage.player.ai.ComputerPlayer7;
|
import mage.player.ai.ComputerPlayer7;
|
||||||
|
import mage.player.ai.ComputerPlayerMCTS;
|
||||||
import mage.players.ManaPool;
|
import mage.players.ManaPool;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
@ -1447,8 +1448,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAiPlayAndGameCompatible(TestPlayer player) {
|
private void assertAiPlayAndGameCompatible(TestPlayer player) {
|
||||||
if (player.isAIPlayer() || !(player.getComputerPlayer() instanceof ComputerPlayer7)) {
|
boolean aiCompatible = (player.getComputerPlayer() instanceof ComputerPlayer7 || player.getComputerPlayer() instanceof ComputerPlayerMCTS);
|
||||||
Assert.fail("AI commands supported by CardTestPlayerBaseWithAIHelps only");
|
if (player.isAIPlayer() || !aiCompatible) {
|
||||||
|
Assert.fail("AI commands supported by CardTestPlayerBaseWith***AIHelps only");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue