forked from External/mage
Tests: added support to cast fused cards in tests (any selected side or fused);
This commit is contained in:
parent
1f1ba7ea8e
commit
5cf1e5a7a0
5 changed files with 157 additions and 43 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue