protected int simulateBlockers( Game game, SimulationNode2 node, UUID defenderId, int depth, int alpha, int beta, boolean counter) { if (ALLOW_INTERRUPT && Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); return GameStateEvaluator2.evaluate(playerId, game); } Integer val = null; SimulationNode2 bestNode = null; // check if defender is being attacked if (game.getCombat().isAttacked(defenderId, game)) { SimulatedPlayer2 defender = (SimulatedPlayer2) game.getPlayer(defenderId); if (logger.isDebugEnabled()) { logger.debug( defender.getName() + "'s possible blockers: " + defender.getAvailableBlockers(game)); } List<Combat> combats = defender.addBlockers(game); for (Combat engagement : combats) { if (alpha >= beta) { logger.debug("Sim blockers -- pruning blockers"); break; } Game sim = game.copy(); for (CombatGroup group : engagement.getGroups()) { if (group.getAttackers().size() > 0) { UUID attackerId = group.getAttackers().get(0); for (UUID blockerId : group.getBlockers()) { sim.getPlayer(defenderId).declareBlocker(defenderId, blockerId, attackerId, sim); } } } sim.fireEvent( GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId)); SimulationNode2 newNode = new SimulationNode2(node, sim, depth, defenderId); if (logger.isDebugEnabled()) { logger.debug("Sim block for player:" + game.getPlayer(defenderId).getName()); } sim.checkStateAndTriggered(); while (!sim.getStack().isEmpty()) { sim.getStack().resolve(sim); logger.debug("Sim blockers: resolving triggered abilities"); sim.applyEffects(); } sim.fireEvent( GameEvent.getEvent( GameEvent.EventType.DECLARE_BLOCKERS_STEP_POST, sim.getActivePlayerId(), sim.getActivePlayerId())); Combat simCombat = sim.getCombat().copy(); finishCombat(sim); if (sim.gameOver(null)) { val = GameStateEvaluator2.evaluate(playerId, sim); } else if (!counter) { val = simulatePostCombatMain(sim, newNode, depth - 1, alpha, beta); } else { val = GameStateEvaluator2.evaluate(playerId, sim); } if (!defenderId.equals(playerId)) { if (val < beta) { beta = val; bestNode = newNode; bestNode.setScore(val); bestNode.setCombat(simCombat); } } else { if (val > alpha) { alpha = val; bestNode = newNode; bestNode.setScore(val); bestNode.setCombat(simCombat); } } } } if (val == null) { val = GameStateEvaluator2.evaluate(playerId, game); } if (bestNode != null) { node.children.clear(); node.children.add(bestNode); node.setScore(bestNode.getScore()); } if (logger.isDebugEnabled()) { logger.debug( "Sim blockers: returning 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) { if (ALLOW_INTERRUPT && Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); return GameStateEvaluator2.evaluate(playerId, game); } Integer val = null; SimulationNode2 bestNode = null; SimulatedPlayer2 attacker = (SimulatedPlayer2) game.getPlayer(attackerId); UUID defenderId = game.getOpponents(attackerId).iterator().next(); if (logger.isDebugEnabled()) { logger.debug( attacker.getName() + "'s possible attackers: " + attacker.getAvailableAttackers(defenderId, game)); } for (Combat engagement : attacker.addAttackers(game)) { if (logger.isDebugEnabled()) { logger.debug( "Sim Attackers: " + engagement.getAttackers() + ", blockers: " + engagement.getBlockers()); } if (alpha >= beta) { logger.debug("Sim Attackers -- pruning attackers"); break; } Game sim = game.copy(); for (CombatGroup group : engagement.getGroups()) { for (UUID attackId : group.getAttackers()) { sim.getPlayer(attackerId).declareAttacker(attackId, defenderId, sim, false); } } sim.fireEvent( GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, attackerId, attackerId)); SimulationNode2 newNode = new SimulationNode2(node, sim, depth, attackerId); if (logger.isDebugEnabled()) { logger.debug("Sim attack for player:" + game.getPlayer(attackerId).getName()); } sim.checkStateAndTriggered(); while (!sim.getStack().isEmpty()) { sim.getStack().resolve(sim); logger.debug("Sim attack: resolving triggered abilities"); sim.applyEffects(); } sim.fireEvent( GameEvent.getEvent( GameEvent.EventType.DECLARE_ATTACKERS_STEP_POST, sim.getActivePlayerId(), sim.getActivePlayerId())); Combat simCombat = sim.getCombat().copy(); sim.getPhase().setStep(new DeclareBlockersStep()); val = simulateCombat(sim, newNode, depth - 1, alpha, beta, counter); if (!attackerId.equals(playerId)) { if (val < beta) { beta = val; bestNode = newNode; bestNode.setScore(val); if (newNode.getChildren().size() > 0) { bestNode.setCombat(newNode.getChildren().get(0).getCombat()); } } } else { if (val > alpha) { alpha = val; bestNode = newNode; bestNode.setScore(val); if (newNode.getChildren().size() > 0) { bestNode.setCombat(newNode.getChildren().get(0).getCombat()); } } } } if (val == null) { val = GameStateEvaluator2.evaluate(playerId, game); } if (bestNode != null) { node.children.clear(); node.children.add(bestNode); node.setScore(bestNode.getScore()); } if (logger.isDebugEnabled()) { logger.debug( "Sim attackers: returning score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName()); } return val; }