@Override public void selectBlockers(Game game, UUID defendingPlayerId) { int numGroups = game.getCombat().getGroups().size(); if (numGroups == 0) return; List<Permanent> blockers = getAvailableBlockers(game); for (Permanent blocker : blockers) { int check = rnd.nextInt(numGroups + 1); if (check < numGroups) { CombatGroup group = game.getCombat().getGroups().get(check); if (group.getAttackers().size() > 0) this.declareBlocker(blocker.getId(), group.getAttackers().get(0), game); } } actionCount++; }
@Override public boolean apply(Permanent input, Game game) { for (CombatGroup combatGroup : game.getCombat().getGroups()) { if (combatGroup.getBlockers().contains(input.getId()) && combatGroup.getAttackers().contains(attackerId)) { return true; } } return false; }
public String getValue(boolean useHidden) { StringBuilder sb = new StringBuilder(1024); sb.append(turnNum) .append(turn.getPhaseType()) .append(turn.getStepType()) .append(activePlayerId) .append(priorityPlayerId); for (Player player : players.values()) { sb.append("player").append(player.getLife()).append("hand"); if (useHidden) { sb.append(player.getHand()); } else { sb.append(player.getHand().size()); } sb.append("library") .append(player.getLibrary().size()) .append("graveyard") .append(player.getGraveyard()); } sb.append("permanents"); for (Permanent permanent : battlefield.getAllPermanents()) { sb.append(permanent.getValue()); } sb.append("spells"); for (StackObject spell : stack) { sb.append(spell.getControllerId()).append(spell.getName()); } for (ExileZone zone : exile.getExileZones()) { sb.append("exile").append(zone.getName()).append(zone); } sb.append("combat"); for (CombatGroup group : combat.getGroups()) { sb.append(group.getDefenderId()).append(group.getAttackers()).append(group.getBlockers()); } return sb.toString(); }
public static CombatSimulator load(Game game) { CombatSimulator simCombat = new CombatSimulator(); for (CombatGroup group : game.getCombat().getGroups()) { simCombat.groups.add( new CombatGroupSimulator( group.getDefenderId(), group.getAttackers(), group.getBlockers(), game)); } for (UUID defenderId : game.getCombat().getDefenders()) { simCombat.defenders.add(defenderId); Player player = game.getPlayer(defenderId); if (player != null) { simCombat.playersLife.put(defenderId, player.getLife()); } else { Permanent permanent = game.getPermanent(defenderId); simCombat.planeswalkerLoyalty.put( defenderId, permanent.getCounters(game).getCount(CounterType.LOYALTY)); } } return simCombat; }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Set<UUID> toSacrifice = new HashSet<UUID>(); if (controller.flipCoin(game)) { // each blocking creature is sacrificed by its controller for (CombatGroup combatGroup : game.getCombat().getGroups()) { for (UUID blockerId : combatGroup.getBlockers()) { toSacrifice.add(blockerId); } } } else { // each blocked creature is sacrificed by its controller for (CombatGroup combatGroup : game.getCombat().getGroups()) { if (!combatGroup.getBlockers().isEmpty()) { for (UUID attackerId : combatGroup.getAttackers()) { toSacrifice.add(attackerId); } } } } for (UUID creatureId : toSacrifice) { Permanent creature = game.getPermanent(creatureId); if (creature != null) { creature.sacrifice(source.getSourceId(), game); Player player = game.getPlayer(creature.getControllerId()); if (player != null) { game.informPlayers( new StringBuilder(player.getName()) .append(" sacrifices ") .append(creature.getName()) .toString()); } } } return true; } return false; }
@Override public boolean canBeBlockedCheckAfter(Permanent attacker, Ability source, Game game) { for (CombatGroup combatGroup : game.getCombat().getGroups()) { if (combatGroup.getAttackers().contains(source.getSourceId())) { for (UUID blockerId : combatGroup.getBlockers()) { Permanent blockingCreature = game.getPermanent(blockerId); if (blockingCreature != null) { for (Permanent permanent : game.getBattlefield() .getAllActivePermanents( new FilterCreaturePermanent(), blockingCreature.getControllerId(), game)) { if (!combatGroup.getBlockers().contains(permanent.getId())) { // not all creatures block Tromokratis return false; } } } } } } return true; }
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; }
public String getValue(boolean useHidden, Game game) { StringBuilder sb = new StringBuilder(1024); sb.append(turnNum) .append(turn.getPhaseType()) .append(turn.getStepType()) .append(activePlayerId) .append(priorityPlayerId); for (Player player : players.values()) { sb.append("player").append(player.isPassed()).append(player.getLife()).append("hand"); if (useHidden) { sb.append(player.getHand()); } else { sb.append(player.getHand().size()); } sb.append("library").append(player.getLibrary().size()); sb.append("graveyard"); for (Card card : player.getGraveyard().getCards(game)) { sb.append(card.getName()); } } sb.append("permanents"); List<String> perms = new ArrayList<String>(); for (Permanent permanent : battlefield.getAllPermanents()) { perms.add(permanent.getValue()); } Collections.sort(perms); sb.append(perms); sb.append("spells"); for (StackObject spell : stack) { sb.append(spell.getControllerId()).append(spell.getName()); sb.append(spell.getStackAbility().toString()); for (Mode mode : spell.getStackAbility().getModes().values()) { if (!mode.getTargets().isEmpty()) { sb.append("targets"); for (Target target : mode.getTargets()) { sb.append(target.getTargets()); } } if (!mode.getChoices().isEmpty()) { sb.append("choices"); for (Choice choice : mode.getChoices()) { sb.append(choice.getChoice()); } } } } for (ExileZone zone : exile.getExileZones()) { sb.append("exile").append(zone.getName()).append(zone); } sb.append("combat"); for (CombatGroup group : combat.getGroups()) { sb.append(group.getDefenderId()).append(group.getAttackers()).append(group.getBlockers()); } return sb.toString(); }