Merge branch 'collector-number-in-card-list-and-card-db-refactoring' into 'master'

FIX and Improvements to Card Edition Sorting, Cards Processing from Oracle, and Cards Art Index Matching

See merge request core-developers/forge!4756
This commit is contained in:
Michael Kamensky
2021-05-27 10:38:51 +00:00
4 changed files with 91 additions and 24 deletions

View File

@@ -147,7 +147,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
}
}
public static class CardInSet {
public static class CardInSet implements Comparable<CardInSet> {
public final CardRarity rarity;
public final String collectorNumber;
public final String name;
@@ -171,6 +171,51 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
sb.append(name);
return sb.toString();
}
/**
* This method implements the main strategy to allow for natural ordering of collectorNumber
* (i.e. "1" < "10"), overloading the default lexicographic order (i.e. "10" < "1").
* Any non-numerical parts in the input collectorNumber will be also accounted for, and attached to the
* resulting sorting key, accordingly.
*
* @param collectorNumber: Input collectorNumber tro transform in a Sorting Key
* @return A 5-digits zero-padded collector number + any non-numerical parts attached.
*/
public static String getSortableCollectorNumber(final String collectorNumber){
String sortableCollNr = collectorNumber;
if (sortableCollNr == null || sortableCollNr.length() == 0)
sortableCollNr = "50000"; // very big number of 5 digits to have them in last positions
// Now, for proper sorting, let's zero-pad the collector number (if integer)
int collNr;
try {
collNr = Integer.parseInt(sortableCollNr);
sortableCollNr = String.format("%05d", collNr);
} catch (NumberFormatException ex) {
String nonNumeric = sortableCollNr.replaceAll("[0-9]", "");
String onlyNumeric = sortableCollNr.replaceAll("[^0-9]", "");
if (sortableCollNr.startsWith(onlyNumeric)) // e.g. 12a, 37+, 2018f,
sortableCollNr = String.format("%05d", Integer.parseInt(onlyNumeric)) + nonNumeric;
else // e.g. WS6, S1
sortableCollNr = nonNumeric + String.format("%05d", Integer.parseInt(onlyNumeric));
}
return sortableCollNr;
}
@Override
public int compareTo(CardInSet o) {
final int nameCmp = name.compareToIgnoreCase(o.name);
if (0 != nameCmp) {
return nameCmp;
}
String thisCollNr = getSortableCollectorNumber(collectorNumber);
String othrCollNr = getSortableCollectorNumber(o.collectorNumber);
final int collNrCmp = thisCollNr.compareTo(othrCollNr);
if (0 != collNrCmp) {
return collNrCmp;
}
return rarity.compareTo(o.rarity);
}
}
private final static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
@@ -286,7 +331,9 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public List<CardInSet> getCards() { return cardMap.get("cards"); }
public List<CardInSet> getAllCardsInSet() {
return Lists.newArrayList(cardMap.values());
ArrayList<CardInSet> cardsInSet = Lists.newArrayList(cardMap.values());
Collections.sort(cardsInSet);
return cardsInSet;
}
public boolean isModern() { return getDate().after(parseDate("2003-07-27")); } //8ED and above are modern except some promo cards and others
@@ -305,7 +352,10 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
if (o == null) {
return 1;
}
return date.compareTo(o.date);
int dateComp = date.compareTo(o.date);
if (0 != dateComp)
return dateComp;
return name.compareTo(o.name);
}
@Override
@@ -413,7 +463,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
* rarity - grouping #4
* name - grouping #5
*/
"(^([0-9]+.?) )?(([SCURML]) )?(.*)$"
"(^([0-9A-Z]+.?) )?(([SCURML]) )?(.*)$"
);
ListMultimap<String, CardInSet> cardMap = ArrayListMultimap.create();

View File

@@ -243,6 +243,34 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
// return String.format("%s|%s", name, cardSet);
}
/*
* This (utility) method transform a collectorNumber String into a key string for sorting.
* This method proxies the same strategy implemented in CardEdition.CardInSet class from which the
* collectorNumber of PaperCard instances are originally retrieved.
* This is also to centralise the criterion, whilst avoiding code duplication.
*
* Note: The method has been made private as this is for internal API use **only**, to allow
* for generalised comparison with IPaperCard instances (see compareTo)
*
* The public API of PaperCard includes a method (i.e. getCollectorNumberSortingKey) which applies
* this method on instance's own collector number.
*
* @return a zero-padded 5-digits String + any non-numerical content in the input String, properly attached.
*/
private static String makeCollectorNumberSortingKey(final String collectorNumber0){
String collectorNumber = collectorNumber0;
if (collectorNumber.equals(NO_COLLECTOR_NUMBER))
collectorNumber = null;
return CardEdition.CardInSet.getSortableCollectorNumber(collectorNumber);
}
public String getCollectorNumberSortingKey(){
// Hardly the case, but just invoke getter rather than direct
// attribute to be sure that collectorNumber has been retrieved already!
return makeCollectorNumberSortingKey(getCollectorNumber());
}
@Override
public int compareTo(final IPaperCard o) {
final int nameCmp = name.compareToIgnoreCase(o.getName());
@@ -253,7 +281,9 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
int setDiff = edition.compareTo(o.getEdition());
if (0 != setDiff)
return setDiff;
final int collNrCmp = getCollectorNumber().compareTo(o.getCollectorNumber());
String thisCollNrKey = getCollectorNumberSortingKey();
String othrCollNrKey = makeCollectorNumberSortingKey(o.getCollectorNumber());
final int collNrCmp = thisCollNrKey.compareTo(othrCollNrKey);
if (0 != collNrCmp) {
return collNrCmp;
}

View File

@@ -105,10 +105,10 @@ Foil=NotSupported
30a C Lat-Nam's Legacy
30b C Lat-Nam's Legacy
31 R Library of Lat-Nam
55a C Lim-Dûl's High Guard
55b C Lim-Dûl's High Guard
108 U Lim-Dûl's Paladin
107 U Lim-Dûl's Vault
55a C Lim-Dul's High Guard
55b C Lim-Dul's High Guard
108 U Lim-Dul's Paladin
107 U Lim-Dul's Vault
122 R Lodestone Bauble
112 R Lord of Tresserhorn
10a C Martyrdom

View File

@@ -661,24 +661,11 @@ public enum ColumnDef {
//make sure it's a card. if not, pointless to proceed.
String collectorNumber;
if (i instanceof PaperCard) {
collectorNumber = ((PaperCard) i).getCollectorNumber();
// First off, make all NO_COLLECTOR_NUMBER the last in sortings
if (collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER))
collectorNumber = "50000"; // very big number of 5 digits to have them in last positions
// Now, for proper sorting, let's zero-pad the collector number (if integer)
try {
int collNr = Integer.parseInt(collectorNumber);
collectorNumber = String.format("%05d", collNr);
} catch (NumberFormatException ex) {
String nonNumeric = collectorNumber.replaceAll("[0-9]", "");
String onlyNumeric = collectorNumber.replaceAll("[^0-9]", "");
collectorNumber = String.format("%05d", Integer.parseInt(onlyNumeric)) + nonNumeric;
}
collectorNumber = ((PaperCard) i).getCollectorNumberSortingKey();
} else {
collectorNumber = IPaperCard.NO_COLLECTOR_NUMBER;
}
return collectorNumber + toSortableName(i.getName());
return collectorNumber;
}
/**