Changes in testing framework. Added support for fixed targets. Added test to damage itself by Lightning Bolt. Ignored some old tests.

This commit is contained in:
magenoxx 2011-11-15 19:43:37 +04:00
parent f0cc3d1d0f
commit 60b6fe5a79
13 changed files with 132 additions and 23 deletions

View file

@ -52,10 +52,8 @@ import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.game.turn.*;
import mage.players.Player;
import mage.sets.alarareborn.OfferingToAsha;
import mage.target.Target;
import mage.target.TargetCard;
import sun.rmi.transport.ObjectTable;
import java.io.File;
import java.util.*;
@ -86,7 +84,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
public ComputerPlayer6(String name, RangeOfInfluence range, int skill) {
super(name, range);
maxDepth = skill * 2;
maxThink = skill * 3;
maxThink = skill * 300;
maxNodes = Config2.maxNodes;
getSuggestedActions();
}
@ -196,14 +194,21 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
while (actions.peek() != null) {
Ability ability = actions.poll();
System.out.println("[" + game.getPlayer(playerId).getName() + "] Action: " + ability.toString());
if (ability.getTargets().size() > 0) {
Player player = game.getPlayer(ability.getFirstTarget());
if (player != null) {
System.out.println("targets = " + player.getName());
}
}
this.activateAbility((ActivatedAbility) ability, game);
if (ability.isUsesStack())
usedStack = true;
if (!suggested.isEmpty()) {
if (!suggested.isEmpty() && !(ability instanceof PassAbility)) {
Iterator<String> it = suggested.iterator();
while (it.hasNext()) {
Card card = game.getCard(ability.getSourceId());
String action = it.next();
System.out.println("action="+action+";card="+card);
if (action.equals(card.getName())) {
System.out.println("removed from suggested="+action);
it.remove();
@ -484,6 +489,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " actions:" + action);
sim.checkStateAndTriggered();
int val = addActions(newNode, depth-1, alpha, beta);
logger.debug("val = " + val);
if (!currentPlayer.getId().equals(playerId)) {
if (val < beta) {
beta = val;
@ -523,7 +529,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
}
}
if (alpha >= beta) {
//logger.info("simulating -- pruning");
logger.info("simulating -- pruning");
break;
}
if (SimulationNode2.nodeCount > maxNodes) {
@ -538,11 +544,21 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
node.setScore(bestNode.getScore());
}
if (!currentPlayer.getId().equals(playerId)) {
//logger.info("returning priority beta: " + beta);
/*if (beta == Integer.MAX_VALUE) {
int val = GameStateEvaluator2.evaluate(playerId, game);
logger.info("returning priority beta: " + val);
return val;
}*/
logger.info("returning priority beta: " + beta);
return beta;
}
else {
//logger.info("returning priority alpha: " + alpha);
/*if (alpha == Integer.MIN_VALUE) {
int val = GameStateEvaluator2.evaluate(playerId, game);
logger.info("returning priority beta: " + val);
return val;
}*/
logger.info("returning priority alpha: " + alpha);
return alpha;
}
}

View file

@ -56,6 +56,8 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
private static FilterAbility filterLand = new FilterAbility();
private static FilterAbility filterNotLand = new FilterAbility();
private boolean allowBadMoves;
static {
filterLand.getTypes().add(AbilityType.PLAY_LAND);
filterLand.setZone(Zone.HAND);
@ -155,7 +157,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
if (root.children.size() > 0) {
root = root.children.get(0);
int bestScore = root.getScore();
if (bestScore > currentScore) {
if (bestScore > currentScore || allowBadMoves) {
actions = new LinkedList<Ability>(root.abilities);
combat = root.combat;
}
@ -175,7 +177,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
if (root.children.size() > 0) {
root = root.children.get(0);
int bestScore = root.getScore();
if (bestScore > currentScore) {
if (bestScore > currentScore || allowBadMoves) {
actions = new LinkedList<Ability>(root.abilities);
combat = root.combat;
}
@ -222,8 +224,8 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
if (game.getActivePlayerId().equals(playerId)) {
if (testScore < currentScore) {
// if score at end of step is worse than original score don't check further
logger.debug("simulating -- abandoning check, no immediate benefit");
val = testScore;
//logger.debug("simulating -- abandoning check, no immediate benefit");
val = testScore;
}
else {
switch (game.getTurn().getStepType()) {
@ -541,4 +543,8 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
}
}
@Override
public void setAllowBadMoves(boolean allowBadMoves) {
this.allowBadMoves = allowBadMoves;
}
}

View file

@ -28,8 +28,6 @@
package mage.player.ai;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.PassAbility;
@ -44,9 +42,13 @@ import mage.game.combat.Combat;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackAbility;
import mage.players.Player;
import mage.target.Target;
import org.apache.log4j.Logger;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
*
* @author BetaSteward_at_googlemail.com
@ -56,6 +58,7 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
private final static transient Logger logger = Logger.getLogger(SimulatedPlayer2.class);
private boolean isSimulatedPlayer;
private transient ConcurrentLinkedQueue<Ability> allActions;
private boolean forced;
private static PassAbility pass = new PassAbility();
private List<String> suggested;
@ -81,19 +84,35 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
allActions = new ConcurrentLinkedQueue<Ability>();
Game sim = game.copy();
simulateOptions(sim, pass);
forced = false;
simulateOptions(sim);
ArrayList<Ability> list = new ArrayList<Ability>(allActions);
Collections.reverse(list);
if (!forced) {
list.add(pass);
}
for (Ability a : allActions) {
System.out.println("ability=="+a);
if (a.getTargets().size() > 0) {
Player player = game.getPlayer(a.getFirstTarget());
if (player != null) {
System.out.println(" target="+player.getName());
}
}
}
return list;
}
protected void simulateOptions(Game game, Ability previousActions) {
allActions.add(previousActions);
protected void simulateOptions(Game game) {
List<Ability> playables = game.getPlayer(playerId).getPlayable(game, isSimulatedPlayer);
playables = filterAbilities(game, playables, suggested);
for (Ability ability: playables) {
List<Ability> options = game.getPlayer(playerId).getPlayableOptions(ability, game);
options = filterOptions(game, options, ability, suggested);
if (options.isEmpty()) {
if (ability.getManaCosts().getVariableCosts().size() > 0) {
simulateVariableCosts(ability, game);
@ -145,6 +164,7 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
for (String s : suggested) {
if (s.equals(card.getName())) {
System.out.println("matched: " + s);
forced = true;
filtered.add(ability);
}
}
@ -155,6 +175,41 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
return playables;
}
protected List<Ability> filterOptions(Game game, List<Ability> options, Ability ability, List<String> suggested) {
if (options.isEmpty()) {
return options;
}
if (suggested == null || suggested.isEmpty()) {
return options;
}
List<Ability> filtered = new ArrayList<Ability>();
for (Ability option : options) {
if (option.getTargets().size() > 0 && option.getTargets().get(0).getMaxNumberOfTargets() == 1) {
Card card = game.getCard(ability.getSourceId());
for (String s : suggested) {
String[] groups = s.split(";");
System.out.println("s="+s+";groups="+groups.length);
if (groups.length == 2) {
if (groups[0].equals(card.getName()) && groups[1].startsWith("name=")) {
// extract target and compare to suggested
String name = groups[1].split("=")[1];
Player player = game.getPlayer(option.getFirstTarget());
if (player != null && name.equals(player.getName())) {
System.out.println("matched(option): " + s);
filtered.add(option);
return filtered;
} else {
System.out.println("not equal UUID for target, player=" + player);
}
}
}
}
}
}
// no option was found
return options;
}
//add a generic mana cost for each amount possible
protected void simulateVariableCosts(Ability ability, Game game) {
int numAvailable = getAvailableManaProducers(game).size();

View file

@ -11,14 +11,33 @@ public class LightningBoltTest extends CardTestBase {
@Test
public void testDamageOpponent() {
System.out.println("TEST: testDamageOpponent");
addCard(Constants.Zone.HAND, playerA, "Mountain");
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
playLand(playerA, "Mountain");
castSpell(playerA, "Lightning Bolt");
// not specifying target, AI should choose opponent by itself
execute();
assertLife(playerA, 20);
assertLife(playerB, 17);
}
@Test
public void testDamageSelf() {
System.out.println("TEST: testDamageSelf");
addCard(Constants.Zone.HAND, playerA, "Mountain");
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
playLand(playerA, "Mountain");
castSpell(playerA, "Lightning Bolt");
addFixedTarget(playerA, "Lightning Bolt", playerA);
playerA.setAllowBadMoves(true);
execute();
assertLife(playerA, 17);
assertLife(playerB, 20);
}
}

View file

@ -11,6 +11,7 @@ import mage.game.TwoPlayerDuel;
import mage.player.ai.ComputerPlayer;
import mage.players.Player;
import mage.sets.Sets;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.MageTestBase;
@ -27,7 +28,8 @@ public class PlayGameTest extends MageTestBase {
private static List<String> colorChoices = Arrays.asList("bu", "bg", "br", "bw", "ug", "ur", "uw", "gr", "gw", "rw", "bur", "buw", "bug", "brg", "brw", "bgw", "wur", "wug", "wrg", "rgu");
@Test
@Ignore
@Test
public void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException {
Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL);

View file

@ -4,6 +4,7 @@ import junit.framework.Assert;
import mage.Constants;
import mage.game.permanent.Permanent;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestBase;
@ -16,6 +17,7 @@ import org.mage.test.serverside.base.CardTestBase;
public class BugTapsItselfTest extends CardTestBase {
@Test
@Ignore
public void testVersusInfectCreature() throws Exception {
useWhiteDefault();
addCard(Constants.Zone.BATTLEFIELD, playerA, "Blinding Mage");

View file

@ -66,8 +66,8 @@ public abstract class CardTestBase extends CardTestAPIImpl {
Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL);
playerA = aiTypeA.equals(CardTestBase.AIType.MinimaxHybrid) ?
createPlayer("ComputerA", "Computer - minimax hybrid") :
createPlayer("ComputerA", "Computer - mad");
createPlayer("PlayerA", "Computer - minimax hybrid") :
createPlayer("PlayerA", "Computer - mad");
playerA.setTestMode(true);
logger.info("Loading deck...");
Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
@ -79,8 +79,8 @@ public abstract class CardTestBase extends CardTestAPIImpl {
game.loadCards(deck.getCards(), playerA.getId());
playerB = aiTypeB.equals(CardTestBase.AIType.MinimaxHybrid) ?
createPlayer("ComputerB", "Computer - minimax hybrid") :
createPlayer("ComputerB", "Computer - mad");
createPlayer("PlayerB", "Computer - minimax hybrid") :
createPlayer("PlayerB", "Computer - mad");
playerB.setTestMode(true);
Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
if (deck2.getCards().size() < 40) {

View file

@ -363,8 +363,8 @@ public abstract class CardTestAPIImpl extends MageTestBase implements CardTestAP
player.addAction("cast:"+cardName);
}
public void castSpell(Player player, String cardName, String target) {
player.addAction("cast:"+cardName + ";" + target);
public void addFixedTarget(Player player, String cardName, Player target) {
player.addAction("cast:"+cardName + ";name=" + target.getName());
}
public void useAbility(Player player, String cardName) {

View file

@ -1,6 +1,7 @@
package org.mage.test.serverside.cards.effects;
import mage.filter.Filter;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestBase;
@ -12,6 +13,7 @@ import org.mage.test.serverside.base.CardTestBase;
public class BoostContinuousEffectTest extends CardTestBase {
@Test
@Ignore
public void testHonorOfThePoor() throws Exception {
load("M11/Honor of the Pure.test");
execute();

View file

@ -2,6 +2,7 @@ package org.mage.test.serverside.cards.single.mbs;
import mage.Constants;
import mage.filter.Filter;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestAPI;
import org.mage.test.serverside.base.CardTestBase;
@ -24,6 +25,7 @@ public class BurntheImpureTest extends CardTestBase {
* @throws Exception
*/
@Test
@Ignore
public void testVersusInfectCreature() throws Exception {
// $include red.default
useRedDefault();

View file

@ -164,6 +164,7 @@ public interface Player extends MageItem, Copyable<Player> {
public boolean isTestMode();
public void setTestMode(boolean value);
public void addAction(String action);
public void setAllowBadMoves(boolean allowBadMoves);
public void init(Game game);
public void init(Game game, boolean testMode);

View file

@ -1351,4 +1351,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
// do nothing
}
public void setAllowBadMoves(boolean allowBadMoves) {
// do nothing
}
}