@Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { preventDamageAction(event, source, game); Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { boolean removeCounter = true; // check if in the same combat damage step already a counter was removed if (game.getTurn().getPhase().getStep().getType().equals(PhaseStep.COMBAT_DAMAGE)) { if (game.getTurnNum() == turn && game.getTurn().getStep().equals(combatPhaseStep)) { removeCounter = false; } else { turn = game.getTurnNum(); combatPhaseStep = game.getTurn().getStep(); } } if (removeCounter && permanent.getCounters().getCount(CounterType.P1P1) > 0) { StringBuilder sb = new StringBuilder(permanent.getName()).append(": "); permanent.removeCounters(CounterType.P1P1.createInstance(), game); sb.append("Removed a +1/+1 counter "); game.informPlayers(sb.toString()); } } return false; }
protected void simulateToEnd(Game game) { if (ALLOW_INTERRUPT && Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); return; } if (!game.gameOver(null)) { game.getTurn().getPhase().endPhase(game, game.getActivePlayerId()); game.getTurn().setPhase(new EndPhase()); if (game.getTurn().getPhase().beginPhase(game, game.getActivePlayerId())) { simulateStep(game, new EndStep()); simulateStep(game, new CleanupStep()); } } }
@Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getSourceId().equals(source.getSourceId())) { return !TurnPhase.COMBAT.equals(game.getTurn().getPhaseType()) || game.getStep().getType().equals(PhaseStep.DECLARE_BLOCKERS) || game.getStep().getType().equals(PhaseStep.FIRST_COMBAT_DAMAGE) || game.getStep().getType().equals(PhaseStep.COMBAT_DAMAGE) || game.getStep().getType().equals(PhaseStep.END_COMBAT); } return false; }
protected int simulatePostCombatMain( Game game, SimulationNode2 node, int depth, int alpha, int beta) { if (ALLOW_INTERRUPT && Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); return GameStateEvaluator2.evaluate(playerId, game); } logger.debug("Sim [" + depth + "] -- post combat main"); game.getTurn().setPhase(new PostCombatMainPhase()); if (game.getPhase().beginPhase(game, game.getActivePlayerId())) { game.getPhase().setStep(new PostCombatMainStep()); game.getStep().beginStep(game, playerId); game.getPlayers().resetPassed(); return addActions(node, depth, alpha, beta); } // return simulateCounterAttack(game, node, depth, alpha, beta); return GameStateEvaluator2.evaluate(playerId, game); }
private boolean priorityPlay(Game game) { if (lastLoggedTurn != game.getTurnNum()) { lastLoggedTurn = game.getTurnNum(); logger.info( "======================= Turn: " + game.getTurnNum() + " [" + game.getPlayer(game.getActivePlayerId()).getName() + "] ========================================="); } logState(game); logger.debug( "Priority -- Step: " + (game.getTurn().getStepType() + " ").substring(0, 25) + " ActivePlayer-" + game.getPlayer(game.getActivePlayerId()).getName() + " PriorityPlayer-" + name); game.getState().setPriorityPlayerId(playerId); game.firePriorityEvent(playerId); switch (game.getTurn().getStepType()) { case UPKEEP: case DRAW: pass(game); return false; case PRECOMBAT_MAIN: if (game.getActivePlayerId().equals(playerId)) { printOutState(game); if (actions.size() == 0) { logger.info( "Sim Calculate pre combat actions ----------------------------------------------------- "); calculatePreCombatActions(game); } act(game); return true; } else { pass(game); } return false; case BEGIN_COMBAT: pass(game); return false; case DECLARE_ATTACKERS: if (!game.getActivePlayerId().equals(playerId)) { printOutState(game); if (actions.size() == 0) { logger.info( "Sim Calculate declare attackers actions ----------------------------------------------------- "); calculatePreCombatActions(game); } act(game); return true; } else { pass(game); } return false; case DECLARE_BLOCKERS: case FIRST_COMBAT_DAMAGE: case COMBAT_DAMAGE: case END_COMBAT: pass(game); return false; case POSTCOMBAT_MAIN: // if (game.getActivePlayerId().equals(playerId)) { printOutState(game); if (actions.size() == 0) { calculatePostCombatActions(game); } act(game); return true; // } // else { // pass(game); // } // return false; case END_TURN: case CLEANUP: actionCache.clear(); pass(game); return false; } return false; }
protected int simulateCombat( Game game, SimulationNode2 node, int depth, int alpha, int beta, boolean counter) { Integer val = null; if (ALLOW_INTERRUPT && Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); return GameStateEvaluator2.evaluate(playerId, game); } if (game.getTurn().getStepType() != PhaseStep.DECLARE_BLOCKERS) { game.getTurn().setPhase(new CombatPhase()); if (game.getPhase().beginPhase(game, game.getActivePlayerId())) { simulateStep(game, new BeginCombatStep()); game.getPhase().setStep(new DeclareAttackersStep()); if (!game.getStep().skipStep(game, game.getActivePlayerId())) { game.fireEvent( new GameEvent( GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, game.getActivePlayerId())); if (!game.replaceEvent( GameEvent.getEvent( GameEvent.EventType.DECLARING_ATTACKERS, game.getActivePlayerId(), game.getActivePlayerId()))) { val = simulateAttackers( game, node, game.getActivePlayerId(), depth, alpha, beta, counter); } } else if (!counter) { simulateToEnd(game); val = simulatePostCombatMain(game, node, depth, alpha, beta); } } } else { if (!game.getStep().skipStep(game, game.getActivePlayerId())) { game.fireEvent( new GameEvent( GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, game.getActivePlayerId())); if (!game.replaceEvent( GameEvent.getEvent( GameEvent.EventType.DECLARING_BLOCKERS, game.getActivePlayerId(), game.getActivePlayerId()))) { // only suitable for two player games - only simulates blocks for 1st defender val = simulateBlockers( game, node, game.getCombat().getDefenders().iterator().next(), depth, alpha, beta, counter); } } else if (!counter) { finishCombat(game); /// val = simulateCounterAttack(game, node, depth, alpha, beta); } } if (val == null) { val = GameStateEvaluator2.evaluate(playerId, game); } if (logger.isDebugEnabled()) { logger.debug( "returning -- combat score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName()); } return val; }
@Override protected int addActions(SimulationNode2 node, int depth, int alpha, int beta) { boolean stepFinished = false; int val; if (logger.isTraceEnabled() && node != null && node.getAbilities() != null && !node.getAbilities().toString().equals("[Pass]")) { logger.trace( "Add Action [" + depth + "] " + node.getAbilities().toString() + " a: " + alpha + " b: " + beta); } Game game = node.getGame(); if (ALLOW_INTERRUPT && Thread.interrupted()) { Thread.currentThread().interrupt(); logger.debug("interrupted"); return GameStateEvaluator2.evaluate(playerId, game); } // Condition to stop deeper simulation if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.gameOver(null)) { val = GameStateEvaluator2.evaluate(playerId, game); if (logger.isTraceEnabled()) { StringBuilder sb = new StringBuilder("Add Actions -- reached end state <").append(val).append(">"); SimulationNode2 logNode = node; do { sb.append( new StringBuilder( " <- [" + logNode.getDepth() + "]" + (logNode.getAbilities() != null ? logNode.getAbilities().toString() : "[empty]"))); logNode = logNode.getParent(); } while ((logNode.getParent() != null)); logger.trace(sb); } } else if (node.getChildren().size() > 0) { if (logger.isDebugEnabled()) { StringBuilder sb = new StringBuilder("Add Action [") .append(depth) .append("] -- something added children ") .append(node.getAbilities() != null ? node.getAbilities().toString() : "null") .append(" added children: ") .append(node.getChildren().size()) .append(" ("); for (SimulationNode2 logNode : node.getChildren()) { sb.append(logNode.getAbilities() != null ? logNode.getAbilities().toString() : "null") .append(", "); } sb.append(")"); logger.debug(sb); } val = minimaxAB(node, depth - 1, alpha, beta); } else { logger.trace( "Add Action -- alpha: " + alpha + " beta: " + beta + " depth:" + depth + " step:" + game.getTurn().getStepType() + " for player:" + game.getPlayer(game.getPlayerList().get()).getName()); if (allPassed(game)) { if (!game.getStack().isEmpty()) { resolve(node, depth, game); } else { stepFinished = true; } } if (game.gameOver(null)) { val = GameStateEvaluator2.evaluate(playerId, game); } else if (stepFinished) { logger.debug("Step finished"); int testScore = GameStateEvaluator2.evaluate(playerId, game); if (game.getActivePlayerId().equals(playerId)) { if (testScore < currentScore) { // if score at end of step is worse than original score don't check further // logger.debug("Add Action -- abandoning check, no immediate benefit"); val = testScore; } else { /*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; default: val = GameStateEvaluator2.evaluate(playerId, game); break; }*/ val = GameStateEvaluator2.evaluate(playerId, game); } } else { 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) { if (logger.isDebugEnabled()) { StringBuilder sb = new StringBuilder("Add Action [") .append(depth) .append("] -- trigger ") .append(node.getAbilities() != null ? node.getAbilities().toString() : "null") .append(" added children: ") .append(node.getChildren().size()) .append(" ("); for (SimulationNode2 logNode : node.getChildren()) { sb.append(logNode.getAbilities() != null ? logNode.getAbilities().toString() : "null") .append(", "); } sb.append(")"); logger.debug(sb); } val = minimaxAB(node, depth, alpha, beta); } else { val = simulatePriority(node, game, depth, alpha, beta); } } node.setScore(val); // test logger.trace( "returning -- score: " + val + " depth:" + depth + " step:" + game.getTurn().getStepType() + " for player:" + game.getPlayer(node.getPlayerId()).getName()); return val; }