diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PartyCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PartyCount.java index 58b5acce234..d2e0ed94927 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PartyCount.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PartyCount.java @@ -17,12 +17,99 @@ import java.util.stream.Collectors; public enum PartyCount implements DynamicValue { instance; + private static final List partyTypes = Arrays.asList( + SubType.CLERIC, + SubType.ROGUE, + SubType.WARRIOR, + SubType.WIZARD + ); + + private static final class CreatureTypes { + + private final Set subTypeSet = new HashSet<>(); + + private CreatureTypes(Permanent permanent, Game game) { + for (SubType subType : partyTypes) { + if (permanent.hasSubtype(subType, game)) { + subTypeSet.add(subType); + } + } + } + + private int count() { + return subTypeSet.size(); + } + + private void removeAll(Set subTypes) { + this.subTypeSet.removeAll(subTypes); + } + + public Set getSubTypeSet() { + return subTypeSet; + } + } + @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { - // TODO: implement this (in separate branch for now) + List creatureTypesList = game.getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, + sourceAbility.getControllerId(), sourceAbility.getSourceId(), game + ).stream() + .map(permanent -> new CreatureTypes(permanent, game)) + .collect(Collectors.toList()); + Set subTypeSet = new HashSet<>(); + boolean flag = true; + while (flag) { + List creatureTypesList2 = new ArrayList<>(); + // Find all creatures with only one of the creature types and eliminate those + for (CreatureTypes creatureTypes : creatureTypesList) { + switch (creatureTypes.count()) { + case 0: + break; + case 1: + subTypeSet.addAll(creatureTypes.getSubTypeSet()); + flag = false; + break; + default: + creatureTypesList2.add(creatureTypes); + } + } + // Now find all the creature types only represented by one creature and eliminate those + for (SubType subType : partyTypes) { + if (!subTypeSet.contains(subType) && creatureTypesList2.stream().map(CreatureTypes::getSubTypeSet).mapToInt(s -> s.contains(subType) ? 1 : 0).sum() == 1) { + subTypeSet.add(subType); + flag = false; + } + } + // Remove all the eliminated creature types from the creatures and now we have less to analyze + creatureTypesList.clear(); + for (CreatureTypes creatureTypes : creatureTypesList2) { + creatureTypes.removeAll(subTypeSet); + if (creatureTypes.count() > 0) { + creatureTypesList.add(creatureTypes); + } + } + } + if (creatureTypesList.isEmpty()) { + return subTypeSet.size(); + } + // Not sure what to do here return 0; } + private static int typeCount(Permanent permanent, Game game) { + return partyTypes.stream().mapToInt(subType -> permanent.hasSubtype(subType, game) ? 1 : 0).sum(); + } + + private static void addType(Permanent permanent, Set subTypeSet, Game game) { + for (SubType subType : partyTypes) { + if (permanent.hasSubtype(subType, game)) { + subTypeSet.add(subType); + } + } + } + @Override public PartyCount copy() { return instance;