@Override protected void update(GameState state, Event event) { Set objects = event.getResult(state); for (GameObject o : objects.getAll(GameObject.class)) { int controllerID = o.getController(state).ID; if (this.counts.containsKey(controllerID)) this.counts.put(controllerID, this.counts.get(controllerID) + 1); else this.counts.put(controllerID, 1); } }
@Override public Set evaluate(GameState state, Identified thisObject) { Set ret = new Set(); for (GameObject object : state.getAllObjects()) for (Class<? extends Keyword> c : this.abilities) if (object.hasAbility(c)) ret.add(object); for (Player player : state.players) for (Class<? extends Keyword> c : this.abilities) if (player.hasAbility(c)) ret.add(player); return ret; }
@Override public DamageAssignment.Batch match(Event context, DamageAssignment.Batch damageAssignments) { DamageAssignment.Batch batch = new DamageAssignment.Batch(); GameObject source = (GameObject) this.getStaticSourceObject(context.game.actualState); int enchantedPlayer = source.getAttachedTo(); for (DamageAssignment assignment : damageAssignments) if (context.state.<Identified>get(assignment.takerID).ID == enchantedPlayer) batch.add(assignment); return batch; }
@Override public MagicSet evaluate(GameState state, Identified thisObject) { MagicSet allAttackers = Attacking.get(state); if (this.what == null) return allAttackers; Set<Integer> beingAttackedIDs = new HashSet<Integer>(); MagicSet evaluateWhat = this.what.evaluate(state, thisObject); for (GameObject o : evaluateWhat.getAll(GameObject.class)) if (o.getTypes().contains(Type.PLANESWALKER)) beingAttackedIDs.add(o.ID); for (Player p : evaluateWhat.getAll(Player.class)) beingAttackedIDs.add(p.ID); Set<GameObject> attackingThisPlayer = allAttackers.getAll(GameObject.class); Iterator<GameObject> objectIterator = attackingThisPlayer.iterator(); while (objectIterator.hasNext()) { GameObject attacker = objectIterator.next(); if (!beingAttackedIDs.contains(attacker.getAttackingID())) objectIterator.remove(); } return new MagicSet(attackingThisPlayer); }
@Override protected boolean match(GameState state, Event event) { if (event.type != EventType.MOVE_BATCH) return false; for (ZoneChange change : event .parametersNow .get(EventType.Parameter.TARGET) .evaluate(state, null) .getAll(ZoneChange.class)) { if (state.battlefield().ID != change.destinationZoneID) continue; GameObject object = state.get(change.newObjectID); if (!object.getColors().contains(Color.GREEN) || !object.getTypes().contains(Type.CREATURE)) continue; return true; } return false; }
@Override public MagicSet evaluate(GameState state, Identified thisObject) { MagicSet ret = new MagicSet(); MagicSet what = this.what.evaluate(state, thisObject); auras: for (GameObject aura : state.getAllObjects()) { if (!aura.getSubTypes().contains(SubType.AURA)) continue; for (Keyword ability : aura.getKeywordAbilities()) if (ability.isEnchant()) { Enchant e = (Enchant) ability; MagicSet intermediate = new MagicSet(what); intermediate.retainAll(e.filter.evaluate(state, aura)); for (GameObject o : intermediate.getAll(GameObject.class)) if (!o.cantBeAttachedBy().match(state, thisObject, new MagicSet(aura))) { ret.add(aura); continue auras; } } } return ret; }
@Override public boolean perform(Game game, Event event, Map<Parameter, MagicSet> parameters) { GameObject permanent = parameters.get(Parameter.PERMANENT).getOne(GameObject.class); Player owner = permanent.getOwner(game.actualState); Zone graveyard = owner.getGraveyard(game.actualState); Map<Parameter, MagicSet> moveParameters = new HashMap<Parameter, MagicSet>(); moveParameters.put(Parameter.CAUSE, parameters.get(Parameter.CAUSE)); moveParameters.put(Parameter.TO, new MagicSet(graveyard)); moveParameters.put(Parameter.OBJECT, new MagicSet(permanent)); // move the permanent to the graveyard Event move = createEvent( game, "Put " + permanent + " in " + owner + "'s graveyard.", MOVE_OBJECTS, moveParameters); boolean status = move.perform(event, false); event.setResult(move.getResultGenerator()); return status; }
@Override public boolean perform(Game game, Event event, java.util.Map<Parameter, Set> parameters) { Set result = new Set(); Identified producer = parameters.get(Parameter.SOURCE).getOne(Identified.class); java.util.Set<Color> colors = parameters.get(Parameter.MANA).getAll(Color.class); java.util.Set<ManaSymbol.ManaType> types = parameters.get(Parameter.MANA).getAll(ManaSymbol.ManaType.class); ManaPool pool = new ManaPool(); ManaSymbol addition = new ManaSymbol(""); addition.colors.addAll(colors); for (ManaSymbol.ManaType type : types) { if (ManaSymbol.ManaType.COLORLESS == type) { addition.colorless = 1; addition.name += "1"; } else { Color color = type.getColor(); addition.colors.add(color); addition.name += color.getLetter(); } } if (!addition.isZero()) pool.add(addition); pool.addAll(parameters.get(Parameter.MANA).getAll(ManaSymbol.class)); int multiply = 1; if (parameters.containsKey(Parameter.MULTIPLY)) multiply = Sum.get(parameters.get(Parameter.MULTIPLY)); if (multiply != 1) { ManaPool newPool = new ManaPool(); if (multiply > 1) { newPool.addAll(pool); for (ManaSymbol symbol : pool) for (int i = 1; i < multiply; ++i) newPool.add(symbol.create()); } pool = newPool; } int number = 1; if (parameters.containsKey(Parameter.NUMBER)) number = Sum.get(parameters.get(Parameter.NUMBER)); boolean snow = false; if (producer.isGameObject()) snow = ((GameObject) producer).getSuperTypes().contains(SuperType.SNOW); for (Player actualPlayer : parameters.get(Parameter.PLAYER).getAll(Player.class)) { Player physicalPlayer = actualPlayer.getPhysical(); java.util.Set<CostCollection> choices = pool.explode("Add"); // TODO : Ticket 430 ManaPool chosen = null; if (choices.isEmpty()) // empty pool to start with chosen = pool; else if (choices.size() == 1) chosen = choices.iterator().next().manaCost; else { // if all of the choices are mana of a single color, present // it as a color choice boolean allSingleColorSymbols = true; for (CostCollection choiceCollection : choices) { ManaPool choice = choiceCollection.manaCost; if (choice.converted() != 1) { allSingleColorSymbols = false; break; } ManaSymbol symbol = choice.first(); if (symbol.colorless != 0) { allSingleColorSymbols = false; break; } if (symbol.colors.size() != 1) { allSingleColorSymbols = false; break; } } if (allSingleColorSymbols) { java.util.Set<Color> colorChoices = java.util.EnumSet.noneOf(Color.class); for (CostCollection choice : choices) colorChoices.add(choice.manaCost.first().colors.iterator().next()); Color chosenColor = physicalPlayer.chooseColor(colorChoices, producer.ID); ManaSymbol s = pool.first().create(); s.colors = java.util.EnumSet.of(chosenColor); s.colorless = 0; chosen = new ManaPool(java.util.Collections.singleton(s)); } else chosen = physicalPlayer .sanitizeAndChoose( game.actualState, 1, choices, PlayerInterface.ChoiceType.MANA_EXPLOSION, PlayerInterface.ChooseReason.HYBRID_MANA) .iterator() .next() .manaCost; } for (int i = 0; i < number; ++i) { // Use the reference mana to create a new mana to // add to the pool for (ManaSymbol newMana : chosen) { newMana = newMana.create(); newMana.sourceID = producer.ID; newMana.isSnow = snow; physicalPlayer.pool.add(newMana); result.add(newMana); if (game.currentAction != null) game.currentAction.manaProduced.add(newMana); } } } GameObject source = event.getSource(); if (source.isActivatedAbility()) ((ActivatedAbility) source.getPhysical()).addedMana(result.getAll(ManaSymbol.class)); event.setResult(Identity.instance(result)); return true; }
public static MagicSet get(GameState state) { MagicSet ret = new MagicSet(); for (GameObject o : state.battlefield()) if (-1 != o.getAttackingID()) ret.add(o); return ret; }
@Override public boolean perform(Game game, Event event, java.util.Map<Parameter, Set> parameters) { GameObject object = parameters.get(Parameter.OBJECT).getOne(GameObject.class); Identified newTarget = parameters.get(Parameter.TARGET).getOne(Identified.class); java.util.Set<Target> canBeChanged = new java.util.HashSet<Target>(); java.util.Map<Target, Boolean> wasLegal = new java.util.HashMap<Target, Boolean>(); java.util.Map<Target, java.util.List<Target>> allChosenTargets = new java.util.HashMap<Target, java.util.List<Target>>(); for (java.util.Map<Target, java.util.List<Target>> chosenTargets : object.getChosenTargets()) allChosenTargets.putAll(chosenTargets); // Introduce this scope because there are two variables named // 'restricted' { java.util.Set<Integer> restricted = new java.util.HashSet<Integer>(); for (Mode checkMode : object.getSelectedModes()) { for (Target checkBaseTarget : checkMode.targets) { java.util.Set<Integer> thisBaseTarget = new java.util.HashSet<Integer>(); for (Target checkTarget : allChosenTargets.get(checkBaseTarget)) { Set legalCheck = checkTarget.legalChoicesNow(game, object); boolean legal = !(restricted.contains(checkTarget.targetID) || !legalCheck.contains(game.actualState.get(checkTarget.targetID))); wasLegal.put(checkTarget, legal); if (checkTarget.restrictFromLaterTargets) restricted.add(checkTarget.targetID); thisBaseTarget.add(checkTarget.targetID); } } } } for (Mode mode : object.getSelectedModes()) { for (Target baseTarget : mode.targets) { for (Target target : allChosenTargets.get(baseTarget)) { Set targets = target.legalChoicesNow(game, object); if (targets.contains(newTarget)) { // The target won't "change" if its already set to // this target. if (target.targetID == newTarget.ID) continue; int oldValue = target.targetID; target.targetID = newTarget.ID; boolean illegal = false; java.util.Set<Integer> restricted = new java.util.HashSet<Integer>(); legalityCheck: for (Mode checkMode : object.getSelectedModes()) { for (Target checkBaseTarget : checkMode.targets) { java.util.Set<Integer> thisBaseTarget = new java.util.HashSet<Integer>(); for (Target checkTarget : allChosenTargets.get(checkBaseTarget)) { Set legalCheck = checkTarget.legalChoicesNow(game, object); boolean targetWasLegal = wasLegal.get(checkTarget); if (targetWasLegal && (thisBaseTarget.contains(checkTarget.targetID) || restricted.contains(checkTarget.targetID) || !legalCheck.contains(game.actualState.get(checkTarget.targetID)))) { illegal = true; break legalityCheck; } if (checkTarget.restrictFromLaterTargets) restricted.add(checkTarget.targetID); thisBaseTarget.add(checkTarget.targetID); } } } target.targetID = oldValue; if (!illegal) { canBeChanged.add(target); } } } } } Player player = parameters.get(Parameter.PLAYER).getOne(Player.class); java.util.List<Target> choice = player.sanitizeAndChoose( game.actualState, 1, canBeChanged, PlayerInterface.ChoiceType.SINGLE_TARGET, PlayerInterface.ChooseReason.TARGET); if (!choice.isEmpty()) { event.setResult(Identity.instance(object)); Target chosenTarget = choice.get(0); chosenTarget.targetID = newTarget.ID; // Also set the target on the physical object java.util.Map<Target, java.util.List<Target>>[] chosenTargets = object.getChosenTargets(); setPhysicalTarget: for (int sideNumber = 0; sideNumber < object.getChosenTargets().length; ++sideNumber) for (java.util.Map.Entry<Target, java.util.List<Target>> entry : chosenTargets[sideNumber].entrySet()) { for (int targetNumber = 0; targetNumber < entry.getValue().size(); ++targetNumber) { if (entry.getValue().get(targetNumber) == chosenTarget) { GameObject physical = object.getPhysical(); physical .getChosenTargets()[sideNumber] .get(entry.getKey()) .get(targetNumber) .targetID = newTarget.ID; break setPhysicalTarget; } } } } else { event.setResult(Identity.instance()); } return choice.size() == 1; }
@Test public void tarmogoyf() { this.addDeck( Tarmogoyf.class, Tarmogoyf.class, Tarmogoyf.class, BlackLotus.class, BlackLotus.class, Shock.class, Shock.class); this.addDeck( Plains.class, Plains.class, Plains.class, Plains.class, Plains.class, Plains.class, Plains.class); startGame(new Open()); respondWith(getPlayer(0)); keep(); keep(); // pass upkeep pass(); pass(); respondWith(getSpellAction(BlackLotus.class)); pass(); pass(); respondWith(getSpellAction(Tarmogoyf.class)); respondWith(getAbilityAction(BlackLotus.BlackLotusMana.class)); respondWith(Color.GREEN); donePlayingManaAbilities(); respondWith(getMana(Color.GREEN, Color.GREEN)); pass(); pass(); assertTrue(this.game.actualState.battlefield().objects.get(0).getName().equals("Tarmogoyf")); assertEquals(1, this.game.actualState.battlefield().objects.get(0).getPower()); assertEquals(2, this.game.actualState.battlefield().objects.get(0).getToughness()); respondWith(getSpellAction(BlackLotus.class)); pass(); pass(); respondWith(getSpellAction(Shock.class)); respondWith(getTarget(Tarmogoyf.class)); respondWith(getAbilityAction(BlackLotus.BlackLotusMana.class)); respondWith(Color.RED); donePlayingManaAbilities(); respondWith(getMana(Color.RED)); pass(); pass(); assertTrue(this.game.actualState.battlefield().objects.get(0).getName().equals("Tarmogoyf")); assertEquals(2, this.game.actualState.battlefield().objects.get(0).getPower()); assertEquals(3, this.game.actualState.battlefield().objects.get(0).getToughness()); assertEquals(2, this.game.actualState.battlefield().objects.get(0).getDamage()); respondWith(getSpellAction(Shock.class)); respondWith(getTarget(Tarmogoyf.class)); donePlayingManaAbilities(); respondWith(getMana(Color.RED)); pass(); pass(); // tarmogoyf should be 3/4 and dead -- it counts itself since it's in // the yard now! GameObject tarmy = this.game.actualState.get(getGraveyard(0).objects.get(0).ID); assertEquals(0, this.game.actualState.battlefield().objects.size()); assertTrue(tarmy.getName().equals("Tarmogoyf")); assertEquals(3, tarmy.getPower()); assertEquals(4, tarmy.getToughness()); }