Tests: added support to cast fused cards in tests (any selected side or fused);

This commit is contained in:
Oleg Agafonov 2018-11-23 17:02:39 +04:00
parent 1f1ba7ea8e
commit 5cf1e5a7a0
5 changed files with 157 additions and 43 deletions

View file

@ -0,0 +1,62 @@
package org.mage.test.player;
import mage.MageObject;
import mage.abilities.ActivatedAbility;
import mage.abilities.SpellAbility;
import mage.constants.RangeOfInfluence;
import mage.game.Game;
import mage.player.ai.ComputerPlayer;
import java.util.LinkedHashMap;
import java.util.UUID;
/**
* @author JayDi85
*/
// mock class to override to override AI logic for test
public class TestComputerPlayer extends ComputerPlayer {
private TestPlayer testPlayerLink;
public TestComputerPlayer(String name, RangeOfInfluence range) {
super(name, range);
}
public void setTestPlayerLink(TestPlayer testPlayerLink) {
this.testPlayerLink = testPlayerLink;
}
@Override
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
// copy-paste for TestComputerXXX
// workaround to cast fused cards in tests by it's NAMES (Wear, Tear, Wear // Tear)
// reason: TestPlayer uses outer computerPlayer to cast, not TestPlayer
switch (ability.getSpellAbilityType()) {
case SPLIT:
case SPLIT_FUSED:
case SPLIT_AFTERMATH:
if (!this.testPlayerLink.getChoices().isEmpty()) {
MageObject object = game.getObject(ability.getSourceId());
if (object != null) {
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = this.getSpellAbilities(object, game.getState().getZone(object.getId()), game);
// left, right or fused cast
for (String choose : this.testPlayerLink.getChoices()) {
for (ActivatedAbility activatedAbility : useableAbilities.values()) {
if (activatedAbility instanceof SpellAbility) {
if (((SpellAbility) activatedAbility).getCardName().equals(choose)) {
return (SpellAbility) activatedAbility;
}
}
}
}
}
}
}
// default implementation by AI
return super.chooseSpellAbilityForCast(ability, game, noMana);
}
}

View file

@ -0,0 +1,62 @@
package org.mage.test.player;
import mage.MageObject;
import mage.abilities.ActivatedAbility;
import mage.abilities.SpellAbility;
import mage.constants.RangeOfInfluence;
import mage.game.Game;
import mage.player.ai.ComputerPlayer7;
import java.util.LinkedHashMap;
import java.util.UUID;
/**
* @author JayDi85
*/
// mock class to override AI logic in tests
public class TestComputerPlayer7 extends ComputerPlayer7 {
private TestPlayer testPlayerLink;
public TestComputerPlayer7(String name, RangeOfInfluence range, int skill) {
super(name, range, skill);
}
public void setTestPlayerLink(TestPlayer testPlayerLink) {
this.testPlayerLink = testPlayerLink;
}
@Override
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
// copy-paste for TestComputerXXX
// workaround to cast fused cards in tests by it's NAMES (Wear, Tear, Wear // Tear)
// reason: TestPlayer uses outer computerPlayer to cast, not TestPlayer
switch (ability.getSpellAbilityType()) {
case SPLIT:
case SPLIT_FUSED:
case SPLIT_AFTERMATH:
if (!this.testPlayerLink.getChoices().isEmpty()) {
MageObject object = game.getObject(ability.getSourceId());
if (object != null) {
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = this.getSpellAbilities(object, game.getState().getZone(object.getId()), game);
// left, right or fused cast
for (String choose : this.testPlayerLink.getChoices()) {
for (ActivatedAbility activatedAbility : useableAbilities.values()) {
if (activatedAbility instanceof SpellAbility) {
if (((SpellAbility) activatedAbility).getCardName().equals(choose)) {
return (SpellAbility) activatedAbility;
}
}
}
}
}
}
}
// default implementation by AI
return super.chooseSpellAbilityForCast(ability, game, noMana);
}
}

View file

@ -43,7 +43,6 @@ import mage.player.ai.ComputerPlayer;
import mage.players.Library;
import mage.players.ManaPool;
import mage.players.Player;
import mage.players.PlayerList;
import mage.players.net.UserData;
import mage.target.*;
import mage.target.common.*;
@ -84,9 +83,16 @@ public class TestPlayer implements Player {
// Before actual turns start. Needed for checking attacker/blocker legality in the tests
private static int initialTurns = 0;
public TestPlayer(ComputerPlayer computerPlayer) {
public TestPlayer(TestComputerPlayer computerPlayer) {
this.computerPlayer = computerPlayer;
AIPlayer = false;
computerPlayer.setTestPlayerLink(this);
}
public TestPlayer(TestComputerPlayer7 computerPlayer) {
this.computerPlayer = computerPlayer;
AIPlayer = false;
computerPlayer.setTestPlayerLink(this);
}
public TestPlayer(final TestPlayer testPlayer) {
@ -106,6 +112,10 @@ public class TestPlayer implements Player {
choices.add(choice);
}
public List<String> getChoices() {
return this.choices;
}
public void addModeChoice(String mode) {
modesSet.add(mode);
}
@ -1146,9 +1156,9 @@ public class TestPlayer implements Player {
Boolean canEquals = canSupportChars.contains("=");
// how to fix: change target definition for addTarget in test's code or update choose from targets implementation in TestPlayer
if((foundMulti && !canMulti) || (foundSpecialStart && !canSpecialStart) || (foundSpecialClose && !canSpecialClose)|| (foundEquals && !canEquals)) {
if ((foundMulti && !canMulti) || (foundSpecialStart && !canSpecialStart) || (foundSpecialClose && !canSpecialClose) || (foundEquals && !canEquals)) {
Assert.fail("Targets list was setup by addTarget with " + targets + ", but target definition [" + targetDefinition + "]"
+ " is not supported by ["+ canSupportChars + "] for target class " + needTarget.getClass().getSimpleName());
+ " is not supported by [" + canSupportChars + "] for target class " + needTarget.getClass().getSimpleName());
}
}
@ -1330,14 +1340,14 @@ public class TestPlayer implements Player {
List<UUID> needPlayers = game.getState().getPlayersInRange(getId(), game).toList();
// fix for opponent graveyard
if(target instanceof TargetCardInOpponentsGraveyard) {
if (target instanceof TargetCardInOpponentsGraveyard) {
// current player remove
Assert.assertTrue(needPlayers.contains(getId()));
needPlayers.remove(getId());
Assert.assertFalse(needPlayers.contains(getId()));
}
// fix for your graveyard
if(target instanceof TargetCardInYourGraveyard) {
if (target instanceof TargetCardInYourGraveyard) {
// only current player
Assert.assertTrue(needPlayers.contains(getId()));
needPlayers.clear();
@ -1400,10 +1410,10 @@ public class TestPlayer implements Player {
// wrong target settings by addTarget
// how to fix: implement target class processing above
if(!targets.isEmpty()) {
if (!targets.isEmpty()) {
String message;
if(source != null) {
if (source != null) {
message = "Targets list was setup by addTarget with " + targets + ", but not used in ["
+ "card " + source.getSourceObject(game)
+ " -> ability " + source.getClass().getSimpleName() + " (" + source.getRule().substring(0, Math.min(20, source.getRule().length()) - 1) + "..." + ")"
@ -1792,6 +1802,8 @@ public class TestPlayer implements Player {
@Override
public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference) {
// TestPlayer, ComputerPlayer always call inherited cast() from PlayerImpl
// that's why chooseSpellAbilityForCast will be ignored in TestPlayer, see workaround with TestComputerPlayerXXX
return computerPlayer.cast(ability, game, noMana, reference);
}
@ -2586,24 +2598,7 @@ public class TestPlayer implements Player {
@Override
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
switch (ability.getSpellAbilityType()) {
case SPLIT:
case SPLIT_FUSED:
case SPLIT_AFTERMATH:
if (!choices.isEmpty()) {
MageObject object = game.getObject(ability.getSourceId());
if (object != null) {
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = computerPlayer.getSpellAbilities(object, game.getState().getZone(object.getId()), game);
for (String choose : choices) {
for (ActivatedAbility actiavtedAbility : useableAbilities.values()) {
if (actiavtedAbility.getRule().startsWith(choose)) {
return (SpellAbility) actiavtedAbility;
}
}
}
}
}
}
Assert.fail("That's method calls only from computerPlayer->cast(), see TestComputerPlayerXXX");
return computerPlayer.chooseSpellAbilityForCast(ability, game, noMana);
}

View file

@ -1,18 +1,17 @@
package org.mage.test.serverside.base;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.game.Game;
import mage.game.GameException;
import mage.game.TwoPlayerDuel;
import mage.player.ai.ComputerPlayer7;
import org.mage.test.player.TestComputerPlayer7;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl;
import java.io.FileNotFoundException;
/**
*
* @author LevelX2
*/
public abstract class CardTestPlayerBaseAI extends CardTestPlayerAPIImpl {
@ -31,7 +30,7 @@ public abstract class CardTestPlayerBaseAI extends CardTestPlayerAPIImpl {
@Override
protected TestPlayer createPlayer(String name, RangeOfInfluence rangeOfInfluence) {
if (name.equals("PlayerA")) {
TestPlayer testPlayer = new TestPlayer(new ComputerPlayer7("PlayerA", RangeOfInfluence.ONE, skill));
TestPlayer testPlayer = new TestPlayer(new TestComputerPlayer7("PlayerA", RangeOfInfluence.ONE, skill));
testPlayer.setAIPlayer(true);
return testPlayer;
}

View file

@ -1,16 +1,6 @@
package org.mage.test.serverside.base;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mage.cards.Card;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
@ -21,7 +11,6 @@ import mage.game.Game;
import mage.game.match.MatchType;
import mage.game.permanent.PermanentCard;
import mage.game.tournament.TournamentType;
import mage.player.ai.ComputerPlayer;
import mage.players.Player;
import mage.server.game.GameFactory;
import mage.server.util.ConfigSettings;
@ -32,8 +21,15 @@ import mage.util.Copier;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.mage.test.player.TestComputerPlayer;
import org.mage.test.player.TestPlayer;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Base class for all tests.
*
@ -334,7 +330,7 @@ public abstract class MageTestPlayerBase {
}
protected TestPlayer createPlayer(String name, RangeOfInfluence rangeOfInfluence) {
return new TestPlayer(new ComputerPlayer(name, rangeOfInfluence));
return new TestPlayer(new TestComputerPlayer(name, rangeOfInfluence));
}
}