Search in sources :

Example 6 with PassAbility

use of mage.abilities.common.PassAbility in project mage by magefree.

the class ComputerPlayerMCTS method priority.

@Override
public boolean priority(Game game) {
    if (game.getStep().getType() == PhaseStep.UPKEEP) {
        if (!lastPhase.equals(game.getTurn().getValue(game.getTurnNum()))) {
            logList(game.getTurn().getValue(game.getTurnNum()) + name + " hand: ", new ArrayList(hand.getCards(game)));
            lastPhase = game.getTurn().getValue(game.getTurnNum());
            if (MCTSNode.USE_ACTION_CACHE) {
                int count = MCTSNode.cleanupCache(game.getTurnNum());
                if (count > 0)
                    logger.info("Removed " + count + " cache entries");
            }
        }
    }
    game.getState().setPriorityPlayerId(playerId);
    game.firePriorityEvent(playerId);
    getNextAction(game, NextAction.PRIORITY);
    Ability ability = root.getAction();
    if (ability == null)
        logger.fatal("null ability");
    activateAbility((ActivatedAbility) ability, game);
    if (ability instanceof PassAbility)
        return false;
    logLife(game);
    logger.info("choose action:" + root.getAction() + " success ratio: " + root.getWinRatio());
    return true;
}
Also used : PassAbility(mage.abilities.common.PassAbility) ActivatedAbility(mage.abilities.ActivatedAbility) Ability(mage.abilities.Ability) PassAbility(mage.abilities.common.PassAbility) ArrayList(java.util.ArrayList)

Example 7 with PassAbility

use of mage.abilities.common.PassAbility in project mage by magefree.

the class SimulatedPlayerMCTS method priority.

@Override
public boolean priority(Game game) {
    // logger.info("priority");
    boolean didSomething = false;
    Ability ability = getAction(game);
    // logger.info("simulate " + ability.toString());
    if (!(ability instanceof PassAbility)) {
        didSomething = true;
    }
    activateAbility((ActivatedAbility) ability, game);
    actionCount++;
    return didSomething;
}
Also used : PassAbility(mage.abilities.common.PassAbility) StackAbility(mage.game.stack.StackAbility) PassAbility(mage.abilities.common.PassAbility)

Example 8 with PassAbility

use of mage.abilities.common.PassAbility in project mage by magefree.

the class ComputerPlayer2 method checkForUselessAction.

/**
 * resolve current ability on the stack if there is one, then
 * check if current game state is the same as the previous, if so then
 * action has no effect and is not useful
 *
 * @param sim
 * @param node
 * @param action
 * @param playerId
 * @return
 */
private boolean checkForUselessAction(Game sim, SimulationNode node, Ability action, UUID playerId) {
    int currentVal = 0;
    int prevVal = 0;
    if (action instanceof PassAbility)
        return false;
    SimulationNode test = node.getParent();
    if (test == null)
        return false;
    if (action.isUsesStack()) {
        Game testSim = sim.copy();
        StackObject ability = testSim.getStack().pop();
        ability.resolve(testSim);
        testSim.applyEffects();
        currentVal = GameStateEvaluator.evaluate(playerId, testSim, true);
    } else {
        currentVal = GameStateEvaluator.evaluate(playerId, sim, true);
    }
    prevVal = GameStateEvaluator.evaluate(playerId, test.getGame(), true);
    return currentVal == prevVal;
}
Also used : PassAbility(mage.abilities.common.PassAbility) Game(mage.game.Game) StackObject(mage.game.stack.StackObject)

Example 9 with PassAbility

use of mage.abilities.common.PassAbility 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;
    }
}
Also used : StaticAbility(mage.abilities.StaticAbility) ActivatedAbility(mage.abilities.ActivatedAbility) PassAbility(mage.abilities.common.PassAbility) StackAbility(mage.game.stack.StackAbility) SpellAbility(mage.abilities.SpellAbility) Ability(mage.abilities.Ability) Target(mage.target.Target) TreeOptimizer(mage.player.ai.ma.optimizers.TreeOptimizer) java.util(java.util) Combat(mage.game.combat.Combat) DiscardCardOptimizer(mage.player.ai.ma.optimizers.impl.DiscardCardOptimizer) RangeOfInfluence(mage.constants.RangeOfInfluence) StaticAbility(mage.abilities.StaticAbility) Player(mage.players.Player) LevelUpOptimizer(mage.player.ai.ma.optimizers.impl.LevelUpOptimizer) CombatInfo(mage.player.ai.util.CombatInfo) Logger(org.apache.log4j.Logger) AbilityType(mage.constants.AbilityType) TargetCard(mage.target.TargetCard) MageObject(mage.MageObject) StackObject(mage.game.stack.StackObject) ActivatedAbility(mage.abilities.ActivatedAbility) Card(mage.cards.Card) RandomUtil(mage.util.RandomUtil) Choice(mage.choices.Choice) StaticFilters(mage.filter.StaticFilters) CombatUtil(mage.player.ai.util.CombatUtil) Targets(mage.target.Targets) SearchEffect(mage.abilities.effects.SearchEffect) mage.abilities.keyword(mage.abilities.keyword) PassAbility(mage.abilities.common.PassAbility) java.util.concurrent(java.util.concurrent) Cards(mage.cards.Cards) Outcome(mage.constants.Outcome) StackAbility(mage.game.stack.StackAbility) Collectors(java.util.stream.Collectors) File(java.io.File) SpellAbility(mage.abilities.SpellAbility) Game(mage.game.Game) Effect(mage.abilities.effects.Effect) GameEvent(mage.game.events.GameEvent) Permanent(mage.game.permanent.Permanent) OutcomeOptimizer(mage.player.ai.ma.optimizers.impl.OutcomeOptimizer) TargetAmount(mage.target.TargetAmount) EquipOptimizer(mage.player.ai.ma.optimizers.impl.EquipOptimizer) CounterType(mage.counters.CounterType) Ability(mage.abilities.Ability) PassAbility(mage.abilities.common.PassAbility) StaticAbility(mage.abilities.StaticAbility) ActivatedAbility(mage.abilities.ActivatedAbility) Game(mage.game.Game)

Aggregations

PassAbility (mage.abilities.common.PassAbility)9 StackAbility (mage.game.stack.StackAbility)5 Ability (mage.abilities.Ability)4 ActivatedAbility (mage.abilities.ActivatedAbility)3 SpellAbility (mage.abilities.SpellAbility)3 Card (mage.cards.Card)3 Game (mage.game.Game)3 java.util (java.util)2 java.util.concurrent (java.util.concurrent)2 Collectors (java.util.stream.Collectors)2 StaticAbility (mage.abilities.StaticAbility)2 Cards (mage.cards.Cards)2 Choice (mage.choices.Choice)2 Permanent (mage.game.permanent.Permanent)2 StackObject (mage.game.stack.StackObject)2 Player (mage.players.Player)2 TargetCard (mage.target.TargetCard)2 java.io (java.io)1 File (java.io.File)1 ArrayList (java.util.ArrayList)1