* Improved mana source check. Fixed #1513.

This commit is contained in:
LevelX2 2016-02-14 18:31:02 +01:00
parent 6726f48669
commit 74799d286b
19 changed files with 294 additions and 170 deletions

View file

@ -343,11 +343,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
target.add(abilityControllerId, game);
return true;
}
} else {
if (target.canTarget(randomOpponentId, null, game)) {
target.add(randomOpponentId, game);
return true;
}
} else if (target.canTarget(randomOpponentId, null, game)) {
target.add(randomOpponentId, game);
return true;
}
if (!target.isRequired(sourceId, game)) {
return false;
@ -378,11 +376,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
target.add(abilityControllerId, game);
return true;
}
} else {
if (target.canTarget(randomOpponentId, null, game)) {
target.add(randomOpponentId, game);
return true;
}
} else if (target.canTarget(randomOpponentId, null, game)) {
target.add(randomOpponentId, game);
return true;
}
if (!target.isRequired(sourceId, game) || target.getNumberOfTargets() == 0) {
return false;
@ -580,11 +576,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
target.addTarget(abilityControllerId, source, game);
return true;
}
} else {
if (target.canTarget(getId(), randomOpponentId, source, game)) {
target.addTarget(randomOpponentId, source, game);
return true;
}
} else if (target.canTarget(getId(), randomOpponentId, source, game)) {
target.addTarget(randomOpponentId, source, game);
return true;
}
}
@ -606,11 +600,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
target.addTarget(abilityControllerId, source, game);
return true;
}
} else {
if (target.canTarget(getId(), randomOpponentId, source, game)) {
target.addTarget(randomOpponentId, source, game);
return true;
}
} else if (target.canTarget(getId(), randomOpponentId, source, game)) {
target.addTarget(randomOpponentId, source, game);
return true;
}
//if (!target.isRequired())
@ -1024,10 +1016,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
playableNonInstant.add(card);
}
}
} else {
if (!playableInstant.contains(card) && !playableNonInstant.contains(card)) {
unplayable.put(mana.needed(avail), card);
}
} else if (!playableInstant.contains(card) && !playableNonInstant.contains(card)) {
unplayable.put(mana.needed(avail), card);
}
}
}
@ -1045,7 +1035,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
option.add(Mana.GenericMana(3));
}
}
if (abilityOptions.size() == 0) {
if (abilityOptions.isEmpty()) {
playableAbilities.add(ability);
} else {
for (Mana mana : abilityOptions) {
@ -1063,7 +1053,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.GRAVEYARD)) {
if (ability.canActivate(playerId, game)) {
ManaOptions abilityOptions = ability.getManaCosts().getOptions();
if (abilityOptions.size() == 0) {
if (abilityOptions.isEmpty()) {
playableAbilities.add(ability);
} else {
for (Mana mana : abilityOptions) {
@ -1096,7 +1086,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
// log.info("paying for " + unpaid.getText());
boolean spendAnyMana = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
ManaCost cost;
List<Permanent> producers;
List<MageObject> producers;
if (unpaid instanceof ManaCosts) {
ManaCosts<ManaCost> manaCosts = (ManaCosts<ManaCost>) unpaid;
cost = manaCosts.get(manaCosts.size() - 1);
@ -1106,11 +1096,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
producers = this.getAvailableManaProducers(game);
producers.addAll(this.getAvailableManaProducersWithCost(game));
}
for (Permanent perm : producers) {
for (MageObject mageObject : producers) {
// use color producing mana abilities with costs first that produce all color manas that are needed to pay
// otherwise the computer may not be able to pay the cost for that source
ManaAbility:
for (ManaAbility manaAbility : perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (ManaAbility manaAbility : mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
int colored = 0;
for (Mana mana : manaAbility.getNetMana(game)) {
if (!unpaid.getMana().includesMana(mana)) {
@ -1131,9 +1121,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
for (Permanent perm : producers) {
for (MageObject mageObject : producers) {
// pay all colored costs first
for (ManaAbility manaAbility : perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (ManaAbility manaAbility : mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
if (cost instanceof ColoredManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyMana) {
@ -1145,7 +1135,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// then pay hybrid
for (ManaAbility manaAbility : perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (ManaAbility manaAbility : mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
if (cost instanceof HybridManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyMana) {
@ -1157,7 +1147,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// then pay mono hybrid
for (ManaAbility manaAbility : perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (ManaAbility manaAbility : mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
if (cost instanceof MonoHybridManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyMana) {
@ -1169,7 +1159,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// pay colorless
for (ManaAbility manaAbility : perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (ManaAbility manaAbility : mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
if (cost instanceof ColorlessManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyMana) {
@ -1181,7 +1171,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// finally pay generic
for (ManaAbility manaAbility : perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (ManaAbility manaAbility : mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
if (cost instanceof GenericManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyMana) {
@ -1216,15 +1206,15 @@ public class ComputerPlayer extends PlayerImpl implements Player {
* @param game
* @return List<Permanent>
*/
private List<Permanent> getSortedProducers(ManaCosts<ManaCost> unpaid, Game game) {
List<Permanent> unsorted = this.getAvailableManaProducers(game);
private List<MageObject> getSortedProducers(ManaCosts<ManaCost> unpaid, Game game) {
List<MageObject> unsorted = this.getAvailableManaProducers(game);
unsorted.addAll(this.getAvailableManaProducersWithCost(game));
Map<Permanent, Integer> scored = new HashMap<>();
for (Permanent permanent : unsorted) {
Map<MageObject, Integer> scored = new HashMap<>();
for (MageObject mageObject : unsorted) {
int score = 0;
for (ManaCost cost : unpaid) {
Abilities:
for (ManaAbility ability : permanent.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (ManaAbility ability : mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) {
for (Mana netMana : ability.getNetMana(game)) {
if (cost.testPay(netMana)) {
score++;
@ -1234,29 +1224,29 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
if (score > 0) { // score mana producers that produce other mana types and have other uses higher
score += permanent.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game).size();
score += permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD).size();
if (!permanent.getCardType().contains(CardType.LAND)) {
score += mageObject.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game).size();
score += mageObject.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD).size();
if (!mageObject.getCardType().contains(CardType.LAND)) {
score += 2;
} else if (permanent.getCardType().contains(CardType.CREATURE)) {
} else if (mageObject.getCardType().contains(CardType.CREATURE)) {
score += 2;
}
}
scored.put(permanent, score);
scored.put(mageObject, score);
}
return sortByValue(scored);
}
private List<Permanent> sortByValue(Map<Permanent, Integer> map) {
List<Entry<Permanent, Integer>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Entry<Permanent, Integer>>() {
private List<MageObject> sortByValue(Map<MageObject, Integer> map) {
List<Entry<MageObject, Integer>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Entry<MageObject, Integer>>() {
@Override
public int compare(Entry<Permanent, Integer> o1, Entry<Permanent, Integer> o2) {
public int compare(Entry<MageObject, Integer> o1, Entry<MageObject, Integer> o2) {
return (o1.getValue().compareTo(o2.getValue()));
}
});
List<Permanent> result = new ArrayList<>();
for (Entry<Permanent, Integer> entry : list) {
List<MageObject> result = new ArrayList<>();
for (Entry<MageObject, Integer> entry : list) {
result.add(entry.getKey());
}
return result;
@ -1595,7 +1585,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
@Override
public List<Permanent> getAvailableManaProducers(Game game) {
public List<MageObject> getAvailableManaProducers(Game game) {
return super.getAvailableManaProducers(game);
}
@ -2174,11 +2164,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
target.add(randomOpponentId, game);
return true;
}
} else {
if (((TargetOpponent) target).canTarget(randomOpponentId, source, game)) {
target.add(randomOpponentId, game);
return true;
}
} else if (((TargetOpponent) target).canTarget(randomOpponentId, source, game)) {
target.add(randomOpponentId, game);
return true;
}
for (UUID currentId : game.getOpponents(abilityControllerId)) {
if (source == null) {
@ -2186,11 +2174,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
target.add(currentId, game);
return true;
}
} else {
if (((TargetOpponent) target).canTarget(currentId, source, game)) {
target.add(currentId, game);
return true;
}
} else if (((TargetOpponent) target).canTarget(currentId, source, game)) {
target.add(currentId, game);
return true;
}
}
return false;
@ -2222,29 +2208,27 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
} else if (source == null) {
if (target.canTarget(randomOpponentId, game)) {
target.add(randomOpponentId, game);
return true;
}
if (target.isRequired(sourceId, game)) {
if (target.canTarget(abilityControllerId, game)) {
target.add(abilityControllerId, game);
return true;
}
}
} else {
if (source == null) {
if (target.canTarget(randomOpponentId, game)) {
target.add(randomOpponentId, game);
if (target.canTarget(randomOpponentId, game)) {
target.add(randomOpponentId, game);
return true;
}
if (target.isRequired(sourceId, game)) {
if (target.canTarget(abilityControllerId, game)) {
target.add(abilityControllerId, game);
return true;
}
if (target.isRequired(sourceId, game)) {
if (target.canTarget(abilityControllerId, game)) {
target.add(abilityControllerId, game);
return true;
}
}
} else {
if (target.canTarget(randomOpponentId, game)) {
target.add(randomOpponentId, game);
return true;
}
if (target.isRequired(sourceId, game)) {
if (target.canTarget(abilityControllerId, game)) {
target.add(abilityControllerId, game);
return true;
}
}
}
}
return false;