Tweak cost and value multipliers for non-commons

This commit is contained in:
drdev
2016-03-20 16:29:49 +00:00
parent d0811678c3
commit 5af9e90a2e
10 changed files with 192 additions and 54 deletions

View File

@@ -37,6 +37,7 @@ import forge.limited.GauntletMini;
import forge.planarconquest.ConquestController;
import forge.planarconquest.ConquestPlane;
import forge.planarconquest.ConquestPreferences;
import forge.planarconquest.ConquestUtil;
import forge.player.GamePlayerUtil;
import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences;
@@ -178,6 +179,7 @@ public final class FModel {
CardPreferences.load();
DeckPreferences.load();
ItemManagerConfig.load();
ConquestUtil.updateRarityFilterOdds();
achievements = new HashMap<>();
achievements.put(GameType.Constructed, new ConstructedAchievements());

View File

@@ -12,8 +12,6 @@ public class ConquestAwardPool {
private final BoosterPool commons, uncommons, rares, mythics;
public ConquestAwardPool(Iterable<PaperCard> cards) {
ConquestPreferences prefs = FModel.getConquestPreferences();
commons = new BoosterPool();
uncommons = new BoosterPool();
rares = new BoosterPool();
@@ -38,32 +36,20 @@ public class ConquestAwardPool {
break;
}
}
//calculate odds of each rarity
float commonOdds = commons.getOdds(prefs.getPrefInt(CQPref.BOOSTER_COMMONS));
float uncommonOdds = uncommons.getOdds(prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS));
int raresPerBooster = prefs.getPrefInt(CQPref.BOOSTER_RARES);
float rareOdds = rares.getOdds(raresPerBooster);
float mythicOdds = mythics.getOdds((float)raresPerBooster / (float)prefs.getPrefInt(CQPref.BOOSTERS_PER_MYTHIC));
//determine multipliers for each rarity based on ratio of odds
commons.multiplier = 1;
uncommons.multiplier = commonOdds / uncommonOdds;
rares.multiplier = commonOdds / rareOdds;
mythics.multiplier = mythics.isEmpty() ? 0 : commonOdds / mythicOdds;
}
public int getShardValue(CardRarity rarity, int baseValue) {
ConquestPreferences prefs = FModel.getConquestPreferences();
switch (rarity) {
case Common:
return baseValue;
case Uncommon:
return Math.round(baseValue * uncommons.multiplier);
return Math.round((float)baseValue * (float)prefs.getPrefInt(CQPref.AETHER_UNCOMMON_MULTIPLIER));
case Rare:
case Special:
return Math.round(baseValue * rares.multiplier);
return Math.round((float)baseValue * (float)prefs.getPrefInt(CQPref.AETHER_RARE_MULTIPLIER));
case MythicRare:
return Math.round(baseValue * mythics.multiplier);
return Math.round((float)baseValue * (float)prefs.getPrefInt(CQPref.AETHER_MYTHIC_MULTIPLIER));
default:
return 0;
}
@@ -84,7 +70,6 @@ public class ConquestAwardPool {
public class BoosterPool {
private final List<PaperCard> cards = new ArrayList<PaperCard>();
private float multiplier;
private BoosterPool() {
}
@@ -93,12 +78,6 @@ public class ConquestAwardPool {
return cards.isEmpty();
}
private float getOdds(float perBoosterCount) {
int count = cards.size();
if (count == 0) { return 0; }
return (float)perBoosterCount / (float)count;
}
private void add(PaperCard c) {
cards.add(c);
}

View File

@@ -19,6 +19,7 @@ package forge.planarconquest;
import forge.properties.ForgeConstants;
import forge.properties.PreferencesStore;
import java.io.Serializable;
@SuppressWarnings("serial")
@@ -33,6 +34,9 @@ public class ConquestPreferences extends PreferencesStore<ConquestPreferences.CQ
AETHER_BASE_EXILE_VALUE("75"),
AETHER_BASE_RETRIEVE_COST("150"),
AETHER_BASE_PULL_COST("200"),
AETHER_UNCOMMON_MULTIPLIER("3"),
AETHER_RARE_MULTIPLIER("10"),
AETHER_MYTHIC_MULTIPLIER("25"),
AETHER_START_SHARDS("3000"),
AETHER_WHEEL_SHARDS("1000"),
@@ -65,6 +69,12 @@ public class ConquestPreferences extends PreferencesStore<ConquestPreferences.CQ
super(ForgeConstants.CONQUEST_PREFS_FILE, CQPref.class);
}
@Override
public void save() {
super.save();
ConquestUtil.updateRarityFilterOdds();
}
protected CQPref[] getEnumValues() {
return CQPref.values();
}

View File

@@ -1,6 +1,7 @@
package forge.planarconquest;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
@@ -30,6 +31,7 @@ import forge.deck.generation.DeckGeneratorMonoColor;
import forge.deck.generation.IDeckGenPool;
import forge.item.PaperCard;
import forge.model.FModel;
import forge.planarconquest.ConquestPreferences.CQPref;
import forge.properties.ForgeConstants;
import forge.quest.QuestUtil;
import forge.util.FileUtil;
@@ -182,19 +184,19 @@ public class ConquestUtil {
NONCREATURE_PERMANENT (FSkinProp.IMG_ENCHANTMENT, new TypeFilter(EnumSet.of(CoreType.Artifact, CoreType.Enchantment, CoreType.Planeswalker, CoreType.Land)), "Noncreature Permanent"),
INSTANT_SORCERY (FSkinProp.IMG_SORCERY, new TypeFilter(EnumSet.of(CoreType.Instant, CoreType.Sorcery)), "Instant or Sorcery"),
COMMON (FSkinProp.IMG_PW_BADGE_COMMON, new RarityFilter(CardRarity.Common), "Common"),
UNCOMMON (FSkinProp.IMG_PW_BADGE_UNCOMMON, new RarityFilter(CardRarity.Uncommon), "Uncommon"),
RARE (FSkinProp.IMG_PW_BADGE_RARE, new RarityFilter(CardRarity.Rare), "Rare"),
MYTHIC (FSkinProp.IMG_PW_BADGE_MYTHIC, new RarityFilter(CardRarity.MythicRare), "Mythic Rare"),
COMMON (FSkinProp.IMG_PW_BADGE_COMMON, new RarityFilter(EnumSet.of(CardRarity.Common, CardRarity.Uncommon, CardRarity.Rare, CardRarity.Special, CardRarity.MythicRare)), "Common"),
UNCOMMON (FSkinProp.IMG_PW_BADGE_UNCOMMON, new RarityFilter(EnumSet.of(CardRarity.Uncommon, CardRarity.Rare, CardRarity.Special, CardRarity.MythicRare)), "Uncommon"),
RARE (FSkinProp.IMG_PW_BADGE_RARE, new RarityFilter(EnumSet.of(CardRarity.Rare, CardRarity.Special, CardRarity.MythicRare)), "Rare"),
MYTHIC (FSkinProp.IMG_PW_BADGE_MYTHIC, new RarityFilter(EnumSet.of(CardRarity.MythicRare)), "Mythic Rare (100%)"),
CMC_LOW (FSkinProp.IMG_CMC_LOW, new CMCFilter(0, 3), "CMC 0-3"),
CMC_LOW_MID (FSkinProp.IMG_CMC_LOW_MID, new CMCFilter(2, 5), "CMC 2-5"),
CMC_MID_HIGH (FSkinProp.IMG_CMC_MID_HIGH, new CMCFilter(4, 7), "CMC 4-7"),
CMC_HIGH (FSkinProp.IMG_CMC_HIGH, new CMCFilter(6, -1), "CMC 6+");
public final FSkinProp skinProp;
public final Predicate<PaperCard> predicate;
public final String caption;
private final FSkinProp skinProp;
private final Predicate<PaperCard> predicate;
private String caption;
private AEtherFilter(final FSkinProp skinProp0, final Predicate<PaperCard> predicate0, final String caption0) {
skinProp = skinProp0;
@@ -207,6 +209,10 @@ public class ConquestUtil {
return skinProp;
}
public Predicate<PaperCard> getPredicate() {
return predicate;
}
public ColorSet getColor() {
if (predicate instanceof ColorFilter) {
return ((ColorFilter)predicate).color;
@@ -214,16 +220,19 @@ public class ConquestUtil {
return null;
}
public EnumSet<CoreType> getTypes() {
if (predicate instanceof ColorFilter) {
return ((TypeFilter)predicate).types;
}
return null;
}
public CardRarity getRarity() {
public CardRarity getRarity(double randomSeed) {
if (predicate instanceof RarityFilter) {
return ((RarityFilter)predicate).rarity;
float total = 0;
CardRarity rarity = null;
EnumMap<CardRarity, Double> rarityOdds = ((RarityFilter)predicate).rarityOdds;
for (Entry<CardRarity, Double> entry : rarityOdds.entrySet()) {
rarity = entry.getKey();
total += entry.getValue();
if (randomSeed < total) {
return rarity;
}
}
return rarity;
}
return null;
}
@@ -249,6 +258,25 @@ public class ConquestUtil {
}
}
public static void updateRarityFilterOdds() {
ConquestPreferences prefs = FModel.getConquestPreferences();
EnumMap<CardRarity, Double> odds = new EnumMap<CardRarity, Double>(CardRarity.class);
double commonsPerBooster = prefs.getPrefInt(CQPref.BOOSTER_COMMONS);
double uncommonPerBooster = prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS);
double raresPerBooster = prefs.getPrefInt(CQPref.BOOSTER_RARES);
double mythicsPerBooster = raresPerBooster / (double)prefs.getPrefInt(CQPref.BOOSTERS_PER_MYTHIC);
odds.put(CardRarity.Common, 1d);
odds.put(CardRarity.Uncommon, uncommonPerBooster / commonsPerBooster);
odds.put(CardRarity.Rare, raresPerBooster / commonsPerBooster);
odds.put(CardRarity.MythicRare, mythicsPerBooster / commonsPerBooster);
for (AEtherFilter filter : RARITY_FILTERS) {
filter.caption = ((RarityFilter)filter.predicate).updateOdds(odds);
}
}
public static final AEtherFilter[] COLOR_FILTERS = new AEtherFilter[] {
AEtherFilter.W,
AEtherFilter.U,
@@ -327,18 +355,47 @@ public class ConquestUtil {
}
private static class RarityFilter implements Predicate<PaperCard> {
private final CardRarity rarity;
private final EnumMap<CardRarity, Double> rarityOdds;
private RarityFilter(CardRarity rarity0) {
rarity = rarity0;
private RarityFilter(EnumSet<CardRarity> rarities0) {
rarityOdds = new EnumMap<CardRarity, Double>(CardRarity.class);
for (CardRarity rarity : rarities0) {
rarityOdds.put(rarity, 0d); //values will be set later
}
}
private String updateOdds(EnumMap<CardRarity, Double> oddsLookup) {
double baseOdds = 0;
double remainingOdds = 1;
CardRarity baseRarity = null;
String caption = "";
for (CardRarity rarity : rarityOdds.keySet()) {
Double odds = oddsLookup.get(rarity);
if (odds == null) { continue; } //skip Special rarity
if (baseRarity == null) {
baseRarity = rarity;
baseOdds = odds;
}
else {
odds /= baseOdds;
remainingOdds -= odds;
caption += ", " + rarity.getLongName() + " (" + (Math.round(1000 * odds) / 10) + "%)"; //round to nearest single decimal point
rarityOdds.put(rarity, odds);
}
}
//prepend base rarity and odds
caption = baseRarity.getLongName() + " (" + (Math.round(1000 * remainingOdds) / 10) + "%)" + caption;
rarityOdds.put(baseRarity, remainingOdds);
return caption;
}
@Override
public boolean apply(PaperCard card) {
CardRarity cardRarity = card.getRarity();
if (cardRarity == rarity) { return true; }
if (cardRarity == CardRarity.Special && rarity == CardRarity.Rare) { return true; } //treat specials as rares
return false;
return rarityOdds.containsKey(card.getRarity());
}
}

View File

@@ -66,7 +66,7 @@ public abstract class PreferencesStore<T extends Enum<T>> {
protected abstract T valueOf(String name);
protected abstract String getPrefDefault(T key);
public final void save() {
public void save() {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(filename));