diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index 7285900479..bcf008c3e0 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -54,6 +54,7 @@ import mage.game.turn.*; import mage.player.ai.ma.optimizers.TreeOptimizer; import mage.player.ai.ma.optimizers.impl.EquipOptimizer; import mage.player.ai.ma.optimizers.impl.LevelUpOptimizer; +import mage.player.ai.util.CombatUtil; import mage.players.Player; import mage.target.Target; import mage.target.TargetCard; @@ -126,7 +127,6 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements pass(); return false; case PRECOMBAT_MAIN: - case DECLARE_BLOCKERS: case POSTCOMBAT_MAIN: if (game.getActivePlayerId().equals(playerId)) { printOutState(game, playerId); @@ -140,22 +140,26 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements pass(); } return false; - case BEGIN_COMBAT: + case BEGIN_COMBAT: case FIRST_COMBAT_DAMAGE: case COMBAT_DAMAGE: case END_COMBAT: pass(); return false; - case DECLARE_ATTACKERS: - if (!game.getActivePlayerId().equals(playerId)) { - printOutState(game, playerId); - printOutState(game, game.getOpponents(playerId).iterator().next()); - if (actions.size() == 0) { - calculateActions(game); - } - act(game); + case DECLARE_ATTACKERS: + if (game.getActivePlayerId().equals(playerId)) { + declareAttackers(game, playerId); + pass(); + return true; + } else { + pass(); + } + return false; + case DECLARE_BLOCKERS: + if (!game.getActivePlayerId().equals(playerId)) { + declareBlockers(game, playerId); + pass(); return true; - //printOutState(game, playerId); } else { pass(); } @@ -729,51 +733,10 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements } if (!game.getStep().skipStep(game, game.getActivePlayerId())) { if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS) { - game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId)); - if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, activePlayerId, activePlayerId))) { - for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(activePlayerId)).addAttackers(game)) { - Game sim = game.copy(); - UUID defenderId = game.getOpponents(playerId).iterator().next(); - for (CombatGroup group: engagement.getGroups()) { - for (UUID attackerId: group.getAttackers()) { - sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim); - } - } - sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId)); - SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, activePlayerId); - logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare attakers"); - newNode.setCombat(sim.getCombat()); - node.children.add(newNode); - } - } - } - else if (game.getTurn().getStepType() == PhaseStep.DECLARE_BLOCKERS) { - game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId)); - if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, activePlayerId, activePlayerId))) { - for (UUID defenderId: game.getCombat().getDefenders()) { - //check if defender is being attacked - if (game.getCombat().isAttacked(defenderId, game)) { - for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(defenderId)).addBlockers(game)) { - Game sim = game.copy(); - for (CombatGroup group: engagement.getGroups()) { - List<UUID> blockers = new ArrayList<UUID>(); - blockers.addAll(group.getBlockers()); - for (UUID blockerId: blockers) { - group.addBlocker(blockerId, defenderId, sim); - } - blockers = null; - } - sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId)); - SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, defenderId); - logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare blockers"); - newNode.setCombat(sim.getCombat()); - node.children.add(newNode); - } - } - } - } - } - else { + declareAttackers(game, activePlayerId, node); + } else if (game.getTurn().getStepType() == PhaseStep.DECLARE_BLOCKERS) { + declareBlockers(game, activePlayerId, node); + } else { game.getStep().beginStep(game, activePlayerId); } if (game.getStep().getHasPriority()) @@ -786,7 +749,104 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements game.checkStateAndTriggered(); } - @Override + private void declareBlockers(Game game, UUID activePlayerId) { + game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId)); + if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, activePlayerId, activePlayerId))) { + + } + } + + private void declareBlockers(Game game, UUID activePlayerId, SimulationNode2 node) { + game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId)); + if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, activePlayerId, activePlayerId))) { + /*for (UUID defenderId: game.getCombat().getDefenders()) { + //check if defender is being attacked + if (game.getCombat().isAttacked(defenderId, game)) { + for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(defenderId)).addBlockers(game)) { + Game sim = game.copy(); + for (CombatGroup group: engagement.getGroups()) { + List<UUID> blockers = new ArrayList<UUID>(); + blockers.addAll(group.getBlockers()); + for (UUID blockerId: blockers) { + group.addBlocker(blockerId, defenderId, sim); + } + blockers = null; + } + sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId)); + SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, defenderId); + logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare blockers"); + newNode.setCombat(sim.getCombat()); + node.children.add(newNode); + } + } + }*/ + } + } + + /** + * Choose attackers based on static information. + * That means that AI won't look to the future as it was before, but just choose attackers based on current state + * of the game. This is worse, but at least it is easier to implement and won't lead to the case when AI doesn't + * do anything - neither attack nor block. + * + * @param game + * @param activePlayerId + */ + private void declareAttackers(Game game, UUID activePlayerId) { + game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId)); + if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, activePlayerId, activePlayerId))) { + + Player attackingPlayer = game.getPlayer(activePlayerId); + UUID defenderId = game.getOpponents(playerId).iterator().next(); + Player defender = game.getPlayer(defenderId); + + List<Permanent> attackersList = super.getAvailableAttackers(game); + if (attackersList.isEmpty()) { + return; + } + + List<Permanent> possibleBlockers = defender.getAvailableBlockers(game); + + List<Permanent> killers = CombatUtil.canKillOpponent(game, attackersList, possibleBlockers, defender); + if (!killers.isEmpty()) { + for (Permanent attacker : killers) { + attackingPlayer.declareAttacker(attacker.getId(), defenderId, game); + } + return; + } + + CombatUtil.handleExalted(); + + int aggressionRate = 5; + for (Permanent attacker : attackersList) { + if (aggressionRate == 5) { + attackingPlayer.declareAttacker(attacker.getId(), defenderId, game); + } + } + } + } + + private void declareAttackers(Game game, UUID activePlayerId, SimulationNode2 node) { + game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId)); + if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, activePlayerId, activePlayerId))) { + for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(activePlayerId)).addAttackers(game)) { + Game sim = game.copy(); + UUID defenderId = game.getOpponents(playerId).iterator().next(); + for (CombatGroup group: engagement.getGroups()) { + for (UUID attackerId: group.getAttackers()) { + sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim); + } + } + sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId)); + SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, activePlayerId); + logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare attakers"); + newNode.setCombat(sim.getCombat()); + node.children.add(newNode); + } + } + } + + @Override public void selectAttackers(Game game) { logger.debug("selectAttackers"); if (combat != null) { diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java index ea4fab6727..e58e904a03 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java @@ -29,22 +29,16 @@ package mage.player.ai; import mage.Constants.AbilityType; -import mage.Constants.PhaseStep; import mage.Constants.RangeOfInfluence; import mage.Constants.Zone; import mage.abilities.Ability; import mage.filter.FilterAbility; import mage.game.Game; -import mage.game.combat.Combat; -import mage.game.combat.CombatGroup; -import mage.game.events.GameEvent; import mage.game.turn.*; import mage.players.Player; import org.apache.log4j.Logger; import java.util.LinkedList; -import java.util.List; -import java.util.UUID; /** * @@ -243,24 +237,27 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { val = testScore; } else { - switch (game.getTurn().getStepType()) { + /*switch (game.getTurn().getStepType()) { case PRECOMBAT_MAIN: val = simulateCombat(game, node, depth-1, alpha, beta, false); break; case POSTCOMBAT_MAIN: - //val = simulateCounterAttack(game, node, depth-1, alpha, beta); - //break; + val = simulateCounterAttack(game, node, depth-1, alpha, beta); + break; default: val = GameStateEvaluator2.evaluate(playerId, game); break; - } + }*/ + val = GameStateEvaluator2.evaluate(playerId, game); } } else { - if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS) + val = GameStateEvaluator2.evaluate(playerId, game); + /*if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS) val = simulateBlockers(game, node, playerId, depth-1, alpha, beta, true); else val = GameStateEvaluator2.evaluate(playerId, game); + */ } } else if (node.getChildren().size() > 0) { @@ -278,7 +275,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { } - protected int simulateCombat(Game game, SimulationNode2 node, int depth, int alpha, int beta, boolean counter) { + /*protected int simulateCombat(Game game, SimulationNode2 node, int depth, int alpha, int beta, boolean counter) { Integer val = null; if (Thread.interrupted()) { Thread.currentThread().interrupt(); @@ -320,10 +317,10 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { if (logger.isDebugEnabled()) logger.debug("returning -- combat score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName()); return val; - } + }*/ - protected int simulateAttackers(Game game, SimulationNode2 node, UUID attackerId, int depth, int alpha, int beta, boolean counter) { + /*protected int simulateAttackers(Game game, SimulationNode2 node, UUID attackerId, int depth, int alpha, int beta, boolean counter) { if (Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); @@ -395,9 +392,9 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { if (logger.isDebugEnabled()) logger.debug("returning -- combat attacker score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName()); return val; - } + }*/ - protected int simulateBlockers(Game game, SimulationNode2 node, UUID defenderId, int depth, int alpha, int beta, boolean counter) { + /*protected int simulateBlockers(Game game, SimulationNode2 node, UUID defenderId, int depth, int alpha, int beta, boolean counter) { if (Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); @@ -474,9 +471,9 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { if (logger.isDebugEnabled()) logger.debug("returning -- combat blocker score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName()); return val; - } + }*/ - protected int simulateCounterAttack(Game game, SimulationNode2 node, int depth, int alpha, int beta) { + /*protected int simulateCounterAttack(Game game, SimulationNode2 node, int depth, int alpha, int beta) { if (Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); @@ -501,7 +498,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { if (val == null) val = GameStateEvaluator2.evaluate(playerId, game); return val; - } + }*/ protected void simulateStep(Game game, Step step) { if (Thread.interrupted()) { @@ -523,7 +520,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { } } - protected void finishCombat(Game game) { + /*protected void finishCombat(Game game) { if (Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); @@ -532,7 +529,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player { simulateStep(game, new FirstCombatDamageStep()); simulateStep(game, new CombatDamageStep()); simulateStep(game, new EndOfCombatStep()); - } + }*/ protected int simulatePostCombatMain(Game game, SimulationNode2 node, int depth, int alpha, int beta) { if (Thread.interrupted()) { diff --git a/Mage.Server/plugins/mage-deck-constructed.jar b/Mage.Server/plugins/mage-deck-constructed.jar index d16f3e6e70..b4187d4252 100644 Binary files a/Mage.Server/plugins/mage-deck-constructed.jar and b/Mage.Server/plugins/mage-deck-constructed.jar differ diff --git a/Mage.Server/plugins/mage-deck-limited.jar b/Mage.Server/plugins/mage-deck-limited.jar index bf7f1b451f..f3d31cedcf 100644 Binary files a/Mage.Server/plugins/mage-deck-limited.jar and b/Mage.Server/plugins/mage-deck-limited.jar differ diff --git a/Mage.Server/plugins/mage-game-freeforall.jar b/Mage.Server/plugins/mage-game-freeforall.jar index e389f718bf..a76dc6bc9a 100644 Binary files a/Mage.Server/plugins/mage-game-freeforall.jar and b/Mage.Server/plugins/mage-game-freeforall.jar differ diff --git a/Mage.Server/plugins/mage-game-twoplayerduel.jar b/Mage.Server/plugins/mage-game-twoplayerduel.jar index 21749d81c6..d2e4bf43d7 100644 Binary files a/Mage.Server/plugins/mage-game-twoplayerduel.jar and b/Mage.Server/plugins/mage-game-twoplayerduel.jar differ diff --git a/Mage.Server/plugins/mage-player-ai-ma.jar b/Mage.Server/plugins/mage-player-ai-ma.jar index d8b70d9a0d..945d5c01a8 100644 Binary files a/Mage.Server/plugins/mage-player-ai-ma.jar and b/Mage.Server/plugins/mage-player-ai-ma.jar differ diff --git a/Mage.Server/plugins/mage-player-ai.jar b/Mage.Server/plugins/mage-player-ai.jar index 2041685d8e..1d70e58a1a 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-aimcts.jar b/Mage.Server/plugins/mage-player-aimcts.jar index d8845a2f6e..2b98a089e8 100644 Binary files a/Mage.Server/plugins/mage-player-aimcts.jar and b/Mage.Server/plugins/mage-player-aimcts.jar differ diff --git a/Mage.Server/plugins/mage-player-aiminimax.jar b/Mage.Server/plugins/mage-player-aiminimax.jar index 7cfdbe3e82..6a549940d3 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.Server/plugins/mage-player-human.jar b/Mage.Server/plugins/mage-player-human.jar index 9d56fb86dc..debc252881 100644 Binary files a/Mage.Server/plugins/mage-player-human.jar and b/Mage.Server/plugins/mage-player-human.jar differ diff --git a/Mage.Server/plugins/mage-tournament-booster-draft.jar b/Mage.Server/plugins/mage-tournament-booster-draft.jar index 9778a8e02e..8dc8698c65 100644 Binary files a/Mage.Server/plugins/mage-tournament-booster-draft.jar and b/Mage.Server/plugins/mage-tournament-booster-draft.jar differ diff --git a/Mage.Server/plugins/mage-tournament-sealed.jar b/Mage.Server/plugins/mage-tournament-sealed.jar index 8b82b5d80e..f6e2927582 100644 Binary files a/Mage.Server/plugins/mage-tournament-sealed.jar and b/Mage.Server/plugins/mage-tournament-sealed.jar differ