Fixed AI doesn't play spells that targets creatureOrPlayer. The fix applied to ai-ma only, other ai jar still needs to be recompiled.

This commit is contained in:
magenoxx 2011-02-12 23:21:20 +03:00
parent 6f576f74f5
commit e189543699
5 changed files with 88 additions and 30 deletions

View file

@ -48,6 +48,7 @@ import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.SearchEffect;
import mage.cards.Card;
import mage.cards.Cards;
import mage.choices.Choice;
import mage.filter.FilterAbility;
@ -55,6 +56,7 @@ import mage.game.Game;
import mage.game.combat.Combat;
import mage.game.combat.CombatGroup;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.game.turn.BeginCombatStep;
@ -136,18 +138,39 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
pass();
break;
case PRECOMBAT_MAIN:
case BEGIN_COMBAT:
case DECLARE_ATTACKERS:
case DECLARE_BLOCKERS:
case COMBAT_DAMAGE:
case END_COMBAT:
case POSTCOMBAT_MAIN:
if (game.getActivePlayerId().equals(playerId)) {
Player player = game.getPlayer(playerId);
System.out.println("Turn::"+game.getTurnNum());
System.out.println("[" + game.getPlayer(playerId).getName() + "] " + game.getTurn().getStepType().name() +", life=" + player.getLife());
String s = "[";
for (Card card : player.getHand().getCards(game)) {
s += card.getName() + ";";
}
s += "]";
System.out.println("Hand: " + s);
s = "[";
for (Permanent permanent : game.getBattlefield().getAllPermanents()) {
if (permanent.getOwnerId().equals(player.getId())) {
s += permanent.getName() + ";";
}
}
s += "]";
System.out.println("Permanents: " + s);
}
if (actions.size() == 0) {
calculateActions(game);
}
act(game);
break;
case BEGIN_COMBAT:
case DECLARE_ATTACKERS:
case DECLARE_BLOCKERS:
case COMBAT_DAMAGE:
case END_COMBAT:
case END_TURN:
pass();
break;
case CLEANUP:
pass();
break;
@ -181,11 +204,14 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
addActionsTimed(new FilterAbility());
if (root.children.size() > 0) {
root = root.children.get(0);
int bestScore = GameStateEvaluator2.evaluate(playerId, root.getGame());
if (bestScore > currentScore) {
actions = new LinkedList<Ability>(root.abilities);
combat = root.combat;
}
}
}
}
protected boolean getNextAction(Game game) {
if (root != null && root.children.size() > 0) {
@ -243,11 +269,11 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
if (bestChild != null)
node.children.add(bestChild);
if (!currentPlayerId.equals(playerId)) {
logger.info("returning minimax beta: " + beta);
//logger.info("returning minimax beta: " + beta);
return beta;
}
else {
logger.info("returning minimax alpha: " + alpha);
//logger.info("returning minimax alpha: " + alpha);
return alpha;
}
}
@ -311,7 +337,7 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
}
protected int addActions(SimulationNode2 node, FilterAbility filter, int depth, int alpha, int beta) {
logger.info("addActions: " + depth + ", alpha=" + alpha + ", beta=" + beta);
logger.fine("addActions: " + depth + ", alpha=" + alpha + ", beta=" + beta);
Game game = node.getGame();
int val;
if (Thread.interrupted()) {
@ -320,16 +346,16 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
return GameStateEvaluator2.evaluate(playerId, game);
}
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.isGameOver()) {
logger.info("simulating -- reached end state, node count="+ SimulationNode2.nodeCount + ", depth="+depth);
logger.fine("simulating -- reached end state, node count="+ SimulationNode2.nodeCount + ", depth="+depth);
val = GameStateEvaluator2.evaluate(playerId, game);
}
else if (node.getChildren().size() > 0) {
logger.info("simulating -- somthing added children:" + node.getChildren().size());
logger.fine("simulating -- somthing added children:" + node.getChildren().size());
val = minimaxAB(node, filter, depth-1, alpha, beta);
}
else {
if (logger.isLoggable(Level.FINE))
logger.info("simulating -- alpha: " + alpha + " beta: " + beta + " depth:" + depth + " step:" + game.getTurn().getStepType() + " for player:" + (node.getPlayerId().equals(playerId)?"yes":"no"));
logger.fine("simulating -- alpha: " + alpha + " beta: " + beta + " depth:" + depth + " step:" + game.getTurn().getStepType() + " for player:" + (node.getPlayerId().equals(playerId)?"yes":"no"));
if (allPassed(game)) {
if (!game.getStack().isEmpty()) {
resolve(node, depth, game);
@ -350,10 +376,9 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
val = GameStateEvaluator2.evaluate(playerId, game);
}
else if (node.getChildren().size() > 0) {
throw new RuntimeException("This shouldn't happen.");
//declared attackers or blockers or triggered abilities
///logger.info("simulating -- attack/block/trigger added children:" + node.getChildren().size());
///val = minimaxAB(node, filter, depth-1, alpha, beta);
logger.fine("simulating -- attack/block/trigger added children:" + node.getChildren().size());
val = minimaxAB(node, filter, depth-1, alpha, beta);
}
else {
val = simulatePriority(node, game, filter, depth, alpha, beta);
@ -361,7 +386,7 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
}
if (logger.isLoggable(Level.FINE))
logger.info("returning -- score: " + val + " depth:" + depth + " step:" + game.getTurn().getStepType() + " for player:" + game.getPlayer(node.getPlayerId()).getName());
logger.fine("returning -- score: " + val + " depth:" + depth + " step:" + game.getTurn().getStepType() + " for player:" + game.getPlayer(node.getPlayerId()).getName());
return val;
}
@ -378,7 +403,7 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
SimulationNode2 bestNode = null;
List<Ability> allActions = currentPlayer.simulatePriority(game, filter);
if (logger.isLoggable(Level.FINE))
logger.info("simulating -- adding " + allActions.size() + " children:" + allActions);
logger.fine("simulating -- adding " + allActions.size() + " children:" + allActions);
for (Ability action: allActions) {
Game sim = game.copy();
if (sim.getPlayer(currentPlayer.getId()).activateAbility((ActivatedAbility) action.copy(), sim)) {
@ -390,7 +415,7 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
}
SimulationNode2 newNode = new SimulationNode2(sim, action, depth, currentPlayer.getId());
if (logger.isLoggable(Level.FINE))
logger.info("simulating -- node #:" + SimulationNode2.getCount() + " actions:" + action);
logger.fine("simulating -- node #:" + SimulationNode2.getCount() + " actions:" + action);
sim.checkStateAndTriggered();
int val = addActions(newNode, filter, depth-1, alpha, beta);
if (!currentPlayer.getId().equals(playerId)) {
@ -416,7 +441,7 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
break;
}
if (SimulationNode2.nodeCount > maxNodes) {
logger.info("simulating -- reached end-state");
logger.fine("simulating -- reached end-state");
break;
}
}

View file

@ -112,6 +112,7 @@ public class ComputerPlayer5 extends ComputerPlayer4 implements Player {
case PRECOMBAT_MAIN:
if (game.getActivePlayerId().equals(playerId)) {
Player player = game.getPlayer(playerId);
System.out.println("Turn:"+game.getTurnNum());
System.out.println("[" + game.getPlayer(playerId).getName() + "] Precombat Main, life=" + player.getLife());
String s = "[";
for (Card card : player.getHand().getCards(game)) {
@ -181,9 +182,12 @@ public class ComputerPlayer5 extends ComputerPlayer4 implements Player {
addActionsTimed(new FilterAbility());
if (root.children.size() > 0) {
root = root.children.get(0);
int bestScore = GameStateEvaluator2.evaluate(playerId, root.getGame());
if (bestScore > currentScore) {
actions = new LinkedList<Ability>(root.abilities);
combat = root.combat;
}
}
//}
}
@ -197,11 +201,14 @@ public class ComputerPlayer5 extends ComputerPlayer4 implements Player {
addActionsTimed(new FilterAbility());
if (root.children.size() > 0) {
root = root.children.get(0);
int bestScore = GameStateEvaluator2.evaluate(playerId, root.getGame());
if (bestScore > currentScore) {
actions = new LinkedList<Ability>(root.abilities);
combat = root.combat;
}
}
}
}
@Override
protected int addActions(SimulationNode2 node, FilterAbility filter, int depth, int alpha, int beta) {
@ -240,7 +247,7 @@ public class ComputerPlayer5 extends ComputerPlayer4 implements Player {
logger.fine("step finished");
int testScore = GameStateEvaluator2.evaluate(playerId, game);
if (game.getActivePlayerId().equals(playerId)) {
if (testScore < currentScore) {
if (testScore <= currentScore) {
// if score at end of step is worse than original score don't check further
logger.fine("simulating -- abandoning check, no immediate benefit");
val = testScore;

View file

@ -64,6 +64,7 @@ import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.mana.ManaAbility;
import mage.abilities.mana.ManaOptions;
import mage.filter.common.*;
import mage.game.draft.Draft;
import mage.player.ai.simulators.CombatGroupSimulator;
import mage.player.ai.simulators.CombatSimulator;
@ -73,10 +74,6 @@ import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreatureForCombat;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterLandCard;
import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
import mage.game.Table;
import mage.game.combat.CombatGroup;
@ -90,6 +87,7 @@ import mage.target.TargetAmount;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreatureOrPlayer;
import mage.target.common.TargetDiscard;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreatureOrPlayerAmount;
@ -271,6 +269,34 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
}
}
}
if (target instanceof TargetCreatureOrPlayer) {
List<Permanent> targets;
TargetCreatureOrPlayer t = ((TargetCreatureOrPlayer)target);
if (outcome.isGood()) {
targets = threats(playerId, ((FilterCreatureOrPlayer)t.getFilter()).getCreatureFilter(), game);
}
else {
targets = threats(opponentId, ((FilterCreatureOrPlayer)t.getFilter()).getCreatureFilter(), game);
}
for (Permanent permanent: targets) {
if (((TargetPermanent)target).canTarget(playerId, permanent.getId(), source, game)) {
target.addTarget(permanent.getId(), source, game);
return true;
}
}
if (outcome.isGood()) {
if (target.canTarget(playerId, source, game)) {
target.addTarget(playerId, source, game);
return true;
}
}
else {
if (target.canTarget(playerId, source, game)) {
target.addTarget(opponentId, source, game);
return true;
}
}
}
return false;
}

View file

@ -4,7 +4,7 @@
<server serverAddress="localhost" serverName="mage-server" port="17171" maxGameThreads="10" maxSecondsIdle="600"/>
<playerTypes>
<playerType name="Computer - minimax hybrid" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>
<playerType name="Computer - mad" jar="mage-player-ai-ma.jar" className="mage.player.ai.ComputerPlayer5"/>
<playerType name="Computer - mad" jar="mage-player-ai-ma.jar" className="mage.player.ai.ComputerPlayer4"/>
</playerTypes>
<gameTypes>
<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/>