diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java index ac1a85b247c..8c5334a855c 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java @@ -218,6 +218,7 @@ public class ComputerPlayer2 extends ComputerPlayer implements protected int minimaxAB(SimulationNode node, FilterAbility filter, int depth, int alpha, int beta) { UUID currentPlayerId = node.getGame().getPlayerList().get(); SimulationNode bestChild = null; + boolean isSimulatedPlayer = currentPlayerId.equals(playerId); for (SimulationNode child: node.getChildren()) { if (alpha >= beta) { logger.debug("alpha beta pruning"); @@ -228,27 +229,33 @@ public class ComputerPlayer2 extends ComputerPlayer implements break; } int val = addActions(child, filter, depth-1, alpha, beta); - if (!currentPlayerId.equals(playerId)) { + if (!isSimulatedPlayer) { if (val < beta) { beta = val; bestChild = child; -// if (node.getCombat() == null) - node.setCombat(child.getCombat()); + node.setCombat(child.getCombat()); + } + if (val == GameStateEvaluator.LOSE_SCORE) { + logger.debug("simulating -- lose, can't do worse than this"); + break; } } else { if (val > alpha) { alpha = val; bestChild = child; -// if (node.getCombat() == null) - node.setCombat(child.getCombat()); + node.setCombat(child.getCombat()); + } + if (val == GameStateEvaluator.WIN_SCORE) { + logger.debug("simulating -- win, can't do better than this"); + break; } } } node.children.clear(); if (bestChild != null) node.children.add(bestChild); - if (!currentPlayerId.equals(playerId)) { + if (!isSimulatedPlayer) { logger.debug("returning minimax beta: " + beta); return beta; } @@ -380,6 +387,7 @@ public class ComputerPlayer2 extends ComputerPlayer implements } node.setGameValue(game.getState().getValue()); SimulatedPlayer currentPlayer = (SimulatedPlayer) game.getPlayer(game.getPlayerList().get()); + boolean isSimulatedPlayer = currentPlayer.getId().equals(playerId); logger.debug("simulating -- player " + currentPlayer.getName()); SimulationNode bestNode = null; List allActions = currentPlayer.simulatePriority(game, filter); @@ -401,12 +409,16 @@ public class ComputerPlayer2 extends ComputerPlayer implements logger.debug("simulating -- node #:" + SimulationNode.getCount() + " actions:" + action); sim.checkStateAndTriggered(); int val = addActions(newNode, filter, depth-1, alpha, beta); - if (!currentPlayer.getId().equals(playerId)) { + if (!isSimulatedPlayer) { if (val < beta) { beta = val; bestNode = newNode; node.setCombat(newNode.getCombat()); } + if (val == GameStateEvaluator.LOSE_SCORE) { + logger.debug("simulating -- lose, can't do worse than this"); + break; + } } else { if (val > alpha) { @@ -418,6 +430,10 @@ public class ComputerPlayer2 extends ComputerPlayer implements if (node.getChoices().size() > 0) choices = node.getChoices(); } + if (val == GameStateEvaluator.WIN_SCORE) { + logger.debug("simulating -- win, can't do better than this"); + break; + } } if (alpha >= beta) { logger.debug("simulating -- pruning"); @@ -433,7 +449,7 @@ public class ComputerPlayer2 extends ComputerPlayer implements node.children.clear(); node.children.add(bestNode); } - if (!currentPlayer.getId().equals(playerId)) { + if (!isSimulatedPlayer) { logger.debug("returning priority beta: " + beta); return beta; } diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java index 67ec0288cb8..ec2291780d3 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java @@ -298,7 +298,6 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { } else if (!counter) { finishCombat(game); -// val = GameStateEvaluator.evaluate(playerId, game); val = simulateCounterAttack(game, node, depth, alpha, beta); } } diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java index 8d9044bc46b..eb31cf6f044 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java @@ -59,14 +59,17 @@ public class GameStateEvaluator { private static final int CREATURE_FACTOR = Config.evaluatorCreatureFactor; private static final int HAND_FACTOR = Config.evaluatorHandFactor; + public static final int WIN_SCORE = Integer.MAX_VALUE - 1; + public static final int LOSE_SCORE = Integer.MIN_VALUE + 1; + public static int evaluate(UUID playerId, Game game) { Player player = game.getPlayer(playerId); Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next()); if (game.isGameOver()) { if (player.hasLost() || opponent.hasWon()) - return Integer.MIN_VALUE + 1; + return LOSE_SCORE; if (opponent.hasLost() || player.hasWon()) - return Integer.MAX_VALUE - 1; + return WIN_SCORE; } int lifeScore = (player.getLife() - opponent.getLife()) * LIFE_FACTOR; int permanentScore = 0; diff --git a/Mage.Server/plugins/mage-player-ai.jar b/Mage.Server/plugins/mage-player-ai.jar index 1fa918fa871..913840835f5 100644 Binary files a/Mage.Server/plugins/mage-player-ai.jar and b/Mage.Server/plugins/mage-player-ai.jar differ diff --git a/Mage.Server/plugins/mage-player-aiminimax.jar b/Mage.Server/plugins/mage-player-aiminimax.jar index a436a53d198..59a6eda05fe 100644 Binary files a/Mage.Server/plugins/mage-player-aiminimax.jar and b/Mage.Server/plugins/mage-player-aiminimax.jar differ diff --git a/Mage.Tests/plugins/mage-player-aiminimax.jar b/Mage.Tests/plugins/mage-player-aiminimax.jar index d37d42fcc63..59a6eda05fe 100644 Binary files a/Mage.Tests/plugins/mage-player-aiminimax.jar and b/Mage.Tests/plugins/mage-player-aiminimax.jar differ