verifyTransitivity on saComparator

This commit is contained in:
Hans Mackowiak
2019-10-11 19:03:15 +00:00
committed by Michael Kamensky
parent 3ea93ac9b4
commit fb159a6261
2 changed files with 71 additions and 1 deletions

View File

@@ -59,6 +59,7 @@ import forge.item.PaperCard;
import forge.util.Aggregates; import forge.util.Aggregates;
import forge.util.Expressions; import forge.util.Expressions;
import forge.util.MyRandom; import forge.util.MyRandom;
import forge.util.ComparatorUtil;
import forge.util.collect.FCollectionView; import forge.util.collect.FCollectionView;
import io.sentry.Sentry; import io.sentry.Sentry;
import io.sentry.event.BreadcrumbBuilder; import io.sentry.event.BreadcrumbBuilder;
@@ -609,6 +610,7 @@ public class AiController {
ComputerUtilAbility.getAvailableCards(game, player); ComputerUtilAbility.getAvailableCards(game, player);
List<SpellAbility> all = ComputerUtilAbility.getSpellAbilities(cards, player); List<SpellAbility> all = ComputerUtilAbility.getSpellAbilities(cards, player);
ComparatorUtil.verifyTransitivity(saComparator, all);
Collections.sort(all, saComparator); // put best spells first Collections.sort(all, saComparator); // put best spells first
for (final SpellAbility sa : ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player)) { for (final SpellAbility sa : ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player)) {
@@ -1572,6 +1574,7 @@ public class AiController {
if (all == null || all.isEmpty()) if (all == null || all.isEmpty())
return null; return null;
ComparatorUtil.verifyTransitivity(saComparator, all);
Collections.sort(all, saComparator); // put best spells first Collections.sort(all, saComparator); // put best spells first
for (final SpellAbility sa : ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player)) { for (final SpellAbility sa : ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player)) {

View File

@@ -0,0 +1,67 @@
package forge.util;
import java.util.*;
/**
* @author Gili Tzabari
*/
public final class ComparatorUtil
{
/**
* Verify that a comparator is transitive.
*
* @param <T> the type being compared
* @param comparator the comparator to test
* @param elements the elements to test against
* @throws AssertionError if the comparator is not transitive
*/
public static <T> void verifyTransitivity(Comparator<T> comparator, Collection<T> elements)
{
for (T first: elements)
{
for (T second: elements)
{
int result1 = comparator.compare(first, second);
int result2 = comparator.compare(second, first);
if (result1 != -result2)
{
// Uncomment the following line to step through the failed case
//comparator.compare(first, second);
throw new AssertionError("compare(" + first + ", " + second + ") == " + result1 +
" but swapping the parameters returns " + result2);
}
}
}
for (T first: elements)
{
for (T second: elements)
{
int firstGreaterThanSecond = comparator.compare(first, second);
if (firstGreaterThanSecond <= 0)
continue;
for (T third: elements)
{
int secondGreaterThanThird = comparator.compare(second, third);
if (secondGreaterThanThird <= 0)
continue;
int firstGreaterThanThird = comparator.compare(first, third);
if (firstGreaterThanThird <= 0)
{
// Uncomment the following line to step through the failed case
//comparator.compare(first, third);
throw new AssertionError("compare(" + first + ", " + second + ") > 0, " +
"compare(" + second + ", " + third + ") > 0, but compare(" + first + ", " + third + ") == " +
firstGreaterThanThird);
}
}
}
}
}
/**
* Prevent construction.
*/
private ComparatorUtil()
{
}
}