moved some specific code to ai

This commit is contained in:
Maxmtg
2014-02-17 22:19:45 +00:00
parent 204f65faac
commit 22be9fffb6
2 changed files with 120 additions and 120 deletions

View File

@@ -17,6 +17,7 @@ import forge.game.card.CardLists;
import forge.game.card.CardUtil;
import forge.game.cost.Cost;
import forge.game.cost.CostPayment;
import forge.game.mana.Mana;
import forge.game.mana.ManaCostBeingPaid;
import forge.game.mana.ManaPool;
import forge.game.player.Player;
@@ -31,6 +32,7 @@ import forge.util.maps.EnumMapOfLists;
import forge.util.maps.MapOfLists;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import java.util.*;
import java.util.Map.Entry;
@@ -96,7 +98,19 @@ public class ComputerUtilMana {
Collections.sort(unpaidShards); // most difficult shards must come first
for (ManaCostShard part : unpaidShards) {
if (part != ManaCostShard.X) {
manapool.payManaFromPool(sa, cost, part);
if (cost.isPaid()) {
continue;
}
// get a mana of this type from floating, bail if none available
final Mana mana = getMana(ai, part, sa, cost.getSourceRestriction());
if (mana == null) {
continue; // no matching mana in the pool
}
else {
if ( ai.getManaPool().tryPayCostWithMana(sa, cost, mana) && !test)
sa.getManaPaid().add(mana);
}
}
}
@@ -249,6 +263,97 @@ public class ComputerUtilMana {
return true;
} // payManaCost()
/**
* <p>
* getManaFrom.
* </p>
*
* @param saBeingPaidFor
* a {@link forge.game.spellability.SpellAbility} object.
* @return a {@link forge.game.mana.Mana} object.
*/
private static Mana getMana(final Player ai, final ManaCostShard shard, final SpellAbility saBeingPaidFor, String restriction) {
final List<Pair<Mana, Integer>> weightedOptions = selectManaToPayFor(ai.getManaPool(), shard, saBeingPaidFor, restriction);
// Exclude border case
if (weightedOptions.isEmpty()) {
return null; // There is no matching mana in the pool
}
// select equal weight possibilities
List<Mana> manaChoices = new ArrayList<Mana>();
int bestWeight = Integer.MIN_VALUE;
for (Pair<Mana, Integer> option : weightedOptions) {
int thisWeight = option.getRight();
Mana thisMana = option.getLeft();
if (thisWeight > bestWeight) {
manaChoices.clear();
bestWeight = thisWeight;
}
if (thisWeight == bestWeight) {
// add only distinct Mana-s
boolean haveDuplicate = false;
for (Mana m : manaChoices) {
if (m.equals(thisMana)) {
haveDuplicate = true;
break;
}
}
if (!haveDuplicate) {
manaChoices.add(thisMana);
}
}
}
// got an only one best option?
if (manaChoices.size() == 1) {
return manaChoices.get(0);
}
// Let them choose then
return ai.getController().chooseManaFromPool(manaChoices);
}
private static List<Pair<Mana, Integer>> selectManaToPayFor(final ManaPool manapool, final ManaCostShard shard, final SpellAbility saBeingPaidFor, String restriction) {
final List<Pair<Mana, Integer>> weightedOptions = new ArrayList<Pair<Mana, Integer>>();
for (final Mana thisMana : manapool) {
if (!manapool.canPayForShardWithColor(shard, thisMana.getColor())) {
continue;
}
if (thisMana.getManaAbility() != null && !thisMana.getManaAbility().meetsManaRestrictions(saBeingPaidFor)) {
continue;
}
boolean canPay = manapool.canPayForShardWithColor(shard, thisMana.getColor());
if (!canPay || (shard.isSnow() && !thisMana.isSnow())) {
continue;
}
if (StringUtils.isNotBlank(restriction) && !thisMana.getSourceCard().isType(restriction)) {
continue;
}
// prefer colorless mana to spend
int weight = thisMana.isColorless() ? 5 : 0;
// prefer restricted mana to spend
if (thisMana.isRestricted()) {
weight += 2;
}
// Spend non-snow mana first
if (!thisMana.isSnow()) {
weight += 1;
}
weightedOptions.add(Pair.of(thisMana, weight));
}
return weightedOptions;
}
private static void setExpressColorChoice(final SpellAbility sa, final Player ai, ManaCostBeingPaid cost,
ManaCostShard toPay, SpellAbility saPayment) {

View File

@@ -34,11 +34,10 @@ import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
@@ -49,7 +48,7 @@ import java.util.List;
* @author Forge
* @version $Id$
*/
public class ManaPool {
public class ManaPool implements Iterable<Mana> {
private final Multimap<Byte, Mana> floatingMana = ArrayListMultimap.create();
@@ -91,9 +90,6 @@ public class ManaPool {
for (final Mana m : manaList) {
this.addMana(m);
}
// check state effects replaced by checkStaticAbilities
//owner.getGame().getAction().checkStaticAbilities();
}
/**
@@ -140,100 +136,6 @@ public class ManaPool {
return numRemoved;
}
/**
* <p>
* getManaFrom.
* </p>
*
* @param saBeingPaidFor
* a {@link forge.game.spellability.SpellAbility} object.
* @return a {@link forge.game.mana.Mana} object.
*/
private Mana getMana(final ManaCostShard shard, final SpellAbility saBeingPaidFor, String restriction) {
final List<Pair<Mana, Integer>> weightedOptions = selectManaToPayFor(shard, saBeingPaidFor, restriction);
// Exclude border case
if (weightedOptions.isEmpty()) {
return null; // There is no matching mana in the pool
}
// select equal weight possibilities
List<Mana> manaChoices = new ArrayList<Mana>();
int bestWeight = Integer.MIN_VALUE;
for (Pair<Mana, Integer> option : weightedOptions) {
int thisWeight = option.getRight();
Mana thisMana = option.getLeft();
if (thisWeight > bestWeight) {
manaChoices.clear();
bestWeight = thisWeight;
}
if (thisWeight == bestWeight) {
// add only distinct Mana-s
boolean haveDuplicate = false;
for (Mana m : manaChoices) {
if (m.equals(thisMana)) {
haveDuplicate = true;
break;
}
}
if (!haveDuplicate) {
manaChoices.add(thisMana);
}
}
}
// got an only one best option?
if (manaChoices.size() == 1) {
return manaChoices.get(0);
}
// Let them choose then
return owner.getController().chooseManaFromPool(manaChoices);
}
private List<Pair<Mana, Integer>> selectManaToPayFor(final ManaCostShard shard, final SpellAbility saBeingPaidFor, String restriction) {
final List<Pair<Mana, Integer>> weightedOptions = new ArrayList<Pair<Mana, Integer>>();
for (final Byte manaKey : this.floatingMana.keySet()) {
if (!canPayForShardWithColor(shard, manaKey.byteValue())) {
continue;
}
for (final Mana thisMana : this.floatingMana.get(manaKey)) {
if (thisMana.getManaAbility() != null && !thisMana.getManaAbility().meetsManaRestrictions(saBeingPaidFor)) {
continue;
}
boolean canPay = canPayForShardWithColor(shard, thisMana.getColor());
if (!canPay || (shard.isSnow() && !thisMana.isSnow())) {
continue;
}
if (StringUtils.isNotBlank(restriction) && !thisMana.getSourceCard().isType(restriction)) {
continue;
}
// prefer colorless mana to spend
int weight = thisMana.isColorless() ? 5 : 0;
// prefer restricted mana to spend
if (thisMana.isRestricted()) {
weight += 2;
}
// Spend non-snow mana first
if (!thisMana.isSnow()) {
weight += 1;
}
weightedOptions.add(Pair.of(thisMana, weight));
}
}
return weightedOptions;
}
/**
* <p>
* removeManaFrom.
@@ -249,21 +151,6 @@ public class ManaPool {
}
}
public final void payManaFromPool(final SpellAbility saBeingPaidFor, final ManaCostBeingPaid manaCost, final ManaCostShard manaShard) {
if (manaCost.isPaid()) {
return;
}
// get a mana of this type from floating, bail if none available
final Mana mana = this.getMana(manaShard, saBeingPaidFor, manaCost.getSourceRestriction());
if (mana == null) {
return; // no matching mana in the pool
}
else {
tryPayCostWithMana(saBeingPaidFor, manaCost, mana);
}
}
/**
* <p>
* subtractManaFromAbility.
@@ -283,7 +170,8 @@ public class ManaPool {
paidAbs.add(saPayment); // assumes some part on the mana produced by the ability will get used
for (final Mana mana : abManaPart.getLastManaProduced()) {
tryPayCostWithMana(saPaidFor, manaCost, mana);
if( tryPayCostWithMana(saPaidFor, manaCost, mana) )
saPaidFor.getManaPaid().add(mana);
}
}
@@ -306,7 +194,10 @@ public class ManaPool {
}
return manaFound != null && tryPayCostWithMana(saPaidFor, manaCost, manaFound);
boolean result = manaFound != null && tryPayCostWithMana(saPaidFor, manaCost, manaFound);
if(result)
saPaidFor.getManaPaid().add(manaFound);
return result;
}
@@ -329,7 +220,6 @@ public class ManaPool {
mana.getManaAbility().createETBCounters(sa.getHostCard());
}
}
sa.getManaPaid().add(mana);
return true;
}
@@ -480,4 +370,9 @@ public class ManaPool {
}
return shard.canBePaidWithManaOfColor((byte)0);
}
@Override
public Iterator<Mana> iterator() {
return floatingMana.values().iterator();
}
}