public List<Combat> addAttackers(Game game) {
   Map<Integer, Combat> engagements = new HashMap<Integer, Combat>();
   // useful only for two player games - will only attack first opponent
   UUID defenderId = game.getOpponents(playerId).iterator().next();
   List<Permanent> attackersList = super.getAvailableAttackers(defenderId, game);
   // use binary digits to calculate powerset of attackers
   int powerElements = (int) Math.pow(2, attackersList.size());
   StringBuilder binary = new StringBuilder();
   for (int i = powerElements - 1; i >= 0; i--) {
     Game sim = game.copy();
     binary.setLength(0);
     binary.append(Integer.toBinaryString(i));
     while (binary.length() < attackersList.size()) {
       binary.insert(0, "0");
     }
     for (int j = 0; j < attackersList.size(); j++) {
       if (binary.charAt(j) == '1') {
         setStoredBookmark(
             sim
                 .bookmarkState()); // makes it possible to UNDO a declared attacker with costs
                                    // from e.g. Propaganda
         if (!sim.getCombat()
             .declareAttacker(attackersList.get(j).getId(), defenderId, playerId, sim)) {
           sim.undo(playerId);
         }
       }
     }
     if (engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat()) != null) {
       logger.debug("simulating -- found redundant attack combination");
     } else if (logger.isDebugEnabled()) {
       logger.debug("simulating -- attack:" + sim.getCombat().getGroups().size());
     }
   }
   return new ArrayList<Combat>(engagements.values());
 }
 @Override
 public boolean checkTrigger(GameEvent event, Game game) {
   if (game.getActivePlayerId().equals(this.controllerId)) {
     if (game.getCombat().attacksAlone()) {
       this.getEffects()
           .get(0)
           .setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0)));
       return true;
     }
   }
   return false;
 }
Beispiel #3
0
 @Override
 public boolean checkTrigger(GameEvent event, Game game) {
   if (event.getType() == EventType.DECLARED_ATTACKERS
       && game.getActivePlayerId().equals(this.controllerId)) {
     if (game.getCombat().attacksAlone()) {
       for (Effect effect : this.getEffects()) {
         effect.setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0)));
       }
       return true;
     }
   }
   return false;
 }
  public List<Combat> addBlockers(Game game) {
    Map<Integer, Combat> engagements = new HashMap<Integer, Combat>();
    int numGroups = game.getCombat().getGroups().size();
    if (numGroups == 0) return new ArrayList<Combat>();

    // add a node with no blockers
    Game sim = game.copy();
    engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat());
    sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId));

    List<Permanent> blockers = getAvailableBlockers(game);
    addBlocker(game, blockers, engagements);

    return new ArrayList<Combat>(engagements.values());
  }
Beispiel #5
0
 /**
  * There are effects that let creatures assigns combat damage equal to its toughness rather than
  * its power. So this method takes this into account to get the value of damage a creature will
  * assign
  *
  * @param permanent
  * @param game
  * @return
  */
 private int getDamageValueFromPermanent(Permanent permanent, Game game) {
   if (game.getCombat().useToughnessForDamage()) {
     return permanent.getToughness().getValue();
   } else {
     return permanent.getPower().getValue();
   }
 }
Beispiel #6
0
  @Override
  public void selectBlockers(Game game, UUID defendingPlayerId) {
    int numGroups = game.getCombat().getGroups().size();
    if (numGroups == 0) return;

    List<Permanent> blockers = getAvailableBlockers(game);
    for (Permanent blocker : blockers) {
      int check = rnd.nextInt(numGroups + 1);
      if (check < numGroups) {
        CombatGroup group = game.getCombat().getGroups().get(check);
        if (group.getAttackers().size() > 0)
          this.declareBlocker(blocker.getId(), group.getAttackers().get(0), game);
      }
    }
    actionCount++;
  }
 @Override
 public void selectAttackers(Game game, UUID attackingPlayerId) {
   // useful only for two player games - will only attack first opponent
   //        logger.info("select attackers");
   UUID defenderId = game.getOpponents(playerId).iterator().next();
   List<Permanent> attackersList = super.getAvailableAttackers(defenderId, game);
   // use binary digits to calculate powerset of attackers
   int powerElements = (int) Math.pow(2, attackersList.size());
   int value = rnd.nextInt(powerElements);
   StringBuilder binary = new StringBuilder();
   binary.append(Integer.toBinaryString(value));
   while (binary.length() < attackersList.size()) {
     binary.insert(0, "0"); // pad with zeros
   }
   for (int i = 0; i < attackersList.size(); i++) {
     if (binary.charAt(i) == '1') {
       setStoredBookmark(
           game
               .bookmarkState()); // makes it possible to UNDO a declared attacker with costs from
                                  // e.g. Propaganda
       if (!game.getCombat()
           .declareAttacker(attackersList.get(i).getId(), defenderId, playerId, game)) {
         game.undo(playerId);
       }
     }
   }
   actionCount++;
 }
Beispiel #8
0
 @Override
 public void adjustTargets(Ability ability, Game game) {
   if (this.getAbilities().contains(ability) && ability.getRule().startsWith("&bull Dragons")) {
     FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that player controls");
     filter.add(new ControllerIdPredicate(game.getCombat().getAttackerId()));
     ability.getTargets().clear();
     ability.addTarget(new TargetCreaturePermanent(filter));
   }
 }
 protected void addBlocker(Game game, List<Permanent> blockers, Map<Integer, Combat> engagements) {
   if (blockers.isEmpty()) return;
   int numGroups = game.getCombat().getGroups().size();
   // try to block each attacker with each potential blocker
   Permanent blocker = blockers.get(0);
   if (logger.isDebugEnabled()) logger.debug("simulating -- block:" + blocker);
   List<Permanent> remaining = remove(blockers, blocker);
   for (int i = 0; i < numGroups; i++) {
     if (game.getCombat().getGroups().get(i).canBlock(blocker, game)) {
       Game sim = game.copy();
       sim.getCombat().getGroups().get(i).addBlocker(blocker.getId(), playerId, sim);
       if (engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat()) != null)
         logger.debug("simulating -- found redundant block combination");
       addBlocker(sim, remaining, engagements); // and recurse minus the used blocker
     }
   }
   addBlocker(game, remaining, engagements);
 }
 @Override
 public boolean apply(Permanent input, Game game) {
   for (CombatGroup combatGroup : game.getCombat().getGroups()) {
     if (combatGroup.getBlockers().contains(input.getId())
         && combatGroup.getAttackers().contains(attackerId)) {
       return true;
     }
   }
   return false;
 }
Beispiel #11
0
 public static CombatSimulator load(Game game) {
   CombatSimulator simCombat = new CombatSimulator();
   for (CombatGroup group : game.getCombat().getGroups()) {
     simCombat.groups.add(
         new CombatGroupSimulator(
             group.getDefenderId(), group.getAttackers(), group.getBlockers(), game));
   }
   for (UUID defenderId : game.getCombat().getDefenders()) {
     simCombat.defenders.add(defenderId);
     Player player = game.getPlayer(defenderId);
     if (player != null) {
       simCombat.playersLife.put(defenderId, player.getLife());
     } else {
       Permanent permanent = game.getPermanent(defenderId);
       simCombat.planeswalkerLoyalty.put(
           defenderId, permanent.getCounters(game).getCount(CounterType.LOYALTY));
     }
   }
   return simCombat;
 }
Beispiel #12
0
 @Override
 public boolean checkTrigger(GameEvent event, Game game) {
   if (event.getType() == GameEvent.EventType.DECLARED_BLOCKERS) {
     for (CombatGroup combatGroup : game.getCombat().getGroups()) {
       if (!combatGroup.getBlockers().isEmpty()) {
         return true;
       }
     }
   }
   return false;
 }
Beispiel #13
0
 @Override
 public void adjustTargets(Ability ability, Game game) {
   if (ability.getAbilityType().equals(AbilityType.TRIGGERED)) {
     ability.getTargets().clear();
     FilterCreaturePermanent filter =
         new FilterCreaturePermanent("creature defending player controls");
     UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId());
     filter.add(new ControllerIdPredicate(defenderId));
     TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
     ability.addTarget(target);
   }
 }
Beispiel #14
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   if (controller != null) {
     Set<UUID> toSacrifice = new HashSet<UUID>();
     if (controller.flipCoin(game)) {
       // each blocking creature is sacrificed by its controller
       for (CombatGroup combatGroup : game.getCombat().getGroups()) {
         for (UUID blockerId : combatGroup.getBlockers()) {
           toSacrifice.add(blockerId);
         }
       }
     } else {
       // each blocked creature is sacrificed by its controller
       for (CombatGroup combatGroup : game.getCombat().getGroups()) {
         if (!combatGroup.getBlockers().isEmpty()) {
           for (UUID attackerId : combatGroup.getAttackers()) {
             toSacrifice.add(attackerId);
           }
         }
       }
     }
     for (UUID creatureId : toSacrifice) {
       Permanent creature = game.getPermanent(creatureId);
       if (creature != null) {
         creature.sacrifice(source.getSourceId(), game);
         Player player = game.getPlayer(creature.getControllerId());
         if (player != null) {
           game.informPlayers(
               new StringBuilder(player.getName())
                   .append(" sacrifices ")
                   .append(creature.getName())
                   .toString());
         }
       }
     }
     return true;
   }
   return false;
 }
Beispiel #15
0
 @Override
 public boolean apply(Game game, Ability source) {
   for (UUID attackingCreatureId : game.getCombat().getAttackers()) {
     Permanent attackingCreature = game.getPermanent(attackingCreatureId);
     if (attackingCreature != null) {
       if (attackingCreature.getColor(game).isBlack()
           && attackingCreature.hasAbility(FlyingAbility.getInstance().getId(), game)) {
         return true;
       }
     }
   }
   return false;
 }
Beispiel #16
0
  @Override
  public boolean activate(Game game, boolean noMana) {
    UUID defenderId = game.getCombat().getDefenderId(sourceId);
    if (defenderId != null) {
      FilterCreaturePermanent filter = filterTemplate.copy();
      filter.add(new ControllerIdPredicate(defenderId));

      this.getTargets().clear();
      TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
      target.setRequired(true);
      this.addTarget(target);
      return super.activate(game, noMana);
    }
    return false;
  }
Beispiel #17
0
 @Override
 public boolean apply(Game game, Ability source) {
   List<UUID> attackers = game.getCombat().getAttackers();
   int damage = attackers.size();
   if (!attackers.isEmpty()) {
     for (UUID attacker : attackers) {
       Permanent creature = game.getPermanent(attacker);
       if (creature != null) {
         creature.damage(damage, source.getSourceId(), game, false, true);
       }
     }
     return true;
   }
   return false;
 }
Beispiel #18
0
 @Override
 public void selectAttackers(Game game, UUID attackingPlayerId) {
   // useful only for two player games - will only attack first opponent
   UUID defenderId = game.getOpponents(playerId).iterator().next();
   List<Permanent> attackersList = super.getAvailableAttackers(game);
   // use binary digits to calculate powerset of attackers
   int powerElements = (int) Math.pow(2, attackersList.size());
   int value = rnd.nextInt(powerElements);
   StringBuilder binary = new StringBuilder();
   binary.append(Integer.toBinaryString(value));
   while (binary.length() < attackersList.size()) {
     binary.insert(0, "0"); // pad with zeros
   }
   for (int i = 0; i < attackersList.size(); i++) {
     if (binary.charAt(i) == '1')
       game.getCombat().declareAttacker(attackersList.get(i).getId(), defenderId, game);
   }
   actionCount++;
 }
Beispiel #19
0
 @Override
 public boolean canBeBlockedCheckAfter(Permanent attacker, Ability source, Game game) {
   for (CombatGroup combatGroup : game.getCombat().getGroups()) {
     if (combatGroup.getAttackers().contains(source.getSourceId())) {
       for (UUID blockerId : combatGroup.getBlockers()) {
         Permanent blockingCreature = game.getPermanent(blockerId);
         if (blockingCreature != null) {
           for (Permanent permanent :
               game.getBattlefield()
                   .getAllActivePermanents(
                       new FilterCreaturePermanent(), blockingCreature.getControllerId(), game)) {
             if (!combatGroup.getBlockers().contains(permanent.getId())) {
               // not all creatures block Tromokratis
               return false;
             }
           }
         }
       }
     }
   }
   return true;
 }
Beispiel #20
0
  public boolean putOntoBattlefield(
      int amount,
      Game game,
      UUID sourceId,
      UUID controllerId,
      boolean tapped,
      boolean attacking,
      UUID attackedPlayer) {
    Player controller = game.getPlayer(controllerId);
    if (controller == null) {
      return false;
    }
    lastAddedTokenIds.clear();

    // moved here from CreateTokenEffect because not all cards that create tokens use
    // CreateTokenEffect
    // they use putOntoBattlefield directly
    // TODO: Check this setCode handling because it makes no sense if token put into play with e.g.
    // "Feldon of the third Path"
    String setCode = null;
    if (this.getOriginalExpansionSetCode() != null
        && !this.getOriginalExpansionSetCode().isEmpty()) {
      setCode = this.getOriginalExpansionSetCode();
    } else {
      Card source = game.getCard(sourceId);
      if (source != null) {
        setCode = source.getExpansionSetCode();
      } else {
        MageObject object = game.getObject(sourceId);
        if (object instanceof PermanentToken) {
          setCode = ((PermanentToken) object).getExpansionSetCode();
        }
      }
    }
    if (!expansionSetCodeChecked) {
      expansionSetCodeChecked = this.updateExpansionSetCode(setCode);
    }

    GameEvent event =
        new GameEvent(
            EventType.CREATE_TOKEN,
            null,
            sourceId,
            controllerId,
            amount,
            this.getCardType().contains(CardType.CREATURE));
    if (!game.replaceEvent(event)) {
      amount = event.getAmount();

      List<Permanent> permanents = new ArrayList<>();
      List<Permanent> permanentsEntered = new ArrayList<>();

      for (int i = 0; i < amount; i++) {
        PermanentToken newToken =
            new PermanentToken(
                this,
                event.getPlayerId(),
                setCode,
                game); // use event.getPlayerId() because it can be replaced by replacement effect
        game.getState().addCard(newToken);
        permanents.add(newToken);
        game.getPermanentsEntering().put(newToken.getId(), newToken);
        newToken.setTapped(tapped);
      }
      game.setScopeRelevant(true);
      for (Permanent permanent : permanents) {
        if (permanent.entersBattlefield(sourceId, game, Zone.OUTSIDE, true)) {
          permanentsEntered.add(permanent);
        } else {
          game.getPermanentsEntering().remove(permanent.getId());
        }
      }
      game.setScopeRelevant(false);
      for (Permanent permanent : permanentsEntered) {
        game.addPermanent(permanent);
        permanent.setZone(Zone.BATTLEFIELD, game);
        game.getPermanentsEntering().remove(permanent.getId());

        this.lastAddedTokenIds.add(permanent.getId());
        this.lastAddedTokenId = permanent.getId();
        game.addSimultaneousEvent(
            new ZoneChangeEvent(
                permanent, permanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD));
        if (attacking && game.getCombat() != null) {
          game.getCombat().addAttackingCreature(permanent.getId(), game, attackedPlayer);
        }
        if (!game.isSimulation()) {
          game.informPlayers(
              controller.getLogName()
                  + " puts a "
                  + permanent.getLogName()
                  + " token onto the battlefield");
        }
      }
      return true;
    }
    return false;
  }
Beispiel #21
0
 protected int simulateBlockers(
     Game game,
     SimulationNode2 node,
     UUID defenderId,
     int depth,
     int alpha,
     int beta,
     boolean counter) {
   if (ALLOW_INTERRUPT && Thread.interrupted()) {
     Thread.currentThread().interrupt();
     logger.debug("interrupted");
     return GameStateEvaluator2.evaluate(playerId, game);
   }
   Integer val = null;
   SimulationNode2 bestNode = null;
   // check if defender is being attacked
   if (game.getCombat().isAttacked(defenderId, game)) {
     SimulatedPlayer2 defender = (SimulatedPlayer2) game.getPlayer(defenderId);
     if (logger.isDebugEnabled()) {
       logger.debug(
           defender.getName() + "'s possible blockers: " + defender.getAvailableBlockers(game));
     }
     List<Combat> combats = defender.addBlockers(game);
     for (Combat engagement : combats) {
       if (alpha >= beta) {
         logger.debug("Sim blockers -- pruning blockers");
         break;
       }
       Game sim = game.copy();
       for (CombatGroup group : engagement.getGroups()) {
         if (group.getAttackers().size() > 0) {
           UUID attackerId = group.getAttackers().get(0);
           for (UUID blockerId : group.getBlockers()) {
             sim.getPlayer(defenderId).declareBlocker(defenderId, blockerId, attackerId, sim);
           }
         }
       }
       sim.fireEvent(
           GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId));
       SimulationNode2 newNode = new SimulationNode2(node, sim, depth, defenderId);
       if (logger.isDebugEnabled()) {
         logger.debug("Sim block for player:" + game.getPlayer(defenderId).getName());
       }
       sim.checkStateAndTriggered();
       while (!sim.getStack().isEmpty()) {
         sim.getStack().resolve(sim);
         logger.debug("Sim blockers: resolving triggered abilities");
         sim.applyEffects();
       }
       sim.fireEvent(
           GameEvent.getEvent(
               GameEvent.EventType.DECLARE_BLOCKERS_STEP_POST,
               sim.getActivePlayerId(),
               sim.getActivePlayerId()));
       Combat simCombat = sim.getCombat().copy();
       finishCombat(sim);
       if (sim.gameOver(null)) {
         val = GameStateEvaluator2.evaluate(playerId, sim);
       } else if (!counter) {
         val = simulatePostCombatMain(sim, newNode, depth - 1, alpha, beta);
       } else {
         val = GameStateEvaluator2.evaluate(playerId, sim);
       }
       if (!defenderId.equals(playerId)) {
         if (val < beta) {
           beta = val;
           bestNode = newNode;
           bestNode.setScore(val);
           bestNode.setCombat(simCombat);
         }
       } else {
         if (val > alpha) {
           alpha = val;
           bestNode = newNode;
           bestNode.setScore(val);
           bestNode.setCombat(simCombat);
         }
       }
     }
   }
   if (val == null) {
     val = GameStateEvaluator2.evaluate(playerId, game);
   }
   if (bestNode != null) {
     node.children.clear();
     node.children.add(bestNode);
     node.setScore(bestNode.getScore());
   }
   if (logger.isDebugEnabled()) {
     logger.debug(
         "Sim blockers: returning score: "
             + val
             + " depth:"
             + depth
             + " for player:"
             + game.getPlayer(node.getPlayerId()).getName());
   }
   return val;
 }
Beispiel #22
0
 protected int simulateAttackers(
     Game game,
     SimulationNode2 node,
     UUID attackerId,
     int depth,
     int alpha,
     int beta,
     boolean counter) {
   if (ALLOW_INTERRUPT && Thread.interrupted()) {
     Thread.currentThread().interrupt();
     logger.debug("interrupted");
     return GameStateEvaluator2.evaluate(playerId, game);
   }
   Integer val = null;
   SimulationNode2 bestNode = null;
   SimulatedPlayer2 attacker = (SimulatedPlayer2) game.getPlayer(attackerId);
   UUID defenderId = game.getOpponents(attackerId).iterator().next();
   if (logger.isDebugEnabled()) {
     logger.debug(
         attacker.getName()
             + "'s possible attackers: "
             + attacker.getAvailableAttackers(defenderId, game));
   }
   for (Combat engagement : attacker.addAttackers(game)) {
     if (logger.isDebugEnabled()) {
       logger.debug(
           "Sim Attackers: "
               + engagement.getAttackers()
               + ", blockers: "
               + engagement.getBlockers());
     }
     if (alpha >= beta) {
       logger.debug("Sim Attackers -- pruning attackers");
       break;
     }
     Game sim = game.copy();
     for (CombatGroup group : engagement.getGroups()) {
       for (UUID attackId : group.getAttackers()) {
         sim.getPlayer(attackerId).declareAttacker(attackId, defenderId, sim, false);
       }
     }
     sim.fireEvent(
         GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, attackerId, attackerId));
     SimulationNode2 newNode = new SimulationNode2(node, sim, depth, attackerId);
     if (logger.isDebugEnabled()) {
       logger.debug("Sim attack for player:" + game.getPlayer(attackerId).getName());
     }
     sim.checkStateAndTriggered();
     while (!sim.getStack().isEmpty()) {
       sim.getStack().resolve(sim);
       logger.debug("Sim attack: resolving triggered abilities");
       sim.applyEffects();
     }
     sim.fireEvent(
         GameEvent.getEvent(
             GameEvent.EventType.DECLARE_ATTACKERS_STEP_POST,
             sim.getActivePlayerId(),
             sim.getActivePlayerId()));
     Combat simCombat = sim.getCombat().copy();
     sim.getPhase().setStep(new DeclareBlockersStep());
     val = simulateCombat(sim, newNode, depth - 1, alpha, beta, counter);
     if (!attackerId.equals(playerId)) {
       if (val < beta) {
         beta = val;
         bestNode = newNode;
         bestNode.setScore(val);
         if (newNode.getChildren().size() > 0) {
           bestNode.setCombat(newNode.getChildren().get(0).getCombat());
         }
       }
     } else {
       if (val > alpha) {
         alpha = val;
         bestNode = newNode;
         bestNode.setScore(val);
         if (newNode.getChildren().size() > 0) {
           bestNode.setCombat(newNode.getChildren().get(0).getCombat());
         }
       }
     }
   }
   if (val == null) {
     val = GameStateEvaluator2.evaluate(playerId, game);
   }
   if (bestNode != null) {
     node.children.clear();
     node.children.add(bestNode);
     node.setScore(bestNode.getScore());
   }
   if (logger.isDebugEnabled()) {
     logger.debug(
         "Sim attackers: returning score: "
             + val
             + " depth:"
             + depth
             + " for player:"
             + game.getPlayer(node.getPlayerId()).getName());
   }
   return val;
 }
Beispiel #23
0
 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;
 }
Beispiel #24
0
  public boolean checkBlockRestrictions(Game game, int blockersCount) {
    boolean blockWasLegal = true;
    if (attackers.isEmpty()) {
      return blockWasLegal;
    }
    if (blockersCount == 1) {
      List<UUID> toBeRemoved = new ArrayList<>();
      for (UUID blockerId : getBlockers()) {
        Permanent blocker = game.getPermanent(blockerId);
        if (blocker != null
            && blocker.getAbilities().containsKey(CantBlockAloneAbility.getInstance().getId())) {
          blockWasLegal = false;
          game.informPlayers(blocker.getLogName() + " can't block alone. Removing it from combat.");
          toBeRemoved.add(blockerId);
        }
      }

      for (UUID blockerId : toBeRemoved) {
        game.getCombat().removeBlocker(blockerId, game);
      }
      if (blockers.isEmpty()) {
        this.blocked = false;
      }
    }

    for (UUID uuid : attackers) {
      Permanent attacker = game.getPermanent(uuid);
      // Check if there are enough blockers to have a legal block
      if (attacker != null
          && this.blocked
          && attacker.getMinBlockedBy() > 1
          && blockers.size() > 0
          && blockers.size() < attacker.getMinBlockedBy()) {
        for (UUID blockerId : blockers) {
          Permanent blocker = game.getPermanent(blockerId);
          if (blocker != null) {
            blocker.setBlocking(blocker.getBlocking() - 1);
          }
        }
        blockers.clear();
        blockerOrder.clear();
        this.blocked = false;
        game.informPlayers(
            attacker.getLogName()
                + " can't be blocked except by "
                + attacker.getMinBlockedBy()
                + " or more creatures. Blockers discarded.");
        blockWasLegal = false;
      }
      // Check if there are to many blockers (maxBlockedBy = 0 means no restrictions)
      if (attacker != null
          && this.blocked
          && attacker.getMaxBlockedBy() > 0
          && attacker.getMaxBlockedBy() < blockers.size()) {
        for (UUID blockerId : blockers) {
          Permanent blocker = game.getPermanent(blockerId);
          if (blocker != null) {
            blocker.setBlocking(blocker.getBlocking() - 1);
          }
        }
        blockers.clear();
        blockerOrder.clear();
        this.blocked = false;
        game.informPlayers(
            new StringBuilder(attacker.getLogName())
                .append(" can't be blocked by more than ")
                .append(attacker.getMaxBlockedBy())
                .append(attacker.getMaxBlockedBy() == 1 ? " creature." : " creatures.")
                .append(" Blockers discarded.")
                .toString());
        blockWasLegal = false;
      }
    }
    return blockWasLegal;
  }
Beispiel #25
0
 @Override
 public boolean checkTrigger(GameEvent event, Game game) {
   return !game.getCombat().getAttackers().isEmpty();
 }