Search in sources :

Example 16 with ActivatedAbility

use of mage.abilities.ActivatedAbility in project mage by magefree.

the class MCTSNode method expand.

public void expand() {
    MCTSPlayer player = (MCTSPlayer) game.getPlayer(playerId);
    if (player.getNextAction() == null) {
        logger.fatal("next action is null");
    }
    switch(player.getNextAction()) {
        case PRIORITY:
            // logger.info("Priority for player:" + player.getName() + " turn: " + game.getTurnNum() + " phase: " + game.getPhase().getType() + " step: " + game.getStep().getType());
            List<Ability> abilities;
            if (!USE_ACTION_CACHE)
                abilities = player.getPlayableOptions(game);
            else
                abilities = getPlayables(player, fullStateValue, game);
            for (Ability ability : abilities) {
                Game sim = game.copy();
                // logger.info("expand " + ability.toString());
                MCTSPlayer simPlayer = (MCTSPlayer) sim.getPlayer(player.getId());
                simPlayer.activateAbility((ActivatedAbility) ability, sim);
                sim.resume();
                children.add(new MCTSNode(this, sim, ability));
            }
            break;
        case SELECT_ATTACKERS:
            // logger.info("Select attackers:" + player.getName());
            List<List<UUID>> attacks;
            if (!USE_ACTION_CACHE)
                attacks = player.getAttacks(game);
            else
                attacks = getAttacks(player, fullStateValue, game);
            UUID defenderId = game.getOpponents(player.getId()).iterator().next();
            for (List<UUID> attack : attacks) {
                Game sim = game.copy();
                MCTSPlayer simPlayer = (MCTSPlayer) sim.getPlayer(player.getId());
                for (UUID attackerId : attack) {
                    simPlayer.declareAttacker(attackerId, defenderId, sim, false);
                }
                sim.resume();
                children.add(new MCTSNode(this, sim, sim.getCombat()));
            }
            break;
        case SELECT_BLOCKERS:
            // logger.info("Select blockers:" + player.getName());
            List<List<List<UUID>>> blocks;
            if (!USE_ACTION_CACHE)
                blocks = player.getBlocks(game);
            else
                blocks = getBlocks(player, fullStateValue, game);
            for (List<List<UUID>> block : blocks) {
                Game sim = game.copy();
                MCTSPlayer simPlayer = (MCTSPlayer) sim.getPlayer(player.getId());
                List<CombatGroup> groups = sim.getCombat().getGroups();
                for (int i = 0; i < groups.size(); i++) {
                    if (i < block.size()) {
                        for (UUID blockerId : block.get(i)) {
                            simPlayer.declareBlocker(simPlayer.getId(), blockerId, groups.get(i).getAttackers().get(0), sim);
                        }
                    }
                }
                sim.resume();
                children.add(new MCTSNode(this, sim, sim.getCombat()));
            }
            break;
    }
    game = null;
}
Also used : PassAbility(mage.abilities.common.PassAbility) PlayLandAbility(mage.abilities.PlayLandAbility) ActivatedAbility(mage.abilities.ActivatedAbility) Ability(mage.abilities.Ability) Game(mage.game.Game) ArrayList(java.util.ArrayList) List(java.util.List) UUID(java.util.UUID) CombatGroup(mage.game.combat.CombatGroup)

Example 17 with ActivatedAbility

use of mage.abilities.ActivatedAbility in project mage by magefree.

the class SimulatedPlayer2 method filterAbilities.

// protected void simulateAction(Game game, SimulatedAction previousActions, Ability action) {
// List<Ability> actions = new ArrayList<Ability>(previousActions.getAbilities());
// actions.add(action);
// Game sim = game.copy();
// if (sim.getPlayer(playerId).activateAbility((ActivatedAbility) action.copy(), sim)) {
// sim.applyEffects();
// sim.getPlayers().resetPassed();
// allActions.add(new SimulatedAction(sim, actions));
// }
// }
/**
 * if suggested abilities exist, return only those from playables
 *
 * @param game
 * @param playables
 * @param suggested
 * @return
 */
protected List<ActivatedAbility> filterAbilities(Game game, List<ActivatedAbility> playables, List<String> suggested) {
    if (playables.isEmpty()) {
        return playables;
    }
    if (suggested == null || suggested.isEmpty()) {
        return playables;
    }
    List<ActivatedAbility> filtered = new ArrayList<>();
    for (ActivatedAbility ability : playables) {
        Card card = game.getCard(ability.getSourceId());
        if (card != null) {
            for (String s : suggested) {
                if (s.equals(card.getName())) {
                    logger.debug("matched: " + s);
                    forced = true;
                    filtered.add(ability);
                }
            }
        }
    }
    if (!filtered.isEmpty()) {
        return filtered;
    }
    return playables;
}
Also used : ActivatedAbility(mage.abilities.ActivatedAbility) Card(mage.cards.Card)

Example 18 with ActivatedAbility

use of mage.abilities.ActivatedAbility in project mage by magefree.

the class SimulatedPlayer2 method filterOptions.

protected List<Ability> filterOptions(Game game, List<Ability> options, ActivatedAbility ability, List<String> suggested) {
    if (options.isEmpty()) {
        return options;
    }
    if (suggested == null || suggested.isEmpty()) {
        return options;
    }
    List<Ability> filtered = new ArrayList<>();
    for (Ability option : options) {
        if (!option.getTargets().isEmpty() && option.getTargets().get(0).getMaxNumberOfTargets() == 1) {
            Card card = game.getCard(ability.getSourceId());
            if (card != null) {
                for (String s : suggested) {
                    String[] groups = s.split(";");
                    logger.trace("s=" + s + ";groups=" + groups.length);
                    if (groups.length == 2) {
                        if (groups[0].equals(card.getName()) && groups[1].startsWith("name=")) {
                            // extract target and compare to suggested
                            String targetName = groups[1].split("=")[1];
                            Player player = game.getPlayer(option.getFirstTarget());
                            if (player != null && targetName.equals(player.getName())) {
                                System.out.println("matched(option): " + s);
                                filtered.add(option);
                                return filtered;
                            } else {
                                Card target = game.getCard(option.getFirstTarget());
                                if (target != null && target.getName().equals(targetName)) {
                                    System.out.println("matched(option): " + s);
                                    filtered.add(option);
                                    return filtered;
                                }
                                System.out.println("not equal UUID for target, player=" + player);
                            }
                        }
                    }
                }
            }
        }
    }
    // no option was found
    return options;
}
Also used : PassAbility(mage.abilities.common.PassAbility) StackAbility(mage.game.stack.StackAbility) TriggeredAbility(mage.abilities.TriggeredAbility) ActivatedAbility(mage.abilities.ActivatedAbility) Ability(mage.abilities.Ability) MatchPlayer(mage.game.match.MatchPlayer) Player(mage.players.Player) Card(mage.cards.Card)

Example 19 with ActivatedAbility

use of mage.abilities.ActivatedAbility in project mage by magefree.

the class SimulatedPlayer method simulateVariableCosts.

// protected void simulateAction(Game game, SimulatedAction previousActions, Ability action) {
// List<Ability> actions = new ArrayList<Ability>(previousActions.getAbilities());
// actions.add(action);
// Game sim = game.copy();
// if (sim.getPlayer(playerId).activateAbility((ActivatedAbility) action.copy(), sim)) {
// sim.applyEffects();
// sim.getPlayers().resetPassed();
// allActions.add(new SimulatedAction(sim, actions));
// }
// }
// add a generic mana cost for each amount possible
protected void simulateVariableCosts(Ability ability, Game game) {
    int numAvailable = getAvailableManaProducers(game).size() - ability.getManaCosts().manaValue();
    int start = 0;
    if (!(ability instanceof SpellAbility)) {
        // only use x=0 on spell abilities
        if (numAvailable == 0)
            return;
        else
            start = 1;
    }
    for (int i = start; i < numAvailable; i++) {
        Ability newAbility = ability.copy();
        newAbility.getManaCostsToPay().add(new GenericManaCost(i));
        allActions.add(newAbility);
    }
}
Also used : PassAbility(mage.abilities.common.PassAbility) StackAbility(mage.game.stack.StackAbility) TriggeredAbility(mage.abilities.TriggeredAbility) SpellAbility(mage.abilities.SpellAbility) ActivatedAbility(mage.abilities.ActivatedAbility) Ability(mage.abilities.Ability) GenericManaCost(mage.abilities.costs.mana.GenericManaCost) SpellAbility(mage.abilities.SpellAbility)

Example 20 with ActivatedAbility

use of mage.abilities.ActivatedAbility 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

ActivatedAbility (mage.abilities.ActivatedAbility)21 Ability (mage.abilities.Ability)17 PassAbility (mage.abilities.common.PassAbility)11 Permanent (mage.game.permanent.Permanent)8 StackAbility (mage.game.stack.StackAbility)8 SpellAbility (mage.abilities.SpellAbility)7 Card (mage.cards.Card)7 Player (mage.players.Player)7 ArrayList (java.util.ArrayList)4 TriggeredAbility (mage.abilities.TriggeredAbility)4 SimpleStaticAbility (mage.abilities.common.SimpleStaticAbility)4 Game (mage.game.Game)4 UUID (java.util.UUID)3 File (java.io.File)2 java.util (java.util)2 List (java.util.List)2 Collectors (java.util.stream.Collectors)2 MageObject (mage.MageObject)2 PlayLandAbility (mage.abilities.PlayLandAbility)2 StaticAbility (mage.abilities.StaticAbility)2