package magic.model.choice;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import magic.ai.ArtificialScoringSystem;
import magic.model.MagicAbility;
import magic.model.MagicGame;
import magic.model.MagicPermanent;
import magic.model.MagicPowerToughness;
public class MagicCombatCreature {
public final MagicPermanent permanent;
public final int score;
public final int power;
public final int lethalDamage;
public final boolean normalDamage;
public MagicCombatCreature[] candidateBlockers = new MagicCombatCreature[0];
int attackerScore;
private final Set<MagicAbility> flags;
MagicCombatCreature(final MagicPermanent permanent) {
this.permanent = permanent;
this.score = permanent.getScore();
final MagicPowerToughness pt = permanent.getPowerToughness();
lethalDamage = permanent.getLethalDamage(pt.toughness());
flags = permanent.getAbilityFlags();
power = flags.contains(MagicAbility.DoubleStrike) ?
pt.getPositivePower() * 2 :
pt.getPositivePower();
normalDamage =
!flags.contains(MagicAbility.Deathtouch) &&
!flags.contains(MagicAbility.Wither) &&
!flags.contains(MagicAbility.Infect);
}
MagicCombatCreature(final MagicGame game,final MagicCombatCreature creature) {
permanent=creature.permanent.map(game);
score=creature.score;
power=creature.power;
lethalDamage=creature.lethalDamage;
flags=creature.flags;
normalDamage=creature.normalDamage;
}
public boolean hasAbility(final MagicAbility ability) {
return flags.contains(ability);
}
void setAttacker(final MagicGame game,final Set<MagicCombatCreature> blockers) {
final SortedSet<MagicCombatCreature> candidateBlockersSet =
new TreeSet<MagicCombatCreature>(new BlockerComparator(this));
for (final MagicCombatCreature blocker : blockers) {
if (blocker.permanent.canBlock(permanent)) {
candidateBlockersSet.add(blocker);
}
}
candidateBlockers=new MagicCombatCreature[candidateBlockersSet.size()];
candidateBlockersSet.toArray(candidateBlockers);
attackerScore=ArtificialScoringSystem.getAttackerScore(this);
}
public String getName() {
return permanent.getName();
}
public String toString() {
final StringBuilder builder=new StringBuilder();
builder.append(permanent.getName());
builder.append('(')
.append(power).append(',')
.append(lethalDamage).append(',')
.append(attackerScore).append(',')
.append(score).append(')');
if (candidateBlockers.length > 0) {
builder.append(" = ").append(Arrays.toString(candidateBlockers));
}
return builder.toString();
}
private static final class BlockerComparator implements Comparator<MagicCombatCreature> {
private final MagicCombatCreature attacker;
public BlockerComparator(final MagicCombatCreature attacker) {
this.attacker=attacker;
}
@Override
public int compare(final MagicCombatCreature blocker1,final MagicCombatCreature blocker2) {
int ldif=blocker1.lethalDamage-blocker2.lethalDamage;
if (attacker.normalDamage) {
final boolean front=blocker1.lethalDamage>attacker.power;
if (front!=blocker2.lethalDamage>attacker.power) {
return front?-1:1;
}
if (front) {
ldif=-ldif;
}
}
if (ldif!=0) {
return ldif;
}
final int pdif=blocker1.power-blocker2.power;
if (pdif!=0) {
return pdif;
}
final int sdif=blocker1.score-blocker2.score;
if (sdif!=0) {
return sdif;
}
return blocker1.permanent.compareTo(blocker2.permanent);
}
};
}