Improved Implementation for Card Art Optimisation

The new implementation now contains a completely refactored version of the algorithm, also including the invocation of the latest method for getAlternativeCardPrint in StaticData (with extra statistics paramenters gathered from current pool). This include optimisation for card frame, and cards from Expansion sets.

Moreover, the new implementation now automatically distribute card arts for **all** the cards in the pool - regardless they need to be "replaced" with alternative print or not.

THE ONLY case when this is not happening is when there is NO card to update in the current pool. This makes sense as this means editions has been specified, so the Deck won't receive any UNDESIRED alteration.
This commit is contained in:
leriomaggio
2021-08-12 16:35:08 +01:00
parent e54916e837
commit 4b1e9b6c0c

View File

@@ -290,6 +290,10 @@ public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPo
private void optimiseCardArtSelectionInDeckSections(Map<DeckSection, ArrayList<String>> cardsWithNoEdition) { private void optimiseCardArtSelectionInDeckSections(Map<DeckSection, ArrayList<String>> cardsWithNoEdition) {
StaticData data = StaticData.instance(); StaticData data = StaticData.instance();
// Get current Card Art Preference Settings
boolean isCardArtPreferenceLatestArt = data.cardArtPreferenceIsLatest();
boolean cardArtPreferenceHasFilter = data.isCoreExpansionOnlyFilterSet();
for(Entry<DeckSection, CardPool> part : parts.entrySet()) { for(Entry<DeckSection, CardPool> part : parts.entrySet()) {
DeckSection deckSection = part.getKey(); DeckSection deckSection = part.getKey();
if(deckSection == DeckSection.Planes || deckSection == DeckSection.Schemes || deckSection == DeckSection.Avatar) if(deckSection == DeckSection.Planes || deckSection == DeckSection.Schemes || deckSection == DeckSection.Avatar)
@@ -301,37 +305,82 @@ public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPo
continue; // nothing to do here continue; // nothing to do here
CardPool pool = part.getValue(); CardPool pool = part.getValue();
// Set options for the alternative card print search
boolean isExpansionTheMajorityInThePool = (pool.getTheMostFrequentEditionType() == CardEdition.Type.EXPANSION);
boolean isPoolModernFramed = pool.isModern();
// == Get the most representative (Pivot) Edition in the Pool // == Get the most representative (Pivot) Edition in the Pool
// Note: Card Art Updates (if any) will be determined based on the Pivot Edition. // Note: Card Art Updates (if any) will be determined based on the Pivot Edition.
CardEdition pivotEdition = pool.getPivotEdition(); CardEdition pivotEdition = pool.getPivotCardEdition(isCardArtPreferenceLatestArt);
// == Inspect and Update the Pool // == Inspect and Update the Pool
Date releaseDatePivotEdition = pivotEdition.getDate(); Date releaseDatePivotEdition = pivotEdition.getDate();
CardPool newPool = new CardPool(); CardPool newPool = new CardPool();
for (Entry<PaperCard, Integer> cp : pool) { for (Entry<PaperCard, Integer> cp : pool) {
PaperCard card = cp.getKey(); PaperCard card = cp.getKey();
int count = cp.getValue(); int totalToAddToPool = cp.getValue();
// A. Skip cards not requiring any update, because they add the edition specified! // A. Skip cards not requiring any update, because they add the edition specified!
if (!cardNamesWithNoEditionInSection.contains(card.getName())) { if (!cardNamesWithNoEditionInSection.contains(card.getName())) {
newPool.add(card, count); addCardToPool(newPool, card, totalToAddToPool, card.isFoil());
continue; continue;
} }
// B. Determine if current card requires update // B. Determine if current card requires update
boolean cardArtNeedsOptimisation = this.isCardArtUpdateRequired(card, releaseDatePivotEdition); boolean cardArtNeedsOptimisation = this.isCardArtUpdateRequired(card, releaseDatePivotEdition);
if (!cardArtNeedsOptimisation) { if (!cardArtNeedsOptimisation) {
newPool.add(card, count); addCardToPool(newPool, card, totalToAddToPool, card.isFoil());
continue; continue;
} }
PaperCard alternativeArtCard = data.getAlternativeCardPrint(card, releaseDatePivotEdition); PaperCard alternativeCardPrint = data.getAlternativeCardPrint(card, releaseDatePivotEdition,
if (alternativeArtCard == null) // no alternative found, add original card in Pool isCardArtPreferenceLatestArt,
newPool.add(card, count); cardArtPreferenceHasFilter,
isExpansionTheMajorityInThePool,
isPoolModernFramed);
if (alternativeCardPrint == null) // no alternative found, add original card in Pool
addCardToPool(newPool, card, totalToAddToPool, card.isFoil());
else else
newPool.add(alternativeArtCard, count); addCardToPool(newPool, alternativeCardPrint, totalToAddToPool, card.isFoil());
} }
parts.put(deckSection, newPool); parts.put(deckSection, newPool);
} }
} }
private void addCardToPool(CardPool pool, PaperCard card, int totalToAdd, boolean isFoil) {
StaticData data = StaticData.instance();
if (card.getArtIndex() != IPaperCard.NO_ART_INDEX && card.getArtIndex() != IPaperCard.DEFAULT_ART_INDEX)
pool.add(isFoil ? card.getFoiled() : card, totalToAdd); // art index requested, keep that way!
else {
int artCount = data.getCardArtCount(card);
if (artCount > 1)
addAlternativeCardPrintInPoolWithMultipleArt(card, pool, totalToAdd, artCount);
else
pool.add(isFoil ? card.getFoiled() : card, totalToAdd);
}
}
private void addAlternativeCardPrintInPoolWithMultipleArt(PaperCard alternativeCardPrint, CardPool pool,
int totalNrToAdd, int nrOfAvailableArts) {
StaticData data = StaticData.instance();
// distribute available card art
String cardName = alternativeCardPrint.getName();
String setCode = alternativeCardPrint.getEdition();
boolean isFoil = alternativeCardPrint.isFoil();
int cardsPerArtIndex = totalNrToAdd / nrOfAvailableArts;
cardsPerArtIndex = Math.max(1, cardsPerArtIndex); // make sure is never zero
int restOfCardsToAdd = totalNrToAdd % nrOfAvailableArts;
int cardsAdded = 0;
PaperCard alternativeCardArt = null;
for (int artIndex = 1; artIndex <= nrOfAvailableArts; artIndex++){
alternativeCardArt = data.getOrLoadCommonCard(cardName, setCode, artIndex, isFoil);
cardsAdded += cardsPerArtIndex;
pool.add(alternativeCardArt, cardsPerArtIndex);
if (cardsAdded == totalNrToAdd)
break;
}
if (restOfCardsToAdd > 0)
pool.add(alternativeCardArt, restOfCardsToAdd);
}
private boolean isCardArtUpdateRequired(PaperCard card, Date referenceReleaseDate) { private boolean isCardArtUpdateRequired(PaperCard card, Date referenceReleaseDate) {
/* A Card Art update is required ONLY IF the current edition of the card is either /* A Card Art update is required ONLY IF the current edition of the card is either
newer (older) than pivot edition when LATEST ART (ORIGINAL ART) Card Art Preference newer (older) than pivot edition when LATEST ART (ORIGINAL ART) Card Art Preference
@@ -347,6 +396,9 @@ public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPo
NOTE: the control implemented in release date also consider the case when the input PaperCard NOTE: the control implemented in release date also consider the case when the input PaperCard
is exactly from the Pivot Edition. In this case, NO update will be required! is exactly from the Pivot Edition. In this case, NO update will be required!
*/ */
if (card.getRules().isVariant())
return false; // skip variant cards
boolean isLatestCardArtPreference = StaticData.instance().cardArtPreferenceIsLatest(); boolean isLatestCardArtPreference = StaticData.instance().cardArtPreferenceIsLatest();
CardEdition cardEdition = StaticData.instance().getCardEdition(card.getEdition()); CardEdition cardEdition = StaticData.instance().getCardEdition(card.getEdition());
if (cardEdition == null) return false; if (cardEdition == null) return false;