Search in sources :

Example 36 with CombatGroup

use of mage.game.combat.CombatGroup 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 37 with CombatGroup

use of mage.game.combat.CombatGroup in project mage by magefree.

the class ComputerPlayer2 method playNext.

/*@Override
    public boolean playXMana(VariableManaCost cost, ManaCosts<ManaCost> costs, Game game) {
        //SimulatedPlayer.simulateVariableCosts method adds a generic mana cost for each option
        for (ManaCost manaCost: costs) {
            if (manaCost instanceof GenericManaCost) {
                cost.setPayment(manaCost.getPayment());
                logger.debug("using X = " + cost.getPayment().count());
                break;
            }
        }
        game.informPlayers(getName() + " payed " + cost.getPayment().count() + " for " + cost.getText());
        cost.setPaid();
        return true;
    }*/
public void playNext(Game game, UUID activePlayerId, SimulationNode node) {
    boolean skip = false;
    while (true) {
        Phase currentPhase = game.getPhase();
        if (!skip) {
            currentPhase.getStep().endStep(game, activePlayerId);
        }
        game.applyEffects();
        switch(currentPhase.getStep().getType()) {
            case UNTAP:
                game.getPhase().setStep(new UpkeepStep());
                break;
            case UPKEEP:
                game.getPhase().setStep(new DrawStep());
                break;
            case DRAW:
                game.getTurn().setPhase(new PreCombatMainPhase());
                game.getPhase().setStep(new PreCombatMainStep());
                break;
            case PRECOMBAT_MAIN:
                game.getTurn().setPhase(new CombatPhase());
                game.getPhase().setStep(new BeginCombatStep());
                break;
            case BEGIN_COMBAT:
                game.getPhase().setStep(new DeclareAttackersStep());
                break;
            case DECLARE_ATTACKERS:
                game.getPhase().setStep(new DeclareBlockersStep());
                break;
            case DECLARE_BLOCKERS:
                game.getPhase().setStep(new FirstCombatDamageStep());
                break;
            case FIRST_COMBAT_DAMAGE:
                game.getPhase().setStep(new CombatDamageStep());
                break;
            case COMBAT_DAMAGE:
                game.getPhase().setStep(new EndOfCombatStep());
                break;
            case END_COMBAT:
                game.getTurn().setPhase(new PostCombatMainPhase());
                game.getPhase().setStep(new PostCombatMainStep());
                break;
            case POSTCOMBAT_MAIN:
                game.getTurn().setPhase(new EndPhase());
                game.getPhase().setStep(new EndStep());
                break;
            case END_TURN:
                game.getPhase().setStep(new CleanupStep());
                break;
            case CLEANUP:
                game.getPhase().getStep().beginStep(game, activePlayerId);
                if (!game.checkStateAndTriggered() && !game.checkIfGameIsOver()) {
                    game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext());
                    game.getTurn().setPhase(new BeginningPhase());
                    game.getPhase().setStep(new UntapStep());
                }
        }
        if (!game.getStep().skipStep(game, game.getActivePlayerId())) {
            if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS) {
                game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId));
                if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, activePlayerId, activePlayerId))) {
                    for (Combat engagement : ((SimulatedPlayer) game.getPlayer(activePlayerId)).addAttackers(game)) {
                        Game sim = game.copy();
                        UUID defenderId = game.getOpponents(playerId).iterator().next();
                        for (CombatGroup group : engagement.getGroups()) {
                            for (UUID attackerId : group.getAttackers()) {
                                sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim, false);
                            }
                        }
                        sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId));
                        SimulationNode newNode = new SimulationNode(node, sim, activePlayerId);
                        logger.debug(indent(node.depth) + "simulating -- node #:" + SimulationNode.getCount() + " declare attakers");
                        newNode.setCombat(sim.getCombat());
                        node.children.add(newNode);
                    }
                }
            } else if (game.getTurn().getStepType() == PhaseStep.DECLARE_BLOCKERS) {
                game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId));
                if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, activePlayerId, activePlayerId))) {
                    for (UUID defenderId : game.getCombat().getDefenders()) {
                        // check if defender is being attacked
                        if (game.getCombat().isAttacked(defenderId, game)) {
                            for (Combat engagement : ((SimulatedPlayer) game.getPlayer(defenderId)).addBlockers(game)) {
                                Game sim = game.copy();
                                for (CombatGroup group : engagement.getGroups()) {
                                    for (UUID blockerId : group.getBlockers()) {
                                        group.addBlocker(blockerId, defenderId, sim);
                                    }
                                }
                                sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId));
                                SimulationNode newNode = new SimulationNode(node, sim, defenderId);
                                logger.debug(indent(node.depth) + "simulating -- node #:" + SimulationNode.getCount() + " declare blockers");
                                newNode.setCombat(sim.getCombat());
                                node.children.add(newNode);
                            }
                        }
                    }
                }
            } else {
                game.getStep().beginStep(game, activePlayerId);
            }
            if (game.getStep().getHasPriority())
                break;
        } else {
            skip = true;
        }
    }
    game.checkStateAndTriggered();
}
Also used : GameEvent(mage.game.events.GameEvent) CombatGroup(mage.game.combat.CombatGroup) Game(mage.game.Game) Combat(mage.game.combat.Combat)

Example 38 with CombatGroup

use of mage.game.combat.CombatGroup in project mage by magefree.

the class CamouflageEffect method applies.

@Override
public boolean applies(GameEvent event, Ability source, Game game) {
    Player controller = game.getPlayer(source.getControllerId());
    if (controller != null) {
        Map<UUID, List<List<Permanent>>> masterMap = new HashMap<>();
        // and divides them into a number of piles equal to the number of attacking creatures for whom that player is the defending player (piles can be empty)
        for (UUID defenderId : game.getCombat().getPlayerDefenders(game)) {
            Player defender = game.getPlayer(defenderId);
            if (defender != null) {
                List<List<Permanent>> masterList = new ArrayList<>();
                int attackerCount = 0;
                for (CombatGroup combatGroup : game.getCombat().getGroups()) {
                    if (combatGroup.getDefendingPlayerId().equals(defenderId)) {
                        attackerCount += combatGroup.getAttackers().size();
                    }
                }
                // This shouldn't be necessary, but just in case
                for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), defenderId, game)) {
                    permanent.setBlocking(0);
                }
                boolean declinedChoice = false;
                while (masterList.size() < attackerCount) {
                    List<Permanent> newPile = new ArrayList<>();
                    if (!declinedChoice) {
                        FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creatures you control not yet assigned to a pile");
                        for (List<Permanent> list : masterList) {
                            // Creatures they control that can block additional creatures may likewise be put into additional piles.
                            // (This temporarily manipulates Blocking values to "test" how many blockers the creature has still left to assign)
                            List<Permanent> spentBlockers = new ArrayList<>();
                            for (Permanent possibleBlocker : list) {
                                if (possibleBlocker.getMaxBlocks() != 0 && possibleBlocker.getBlocking() >= possibleBlocker.getMaxBlocks()) {
                                    spentBlockers.add(possibleBlocker);
                                }
                            }
                            filter.add(Predicates.not(new PermanentInListPredicate(spentBlockers)));
                        }
                        if (defender.chooseUse(Outcome.Neutral, "Make a new blocker pile? If not, all remaining piles stay empty. (remaining piles: " + (attackerCount - masterList.size()) + ')', source, game)) {
                            Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true);
                            if (target.canChoose(source.getSourceId(), defenderId, game)) {
                                if (defender.chooseTarget(Outcome.Neutral, target, source, game)) {
                                    for (UUID creatureId : target.getTargets()) {
                                        Permanent creature = game.getPermanent(creatureId);
                                        if (creature != null) {
                                            creature.setBlocking(creature.getBlocking() + 1);
                                            newPile.add(creature);
                                        }
                                    }
                                }
                            }
                        } else {
                            declinedChoice = true;
                        }
                    }
                    masterList.add(newPile);
                    StringBuilder sb = new StringBuilder("Blocker pile of ").append(defender.getLogName()).append(" (no. " + masterList.size() + "): ");
                    int i = 0;
                    for (Permanent permanent : newPile) {
                        i++;
                        sb.append(permanent.getLogName());
                        if (i < newPile.size()) {
                            sb.append(", ");
                        }
                    }
                    game.informPlayers(sb.toString());
                }
                // Clear all test Blocking values before assigning piles
                for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), defenderId, game)) {
                    permanent.setBlocking(0);
                }
                masterMap.put(defenderId, masterList);
            }
        }
        // Assign each pile to a different one of those attacking creatures at random. Each creature in a pile that can block the creature that pile is assigned to does so
        if (!masterMap.isEmpty()) {
            for (UUID playerId : masterMap.keySet()) {
                List<Permanent> available = new ArrayList<>();
                for (CombatGroup combatGroup : game.getCombat().getGroups()) {
                    if (combatGroup.getDefendingPlayerId().equals(playerId)) {
                        for (UUID attackerId : combatGroup.getAttackers()) {
                            Permanent permanent = game.getPermanent(attackerId);
                            if (permanent != null && permanent.isCreature(game)) {
                                available.add(permanent);
                            }
                        }
                    }
                }
                List<List<Permanent>> allPiles = masterMap.get(playerId);
                for (List<Permanent> pile : allPiles) {
                    if (available.isEmpty()) {
                        break;
                    }
                    int randomAttacker = RandomUtil.nextInt(available.size());
                    Permanent attacker = available.get(randomAttacker);
                    if (attacker != null) {
                        available.remove(randomAttacker);
                        for (Permanent blocker : pile) {
                            CombatGroup group = game.getCombat().findGroup(attacker.getId());
                            if (group != null) {
                                if (blocker.canBlock(attacker.getId(), game) && (blocker.getMaxBlocks() == 0 || group.getAttackers().size() <= blocker.getMaxBlocks())) {
                                    boolean notYetBlocked = group.getBlockers().isEmpty();
                                    group.addBlockerToGroup(blocker.getId(), blocker.getControllerId(), game);
                                    game.getCombat().addBlockingGroup(blocker.getId(), attacker.getId(), blocker.getControllerId(), game);
                                    if (notYetBlocked) {
                                        game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, attacker.getId(), source, null));
                                    }
                                    // TODO: find an alternate event solution for multi-blockers (as per issue #4285), this will work fine for single blocker creatures though
                                    game.fireEvent(new BlockerDeclaredEvent(attacker.getId(), blocker.getId(), blocker.getControllerId()));
                                }
                            }
                        }
                    }
                }
            }
        }
        return true;
    }
    return false;
}
Also used : Player(mage.players.Player) PermanentInListPredicate(mage.filter.predicate.permanent.PermanentInListPredicate) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) Permanent(mage.game.permanent.Permanent) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) Target(mage.target.Target) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) ArrayList(java.util.ArrayList) List(java.util.List) UUID(java.util.UUID) BlockerDeclaredEvent(mage.game.events.BlockerDeclaredEvent) CombatGroup(mage.game.combat.CombatGroup)

Example 39 with CombatGroup

use of mage.game.combat.CombatGroup in project mage by magefree.

the class CoilsOfTheMedusaDestroyEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Permanent coils = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
    List<UUID> blockers = new ArrayList<>();
    if (coils != null && coils.getAttachedTo() != null) {
        // grab all creatures blocking enchanted creature
        Permanent enchantedCreature = game.getPermanent(coils.getAttachedTo());
        if (enchantedCreature != null && enchantedCreature.isBlocked(game)) {
            for (CombatGroup group : game.getCombat().getGroups()) {
                if (group.getAttackers().contains(enchantedCreature.getId())) {
                    blockers = group.getBlockers();
                    break;
                }
            }
            // filter out defenders, destroying the rest
            while (!blockers.isEmpty()) {
                Permanent blocker = game.getPermanent(blockers.remove(0));
                if (!blocker.hasAbility(DefenderAbility.getInstance(), game)) {
                    blocker.destroy(source, game, false);
                }
            }
            return true;
        }
    }
    return false;
}
Also used : Permanent(mage.game.permanent.Permanent) TargetCreaturePermanent(mage.target.common.TargetCreaturePermanent) TargetPermanent(mage.target.TargetPermanent) ArrayList(java.util.ArrayList) UUID(java.util.UUID) CombatGroup(mage.game.combat.CombatGroup)

Example 40 with CombatGroup

use of mage.game.combat.CombatGroup in project mage by magefree.

the class BerserkMurlodontEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
    if (permanent == null) {
        return false;
    }
    int blockers = game.getCombat().getGroups().stream().filter(combatGroup -> combatGroup.getAttackers().contains(permanent.getId())).map(CombatGroup::getBlockers).mapToInt(List::size).sum();
    game.addEffect(new BoostTargetEffect(blockers, blockers, Duration.EndOfTurn).setTargetPointer(new FixedTarget(permanent, game)), source);
    return true;
}
Also used : BoostTargetEffect(mage.abilities.effects.common.continuous.BoostTargetEffect) BecomesBlockedAllTriggeredAbility(mage.abilities.common.BecomesBlockedAllTriggeredAbility) Outcome(mage.constants.Outcome) OneShotEffect(mage.abilities.effects.OneShotEffect) UUID(java.util.UUID) MageInt(mage.MageInt) SubType(mage.constants.SubType) FixedTarget(mage.target.targetpointer.FixedTarget) CardSetInfo(mage.cards.CardSetInfo) Duration(mage.constants.Duration) Game(mage.game.Game) List(java.util.List) CardImpl(mage.cards.CardImpl) Permanent(mage.game.permanent.Permanent) CardType(mage.constants.CardType) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) CombatGroup(mage.game.combat.CombatGroup) Ability(mage.abilities.Ability) FixedTarget(mage.target.targetpointer.FixedTarget) Permanent(mage.game.permanent.Permanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) BoostTargetEffect(mage.abilities.effects.common.continuous.BoostTargetEffect) CombatGroup(mage.game.combat.CombatGroup)

Aggregations

CombatGroup (mage.game.combat.CombatGroup)44 Permanent (mage.game.permanent.Permanent)39 UUID (java.util.UUID)25 Player (mage.players.Player)23 FilterCreaturePermanent (mage.filter.common.FilterCreaturePermanent)9 FixedTarget (mage.target.targetpointer.FixedTarget)9 TargetPermanent (mage.target.TargetPermanent)8 TargetCreaturePermanent (mage.target.common.TargetCreaturePermanent)8 HashSet (java.util.HashSet)7 OneShotEffect (mage.abilities.effects.OneShotEffect)6 Game (mage.game.Game)6 ArrayList (java.util.ArrayList)5 List (java.util.List)5 Combat (mage.game.combat.Combat)5 BlockerDeclaredEvent (mage.game.events.BlockerDeclaredEvent)5 Target (mage.target.Target)5 MageObjectReference (mage.MageObjectReference)4 Ability (mage.abilities.Ability)4 PermanentInListPredicate (mage.filter.predicate.permanent.PermanentInListPredicate)4 BlockedByOnlyOneCreatureThisCombatWatcher (mage.watchers.common.BlockedByOnlyOneCreatureThisCombatWatcher)4