package magic.model.choice; import magic.model.MagicCostManaType; import magic.model.MagicManaCost; import java.util.Arrays; import java.util.List; public class MagicBuilderManaCost { public static final MagicBuilderManaCost ZERO_COST=new MagicBuilderManaCost(); private final int[] amounts; private MagicCostManaType[] compressedTypes; private int[] compressedAmounts; private int typeCount; private int minimumAmount; private int XCount; public MagicBuilderManaCost() { amounts=new int[MagicCostManaType.NR_OF_TYPES]; compressedTypes=new MagicCostManaType[0]; compressedAmounts=new int[0]; typeCount=0; minimumAmount=0; XCount=0; } public MagicBuilderManaCost(final MagicManaCost cost) { this(); cost.addTo(this); } public MagicBuilderManaCost(final MagicBuilderManaCost cost) { amounts=Arrays.copyOf(cost.amounts,cost.amounts.length); compressedTypes=Arrays.copyOf(cost.compressedTypes,cost.compressedTypes.length); compressedAmounts=Arrays.copyOf(cost.compressedAmounts,cost.compressedAmounts.length); typeCount=cost.typeCount; minimumAmount=cost.minimumAmount; XCount=cost.XCount; } public void compress() { typeCount = 0; for (final int amt : amounts) { if (amt != 0) { typeCount++; } } compressedTypes=new MagicCostManaType[typeCount]; compressedAmounts=new int[typeCount]; int j=0; // Ordered from most restrictive to least restrictive. for (int i = MagicCostManaType.NR_OF_TYPES - 1; i >= 0; i--) { final int amt = amounts[i]; if (amt != 0) { compressedTypes[j]=MagicCostManaType.values()[i]; compressedAmounts[j]=amt; j++; } } } public MagicCostManaType[] getTypes() { return compressedTypes; } public int[] getAmounts() { return compressedAmounts; } public int getMinimumAmount() { return minimumAmount; } boolean hasX() { return XCount > 0; } public void setXCount(final int amount) { addType(MagicCostManaType.Generic,amount); XCount = amount; } int getX(final int amount) { return hasX() ? (amount - minimumAmount) / XCount + 1 : 0; } boolean validX(final int amount) { return ((amount - compressedAmounts[typeCount - 1]) % XCount) == 0; } public boolean isEmpty() { return typeCount == 0; } public void addType(final MagicCostManaType type,final int amount) { assert type == MagicCostManaType.Generic || amount >= 0 : "amount of mana to add is negative: " + type + ", " + amount; final int i = type.ordinal(); amounts[i] += amount; minimumAmount += amount; } public void removeType(final MagicCostManaType type,final int amount) { assert amount >= 0 : "amount of mana to add is negative: " + type + ", " + amount; final int i = type.ordinal(); amounts[i] -= amount; minimumAmount -= amount; assert amounts[i] >= 0 : "amounts[i] is negative: amounts[i] = " + amounts[i]; } void addTypes(final List<MagicCostManaType> types) { for (final MagicCostManaType type : types) { addType(type,1); } compress(); } @Override public String toString() { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < compressedTypes.length; i++) { builder .append(compressedTypes[i]) .append('=') .append(compressedAmounts[i]) .append(' '); } builder .append("Total=") .append(minimumAmount); return builder.toString(); } }