package magic.model.choice; import magic.model.MagicAbility; import magic.model.MagicGame; import magic.model.MagicPermanent; import magic.model.MagicPlayer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.SortedSet; public class MagicDeclareAttackersResultBuilder { private static final Collection<Object> EMPTY_RESULT=Collections.<Object>singletonList(new MagicDeclareAttackersResult()); private static final int[] MAX_ATTACKERS={5,4,3,2,1,0,0,0}; static Collection<Object> buildResults(final MagicGame game, final MagicPlayer attackingPlayer) { final MagicPlayer defendingPlayer = attackingPlayer.getOpponent(); final MagicCombatCreatureBuilder creatureBuilder=new MagicCombatCreatureBuilder(game,attackingPlayer,defendingPlayer); creatureBuilder.buildBlockers(); // Check if none of the attacking player's creatures can attack. if (!creatureBuilder.buildAttackers()) { return EMPTY_RESULT; } // Remove creatures that have zero power. // Remove creatures that must attack if able and add them to result. final SortedSet<MagicCombatCreature> attackersSet=creatureBuilder.getAttackers(); final MagicPermanent[] current=new MagicPermanent[attackersSet.size()]; int count=0; for (final Iterator<MagicCombatCreature> iterator=attackersSet.iterator();iterator.hasNext();) { final MagicCombatCreature attacker=iterator.next(); if (attacker.hasAbility(MagicAbility.AttacksEachTurnIfAble)) { current[count++]=attacker.permanent; iterator.remove(); } else if (attacker.power<=0) { iterator.remove(); } } final int maxAttackers = game.getRelativeTurn() < MAX_ATTACKERS.length ? MAX_ATTACKERS[game.getRelativeTurn()] : 0; int size=attackersSet.size(); // Single result with the required attackers only. if (maxAttackers==0||size==0) { return Collections.<Object>singletonList(new MagicDeclareAttackersResult(current,count)); } // Build results. final Collection<Object> results=new ArrayList<Object>(); // Get the best remaining optional attackers. while (size>maxAttackers) { // Add option to attack with all creatures for an alpha strike. final MagicDeclareAttackersResult result=new MagicDeclareAttackersResult(current,count); result.addCreatures(attackersSet); results.add(result); // Remove worst attacker. size--; attackersSet.remove(attackersSet.first()); } final MagicCombatCreature[] attackers=new MagicCombatCreature[size]; attackersSet.toArray(attackers); // Build all possible combinations of attackers. final int[] step=new int[size]; int index=0; while (index>=0) { if (index==size) { results.add(new MagicDeclareAttackersResult(current,count)); index--; continue; } switch (step[index]++) { case 0: current[count++]=attackers[index++].permanent; break; case 1: count--; index++; break; case 2: step[index--]=0; break; } } return results; } }