mirror of
https://github.com/correl/mage.git
synced 2024-12-24 03:00:14 +00:00
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:
parent
6f576f74f5
commit
e189543699
5 changed files with 88 additions and 30 deletions
|
@ -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,8 +204,11 @@ public class ComputerPlayer4 extends ComputerPlayer<ComputerPlayer4> implements
|
|||
addActionsTimed(new FilterAbility());
|
||||
if (root.children.size() > 0) {
|
||||
root = root.children.get(0);
|
||||
actions = new LinkedList<Ability>(root.abilities);
|
||||
combat = root.combat;
|
||||
int bestScore = GameStateEvaluator2.evaluate(playerId, root.getGame());
|
||||
if (bestScore > currentScore) {
|
||||
actions = new LinkedList<Ability>(root.abilities);
|
||||
combat = root.combat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,8 +182,11 @@ public class ComputerPlayer5 extends ComputerPlayer4 implements Player {
|
|||
addActionsTimed(new FilterAbility());
|
||||
if (root.children.size() > 0) {
|
||||
root = root.children.get(0);
|
||||
actions = new LinkedList<Ability>(root.abilities);
|
||||
combat = root.combat;
|
||||
int bestScore = GameStateEvaluator2.evaluate(playerId, root.getGame());
|
||||
if (bestScore > currentScore) {
|
||||
actions = new LinkedList<Ability>(root.abilities);
|
||||
combat = root.combat;
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
@ -197,8 +201,11 @@ public class ComputerPlayer5 extends ComputerPlayer4 implements Player {
|
|||
addActionsTimed(new FilterAbility());
|
||||
if (root.children.size() > 0) {
|
||||
root = root.children.get(0);
|
||||
actions = new LinkedList<Ability>(root.abilities);
|
||||
combat = root.combat;
|
||||
int bestScore = GameStateEvaluator2.evaluate(playerId, root.getGame());
|
||||
if (bestScore > currentScore) {
|
||||
actions = new LinkedList<Ability>(root.abilities);
|
||||
combat = root.combat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue