Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 15 card booster generation #13206

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

tiera3
Copy link
Contributor

@tiera3 tiera3 commented Jan 7, 2025

I noticed the code for reducing boosters to 15 cards and realised it wouldn't work well with collated boosters, or with boosters with fixing in the first slot.

I noticed the code for reducing boosters to 15 cards and realised it wouldn't work well with collated boosters, or with boosters with fixing in the first slot.
@github-actions github-actions bot added the engine label Jan 7, 2025
Copy link
Contributor

@xenohedron xenohedron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the current algorithm is not ideal and makes a bad assumption... but what testing have you done for the new algorithm? Can you be sure that no errors will arise as a result?

What sets currently generate boosters of more than 15 cards that would be affected?

I might want to add a test for every set with booster generation to verify the number of cards (and implicitly catch booster generation errors), I'll have to think about that

// removing positional cards from collated boosters is going to mess with balancing and as-fan
// also for sets with common lands in the land slot, this may eliminate the majority of fixing from a pack
// instead removing a random card that is not in the last four (where rare and uncommons usually are - though some uncommons may be displayed by cards with special collation - eg DFC or bonus sheet).
if (this.Booster.size() > 15 && this.Booster.get(0).getRarity() == Rarity.LAND) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.Booster is not correct

Copy link
Contributor Author

@tiera3 tiera3 Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I get for rushing to submit just before the tournament started - fixed now.

As for your first question, the only one I know of is CLB, but there could be others. For CLB, the last four cards (that this protects from being eliminated) are Background, Legendary, Rare, and Foil (which could be any rarity). So the uncommons are at risk. (Edit - changed code so now the uncommons are protected also.)

(According to lethe, 2X2 comes in 16card boosters, with Cryptic Spires being the 16th card. So that is another potential one to trigger this in the future.)

I had considered a slightly more complicated approach of multistep processing.

List<Card> foundCards = [find all basiclands in booster] ;
if (theBooster.size() - foundCards.size() >= 15 ) {
  theBooster.remove(foundCards);
  foundCards = [find all commons in booster] ;
  if (theBooster.size() - foundCards.size() >= 15 ) {
    theBooster.remove(foundCards);
    foundCards = [find all uncommons in booster] ;
  }
}
if (theBooster.size() < 15 ) {
  [raise an error]
}
while (theBooster.size() -  foundCards.size() < 15 ) {
  foundCards.remove( RandomUtil.nextInt( foundCards.size()) );
}
theBooster.remove( foundCards );
// if still greater than 15 and removed all basics, lands, and uncommons, just go ahead with positional removal
while (theBooster.size() > 15) {
  theBooster.remove(0);
}

@@ -145,6 +145,7 @@ public static ExpansionSetComparator getComparator() {
protected boolean hasAlternateBoosterPrintings = true; // not counting basic lands; e.g. Fallen Empires true, but Tenth Edition false

protected int maxCardNumberInBooster; // used to omit cards with collector numbers beyond the regular cards in a set for boosters
protected int maxCardNumberBasePrint; // used to omit limit boosters to only contain cards with a base printing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you adding this? what does it have to do with your change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops thought I had taken that one out. Was part of something else.

@JayDi85
Copy link
Member

JayDi85 commented Jan 7, 2025

It's ok to remove random or land booster card instead first one. Just make sure it's generate too many cards by design, not by error in some collations or other code parts.

@tiera3
Copy link
Contributor Author

tiera3 commented Jan 7, 2025

As for testing, I tested that the array size and random number generation worked correctly. I also looked up Mage/src/main/java/mage/cards/Card.java to check for determining rarity (when checking if the first card was a basic land).

Edit - changed code so that there is no chance of removing an uncommon, rare, or mythic that is preceded by enough commons to remove first. A higher rarity card can only be removed when it is the first card in the booster.

I have no idea what create15CardBooster gets used for, just coming across it got me concerned. (It will be more and more relevant in the future due to modern sets being designed as 14 card boosters.) But that is a different topic.

tiera3 added 2 commits January 7, 2025 20:05
Tested with 20 card packs containing 13 commons followed by 5 uncommons, a rare, then a card of any rarity.
Also tested with 20 card packs containing 3 commons followed by 15 uncommons, a rare, then a card of any rarity.

-------

In the first scenario, only commons from the group of 13 were removed.
In the second scenario, the first three commons got removed, then the first two uncommons in the pack.

That was expected behaviour. Note - second scenario not expected to occur.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants