mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
parent
76e1ee84c7
commit
1e6709de46
4 changed files with 78 additions and 50 deletions
|
@ -28,6 +28,7 @@ public final class AlaraReborn extends ExpansionSet {
|
||||||
this.numBoosterUncommon = 3;
|
this.numBoosterUncommon = 3;
|
||||||
this.numBoosterRare = 1;
|
this.numBoosterRare = 1;
|
||||||
this.ratioBoosterMythic = 8;
|
this.ratioBoosterMythic = 8;
|
||||||
|
this.hasOnlyMulticolorCards = true;
|
||||||
cards.add(new SetCardInfo("Anathemancer", 33, Rarity.UNCOMMON, mage.cards.a.Anathemancer.class));
|
cards.add(new SetCardInfo("Anathemancer", 33, Rarity.UNCOMMON, mage.cards.a.Anathemancer.class));
|
||||||
cards.add(new SetCardInfo("Architects of Will", 17, Rarity.COMMON, mage.cards.a.ArchitectsOfWill.class));
|
cards.add(new SetCardInfo("Architects of Will", 17, Rarity.COMMON, mage.cards.a.ArchitectsOfWill.class));
|
||||||
cards.add(new SetCardInfo("Ardent Plea", 1, Rarity.UNCOMMON, mage.cards.a.ArdentPlea.class));
|
cards.add(new SetCardInfo("Ardent Plea", 1, Rarity.UNCOMMON, mage.cards.a.ArdentPlea.class));
|
||||||
|
|
|
@ -28,6 +28,7 @@ public final class Judgment extends ExpansionSet {
|
||||||
this.numBoosterUncommon = 3;
|
this.numBoosterUncommon = 3;
|
||||||
this.numBoosterRare = 1;
|
this.numBoosterRare = 1;
|
||||||
this.ratioBoosterMythic = 0;
|
this.ratioBoosterMythic = 0;
|
||||||
|
this.hasUnbalancedColors = true;
|
||||||
cards.add(new SetCardInfo("Ancestor's Chosen", 1, Rarity.UNCOMMON, mage.cards.a.AncestorsChosen.class));
|
cards.add(new SetCardInfo("Ancestor's Chosen", 1, Rarity.UNCOMMON, mage.cards.a.AncestorsChosen.class));
|
||||||
cards.add(new SetCardInfo("Anger", 77, Rarity.UNCOMMON, mage.cards.a.Anger.class));
|
cards.add(new SetCardInfo("Anger", 77, Rarity.UNCOMMON, mage.cards.a.Anger.class));
|
||||||
cards.add(new SetCardInfo("Anurid Barkripper", 104, Rarity.COMMON, mage.cards.a.AnuridBarkripper.class));
|
cards.add(new SetCardInfo("Anurid Barkripper", 104, Rarity.COMMON, mage.cards.a.AnuridBarkripper.class));
|
||||||
|
|
|
@ -28,6 +28,7 @@ public final class Torment extends ExpansionSet {
|
||||||
this.numBoosterUncommon = 3;
|
this.numBoosterUncommon = 3;
|
||||||
this.numBoosterRare = 1;
|
this.numBoosterRare = 1;
|
||||||
this.ratioBoosterMythic = 0;
|
this.ratioBoosterMythic = 0;
|
||||||
|
this.hasUnbalancedColors = true;
|
||||||
cards.add(new SetCardInfo("Accelerate", 90, Rarity.COMMON, mage.cards.a.Accelerate.class));
|
cards.add(new SetCardInfo("Accelerate", 90, Rarity.COMMON, mage.cards.a.Accelerate.class));
|
||||||
cards.add(new SetCardInfo("Acorn Harvest", 118, Rarity.COMMON, mage.cards.a.AcornHarvest.class));
|
cards.add(new SetCardInfo("Acorn Harvest", 118, Rarity.COMMON, mage.cards.a.AcornHarvest.class));
|
||||||
cards.add(new SetCardInfo("Ambassador Laquatus", 23, Rarity.RARE, mage.cards.a.AmbassadorLaquatus.class));
|
cards.add(new SetCardInfo("Ambassador Laquatus", 23, Rarity.RARE, mage.cards.a.AmbassadorLaquatus.class));
|
||||||
|
|
|
@ -8,6 +8,7 @@ import mage.collation.BoosterCollator;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
import mage.constants.SetType;
|
import mage.constants.SetType;
|
||||||
|
import mage.filter.FilterMana;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
import mage.util.RandomUtil;
|
import mage.util.RandomUtil;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
@ -124,9 +125,8 @@ public abstract class ExpansionSet implements Serializable {
|
||||||
protected int numBoosterDoubleFaced; // -1 = include normally 0 = exclude 1-n = include explicit
|
protected int numBoosterDoubleFaced; // -1 = include normally 0 = exclude 1-n = include explicit
|
||||||
protected double ratioBoosterMythic;
|
protected double ratioBoosterMythic;
|
||||||
|
|
||||||
protected boolean validateBoosterColors = true;
|
protected boolean hasUnbalancedColors = false;
|
||||||
protected double rejectMissingColorProbability = 0.8;
|
protected boolean hasOnlyMulticolorCards = false;
|
||||||
protected double rejectSameColorUncommonsProbability = 0.8;
|
|
||||||
|
|
||||||
protected int maxCardNumberInBooster; // used to omit cards with collector numbers beyond the regular cards in a set for boosters
|
protected int maxCardNumberInBooster; // used to omit cards with collector numbers beyond the regular cards in a set for boosters
|
||||||
|
|
||||||
|
@ -276,10 +276,12 @@ public abstract class ExpansionSet implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean boosterIsValid(List<Card> booster) {
|
protected boolean boosterIsValid(List<Card> booster) {
|
||||||
if (validateBoosterColors) {
|
if (!validateCommonColors(booster)) {
|
||||||
if (!validateColors(booster)) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
if (!validateUncommonColors(booster)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add partner check
|
// TODO: add partner check
|
||||||
|
@ -287,56 +289,79 @@ public abstract class ExpansionSet implements Serializable {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean validateColors(List<Card> booster) {
|
private static ObjectColor getColorForValidate(Card card) {
|
||||||
List<ObjectColor> magicColors
|
ObjectColor color = card.getColor();
|
||||||
= Arrays.asList(ObjectColor.WHITE, ObjectColor.BLUE, ObjectColor.BLACK, ObjectColor.RED, ObjectColor.GREEN);
|
// treat colorless nonland cards with exactly one ID color as cards of that color
|
||||||
|
// (e.g. devoid, emerge, spellbombs... but not mana fixing artifacts)
|
||||||
// all cards colors
|
if (color.isColorless() && !card.isLand()) {
|
||||||
Map<ObjectColor, Integer> colorWeight = new HashMap<>();
|
FilterMana colorIdentity = card.getColorIdentity();
|
||||||
// uncommon/rare/mythic cards colors
|
if (colorIdentity.getColorCount() == 1) {
|
||||||
Map<ObjectColor, Integer> uncommonWeight = new HashMap<>();
|
return new ObjectColor(colorIdentity.toString());
|
||||||
|
}
|
||||||
for (ObjectColor color : magicColors) {
|
|
||||||
colorWeight.put(color, 0);
|
|
||||||
uncommonWeight.put(color, 0);
|
|
||||||
}
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
// count colors in the booster
|
protected boolean validateCommonColors(List<Card> booster) {
|
||||||
for (Card card : booster) {
|
List<ObjectColor> commonColors = booster.stream()
|
||||||
ObjectColor cardColor = card.getColor(null);
|
.filter(card -> card.getRarity() == Rarity.COMMON)
|
||||||
if (cardColor != null) {
|
.map(ExpansionSet::getColorForValidate)
|
||||||
List<ObjectColor> colors = cardColor.getColors();
|
.collect(Collectors.toList());
|
||||||
// todo: do we need gold color?
|
|
||||||
colors.remove(ObjectColor.GOLD);
|
// for multicolor sets, count not just the colors present at common,
|
||||||
if (!colors.isEmpty()) {
|
// but also the number of color combinations (guilds/shards/wedges)
|
||||||
// 60 - full card weight
|
// e.g. a booster with three UB commons, three RW commons and four G commons
|
||||||
// multicolored cards add part of the weight to each color
|
// has all five colors but isn't "balanced"
|
||||||
int cardColorWeight = 60 / colors.size();
|
ObjectColor colorsRepresented = new ObjectColor();
|
||||||
for (ObjectColor color : colors) {
|
Set<ObjectColor> colorCombinations = new HashSet<>();
|
||||||
colorWeight.put(color, colorWeight.get(color) + cardColorWeight);
|
int colorlessCountPlusOne = 1;
|
||||||
if (card.getRarity() != Rarity.COMMON) {
|
|
||||||
uncommonWeight.put(color, uncommonWeight.get(color) + cardColorWeight);
|
for (ObjectColor color : commonColors) {
|
||||||
}
|
colorCombinations.add(color);
|
||||||
}
|
int colorCount = color.getColorCount();
|
||||||
}
|
if (colorCount == 0) {
|
||||||
|
++colorlessCountPlusOne;
|
||||||
|
} else if (colorCount > 1 && !hasOnlyMulticolorCards) {
|
||||||
|
// to prevent biasing toward multicolor over monocolor cards,
|
||||||
|
// count them as one of their colors chosen at random
|
||||||
|
List<ObjectColor> multiColor = color.getColors();
|
||||||
|
colorsRepresented.addColor(multiColor.get(RandomUtil.nextInt(multiColor.size())));
|
||||||
|
} else {
|
||||||
|
colorsRepresented.addColor(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that all colors are present
|
int colors = Math.min(colorsRepresented.getColorCount(), colorCombinations.size());
|
||||||
if (magicColors.stream().anyMatch(color -> colorWeight.get(color) < 60)) {
|
|
||||||
// reject only part of the boosters
|
|
||||||
if (RandomUtil.nextDouble() < rejectMissingColorProbability) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that we don't have 3 or more uncommons/rares of the same color
|
// if booster has all five colors in five unique combinations, or if it has
|
||||||
if (magicColors.stream().anyMatch(color -> uncommonWeight.get(color) >= 180)) {
|
// one card per color and all but one of the rest are colorless, accept it
|
||||||
// reject only part of the boosters
|
// ("all but one" adds some leeway for sets with small boosters)
|
||||||
return !(RandomUtil.nextDouble() < rejectSameColorUncommonsProbability);
|
if (colors >= Math.min(5, commonColors.size() - colorlessCountPlusOne)) return true;
|
||||||
}
|
// otherwise, if booster is missing more than one color, reject it
|
||||||
|
if (colors < 4) return false;
|
||||||
|
// for Torment and Judgment, always accept boosters with four out of five colors
|
||||||
|
if (hasUnbalancedColors) return true;
|
||||||
|
// if a common was replaced by a special card, increase the chance to accept four colors
|
||||||
|
if (commonColors.size() < numBoosterCommon) ++colorlessCountPlusOne;
|
||||||
|
|
||||||
return true;
|
// otherwise, stochiastically treat each colorless card as 1/5 of a card of the missing color
|
||||||
|
return (RandomUtil.nextDouble() > Math.pow(0.8, colorlessCountPlusOne));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ObjectColor COLORLESS = new ObjectColor();
|
||||||
|
|
||||||
|
protected boolean validateUncommonColors(List<Card> booster) {
|
||||||
|
List<ObjectColor> uncommonColors = booster.stream()
|
||||||
|
.filter(card -> card.getRarity() == Rarity.UNCOMMON)
|
||||||
|
.map(ExpansionSet::getColorForValidate)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// if there are only two uncommons, they can be the same color
|
||||||
|
if (uncommonColors.size() < 3) return true;
|
||||||
|
// boosters of artifact sets can have all colorless uncommons
|
||||||
|
if (uncommonColors.contains(COLORLESS)) return true;
|
||||||
|
// otherwise, reject if all uncommons are the same color combination
|
||||||
|
return (new HashSet<>(uncommonColors).size() > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean checkMythic() {
|
protected boolean checkMythic() {
|
||||||
|
|
Loading…
Reference in a new issue