use of mage.abilities.StaticAbility in project mage by magefree.
the class ContinuousEffects method getApplicableRestrictionUntapNotMoreThanEffects.
public Map<RestrictionUntapNotMoreThanEffect, Set<Ability>> getApplicableRestrictionUntapNotMoreThanEffects(Player player, Game game) {
Map<RestrictionUntapNotMoreThanEffect, Set<Ability>> effects = new HashMap<>();
for (RestrictionUntapNotMoreThanEffect effect : restrictionUntapNotMoreThanEffects) {
Set<Ability> abilities = restrictionUntapNotMoreThanEffects.getAbility(effect.getId());
Set<Ability> applicableAbilities = new HashSet<>();
for (Ability ability : abilities) {
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null)) {
if (effect.applies(player, ability, game)) {
applicableAbilities.add(ability);
}
}
}
if (!applicableAbilities.isEmpty()) {
effects.put(effect, abilities);
}
}
return effects;
}
use of mage.abilities.StaticAbility in project mage by magefree.
the class TraceUtil method traceForPermanent.
private static void traceForPermanent(Game game, Permanent permanent, String uuid, ContinuousEffectsList<RestrictionEffect> restrictionEffects) {
for (RestrictionEffect effect : restrictionEffects) {
log.error(uuid + " effect=" + effect.toString() + " id=" + effect.getId());
for (Ability ability : restrictionEffects.getAbility(effect.getId())) {
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, permanent, null)) {
log.error(uuid + " ability=" + ability + ", applies_to_attacker=" + effect.applies(permanent, ability, game));
} else {
boolean usable = ability.isInUseableZone(game, permanent, null);
log.error(uuid + " instanceof StaticAbility: " + (ability instanceof StaticAbility) + ", ability=" + ability);
log.error(uuid + " usable zone: " + usable + ", ability=" + ability);
if (!usable) {
Zone zone = ability.getZone();
log.error(uuid + " zone: " + zone);
MageObject object = game.getObject(ability.getSourceId());
log.error(uuid + " object: " + object);
if (object != null) {
log.error(uuid + " contains ability: " + object.getAbilities().contains(ability));
}
Zone test = game.getState().getZone(ability.getSourceId());
log.error(uuid + " test_zone: " + test);
}
}
}
}
}
use of mage.abilities.StaticAbility in project mage by magefree.
the class ComputerPlayer6 method simulatePriority.
protected int simulatePriority(SimulationNode2 node, Game game, int depth, int alpha, int beta) {
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS && Thread.interrupted()) {
Thread.currentThread().interrupt();
logger.info("interrupted");
return GameStateEvaluator2.evaluate(playerId, game).getTotalScore();
}
node.setGameValue(game.getState().getValue(true).hashCode());
SimulatedPlayer2 currentPlayer = (SimulatedPlayer2) game.getPlayer(game.getPlayerList().get());
SimulationNode2 bestNode = null;
List<Ability> allActions = currentPlayer.simulatePriority(game);
optimize(game, allActions);
int startedScore = GameStateEvaluator2.evaluate(this.getId(), node.getGame()).getTotalScore();
if (logger.isInfoEnabled() && !allActions.isEmpty() && depth == maxDepth) {
logger.info(String.format("POSSIBLE ACTIONS for %s (%d, started score: %d)%s", getName(), allActions.size(), startedScore, (actions.isEmpty() ? "" : ":")));
for (int i = 0; i < allActions.size(); i++) {
logger.info(String.format("-> #%d (%s)", i + 1, allActions.get(i)));
}
}
int actionNumber = 0;
int bestValSubNodes = Integer.MIN_VALUE;
for (Ability action : allActions) {
actionNumber++;
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS && Thread.interrupted()) {
Thread.currentThread().interrupt();
logger.info("Sim Prio [" + depth + "] -- interrupted");
break;
}
Game sim = game.copy();
sim.setSimulation(true);
if (// for MorphAbility, etc
!(action instanceof StaticAbility) && sim.getPlayer(currentPlayer.getId()).activateAbility((ActivatedAbility) action.copy(), sim)) {
sim.applyEffects();
if (checkForRepeatedAction(sim, node, action, currentPlayer.getId())) {
logger.debug("Sim Prio [" + depth + "] -- repeated action: " + action);
continue;
}
if (!sim.checkIfGameIsOver() && (action.isUsesStack() || action instanceof PassAbility)) {
// skip priority for opponents before stack resolve
UUID nextPlayerId = sim.getPlayerList().get();
do {
sim.getPlayer(nextPlayerId).pass(game);
nextPlayerId = sim.getPlayerList().getNext();
} while (!Objects.equals(nextPlayerId, this.getId()));
}
SimulationNode2 newNode = new SimulationNode2(node, sim, action, depth, currentPlayer.getId());
sim.checkStateAndTriggered();
int actionScore;
if (action instanceof PassAbility && sim.getStack().isEmpty()) {
// no more next actions, it's a final score
actionScore = GameStateEvaluator2.evaluate(this.getId(), sim).getTotalScore();
} else {
// resolve current action and calc all next actions to find best score (return max possible score)
actionScore = addActions(newNode, depth - 1, alpha, beta);
}
logger.debug("Sim Prio " + BLANKS.substring(0, 2 + (maxDepth - depth) * 3) + '[' + depth + "]#" + actionNumber + " <" + actionScore + "> - (" + action + ") ");
// * node.score - rewrites to store max score (e.g. contains only final data)
if (logger.isInfoEnabled() && depth >= maxDepth) {
// show calculated actions and score
// example: Sim Prio [6] #1 <605> (Play Swamp)
int currentActionScore = GameStateEvaluator2.evaluate(this.getId(), newNode.getGame()).getTotalScore();
int diffCurrentAction = currentActionScore - startedScore;
int diffNextActions = actionScore - startedScore - diffCurrentAction;
logger.info(String.format("Sim Prio [%d] #%d <diff %s, %s> (%s)", depth, actionNumber, printDiffScore(diffCurrentAction), printDiffScore(diffNextActions), action + (action.isModal() ? " Mode = " + action.getModes().getMode().toString() : "") + listTargets(game, action.getTargets(), " (targeting %s)", "") + (logger.isTraceEnabled() ? " #" + newNode.hashCode() : "")));
// collect childs info (next actions chain)
SimulationNode2 logNode = newNode;
while (logNode.getChildren() != null && !logNode.getChildren().isEmpty()) {
logNode = logNode.getChildren().get(0);
if (logNode.getAbilities() != null && !logNode.getAbilities().isEmpty()) {
int logCurrentScore = GameStateEvaluator2.evaluate(this.getId(), logNode.getGame()).getTotalScore();
int logPrevScore = GameStateEvaluator2.evaluate(this.getId(), logNode.getParent().getGame()).getTotalScore();
logger.info(String.format("Sim Prio [%d] -> next action: [%d]%s <diff %s, %s>", depth, logNode.getDepth(), logNode.getAbilities().toString(), printDiffScore(logCurrentScore - logPrevScore), printDiffScore(actionScore - logCurrentScore)));
}
}
}
if (currentPlayer.getId().equals(playerId)) {
if (actionScore > bestValSubNodes) {
bestValSubNodes = actionScore;
}
if (depth == maxDepth && action instanceof PassAbility) {
// passivity penalty
actionScore = actionScore - PASSIVITY_PENALTY;
}
if (actionScore > alpha || (depth == maxDepth && actionScore == alpha && RandomUtil.nextBoolean())) {
// Adding random for equal value to get change sometimes
alpha = actionScore;
bestNode = newNode;
bestNode.setScore(actionScore);
if (!newNode.getChildren().isEmpty()) {
bestNode.setCombat(newNode.getChildren().get(0).getCombat());
}
if (depth == maxDepth) {
GameStateEvaluator2.PlayerEvaluateScore score = GameStateEvaluator2.evaluate(this.getId(), bestNode.game);
String scoreInfo = " [" + score.getPlayerInfoShort() + "-" + score.getOpponentInfoShort() + "]";
String abilitiesInfo = bestNode.getAbilities().stream().map(a -> a.toString() + listTargets(game, a.getTargets(), " (targeting %s)", "")).collect(Collectors.joining("; "));
logger.info("Sim Prio [" + depth + "] >> BEST action chain found <" + bestNode.getScore() + scoreInfo + "> " + abilitiesInfo);
node.children.clear();
node.children.add(bestNode);
node.setScore(bestNode.getScore());
}
}
// no need to check other actions
if (actionScore == GameStateEvaluator2.WIN_GAME_SCORE) {
logger.debug("Sim Prio -- win - break");
break;
}
} else {
if (actionScore < beta) {
beta = actionScore;
bestNode = newNode;
bestNode.setScore(actionScore);
if (!newNode.getChildren().isEmpty()) {
bestNode.setCombat(newNode.getChildren().get(0).getCombat());
}
}
// no need to check other actions
if (actionScore == GameStateEvaluator2.LOSE_GAME_SCORE) {
logger.debug("Sim Prio -- lose - break");
break;
}
}
if (alpha >= beta) {
break;
}
if (SimulationNode2.nodeCount > maxNodes) {
logger.debug("Sim Prio -- reached end-state");
break;
}
}
}
if (depth == maxDepth) {
logger.info("Sim Prio [" + depth + "] -- End for Max Depth -- Nodes calculated: " + SimulationNode2.nodeCount);
}
if (bestNode != null) {
node.children.clear();
node.children.add(bestNode);
node.setScore(bestNode.getScore());
if (logger.isTraceEnabled() && !bestNode.getAbilities().toString().equals("[Pass]")) {
logger.trace(new StringBuilder("Sim Prio [").append(depth).append("] -- Set after (depth=").append(depth).append(") <").append(bestNode.getScore()).append("> ").append(bestNode.getAbilities().toString()).toString());
}
}
if (currentPlayer.getId().equals(playerId)) {
return bestValSubNodes;
} else {
return beta;
}
}
Aggregations