[Simulated AI] Support modal spells where allowRepeat is true. (e.g. C15 confluence cycle)

This commit is contained in:
Myrd
2017-01-02 00:29:56 +00:00
parent 939a1b4a53
commit 0c6a7bbd18

View File

@@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.apache.commons.math3.util.CombinatoricsUtils;
@@ -328,10 +329,53 @@ public class SpellAbilityPicker {
private Card selectedChoice;
private Score bestScoreForChoice = new Score(Integer.MIN_VALUE);
public List<AbilitySub> chooseModesForAbility(List<AbilitySub> choices, int min, int num, boolean allowRepeat) {
public List<AbilitySub> chooseModesForAbility(List<AbilitySub> choices, final int min, final int num, boolean allowRepeat) {
if (modeIterator == null) {
// TODO: Below doesn't support allowRepeat!
modeIterator = CombinatoricsUtils.combinationsIterator(choices.size(), num);
// TODO: Need to skip modes that are invalid (e.g. targets don't exist)!
// TODO: Do we need to do something special to support cards that have extra costs
// when choosing more modes, like Blessed Alliance?
if (!allowRepeat) {
modeIterator = CombinatoricsUtils.combinationsIterator(choices.size(), num);;
} else {
// Note: When allowRepeat is true, it does result in many possibilities being tried.
// We should ideally prune some of those at a higher level.
final int numChoices = choices.size();
modeIterator = new Iterator<int[]>() {
int[] indexes = new int[min];
@Override
public boolean hasNext() {
return indexes != null;
}
// Note: This returns a new int[] array and doesn't modify indexes in place,
// since that gets returned to the caller.
private int[] getNextIndexes() {
for (int i = indexes.length - 1; i >= 0; i--) {
if (indexes[i] < numChoices - 1) {
int[] nextIndexes = new int[indexes.length];
System.arraycopy(indexes, 0, nextIndexes, 0, i);
nextIndexes[i] = indexes[i] + 1;
return nextIndexes;
}
}
if (indexes.length < num) {
return new int[indexes.length + 1];
}
return null;
}
@Override
public int[] next() {
if (indexes == null) {
throw new NoSuchElementException();
}
int[] result = indexes;
indexes = getNextIndexes();
return result;
}
};
}
selectedModes = modeIterator.next();
advancedToNextMode = true;
}