Implement new way to generate boosters using box mapping info (WIP) (#7529)

* [THB] added initial common/uncommon collation mechanism

* [THB] added rare/mythic and lands to pack generation

* fixed some card names

* broke out collation into its own separate classes

* built collation into ExpansionSet

* added note about collation information

* [KHM] added collation info

* updated collation to use collector number rather than name

* added shuffle to set constructor

* added some notes on collation methods
This commit is contained in:
Evan Kranzler 2021-02-12 17:35:28 -05:00 committed by GitHub
parent 10e557b873
commit 8a16eda062
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 500 additions and 3 deletions

View file

@ -4,6 +4,10 @@ import mage.cards.ExpansionSet;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.collation.BoosterCollator;
import mage.collation.BoosterStructure;
import mage.collation.CardRun;
import mage.collation.RarityConfiguration;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.SetType;
@ -26,7 +30,7 @@ public final class Kaldheim extends ExpansionSet {
private final List<CardInfo> savedSpecialLand = new ArrayList<>();
private Kaldheim() {
super("Kaldheim", "KHM", ExpansionSet.buildDate(2021, 2, 5), SetType.EXPANSION);
super("Kaldheim", "KHM", ExpansionSet.buildDate(2021, 2, 5), SetType.EXPANSION, new KaldheimCollator());
this.blockName = "Kaldheim";
this.hasBasicLands = true;
this.hasBoosters = true;
@ -489,3 +493,158 @@ public final class Kaldheim extends ExpansionSet {
return new ArrayList<>(savedSpecialLand);
}
}
// Booster collation info from https://www.lethe.xyz/mtg/collation/khm.html
// Using USA collation for common/uncommon and JP for rare/mythic
class KaldheimCollator implements BoosterCollator {
private static class KaldheimRun extends CardRun {
private static final KaldheimRun commonA = new KaldheimRun(true, 34, 77, 136, 13, 78, 149, 3, 47, 127, 14, 67, 140, 19, 54, 124, 38, 49, 147, 39, 55, 157, 1, 53, 141, 37, 66, 126, 10, 71, 155, 4, 65, 121, 13, 77, 136, 34, 78, 127, 3, 47, 149, 14, 54, 124, 38, 67, 140, 19, 55, 147, 39, 49, 157, 37, 53, 141, 10, 65, 155, 1, 71, 121, 4, 66, 126);
private static final KaldheimRun commonB = new KaldheimRun(true, 102, 176, 87, 183, 93, 184, 104, 178, 117, 174, 111, 171, 96, 194, 84, 176, 119, 180, 83, 164, 89, 172, 87, 175, 102, 183, 104, 178, 93, 174, 117, 184, 111, 171, 84, 194, 119, 164, 96, 180, 89, 176, 83, 172, 102, 175, 87, 178, 104, 174, 93, 183, 117, 171, 119, 184, 84, 164, 111, 194, 89, 180, 96, 172, 83, 175);
private static final KaldheimRun commonC1 = new KaldheimRun(true, 187, 152, 242, 46, 173, 23, 101, 246, 48, 190, 32, 151, 99, 68, 267, 31, 91, 192, 143, 57, 100, 243, 105, 16, 134, 42, 196, 238, 187, 46, 23, 242, 152, 173, 48, 32, 246, 190, 151, 101, 31, 68, 99, 267, 91, 134, 105, 57, 16, 192, 100, 143, 243, 196, 42);
private static final KaldheimRun commonC2 = new KaldheimRun(true, 11, 193, 95, 158, 17, 239, 44, 159, 129, 7, 118, 85, 138, 74, 165, 11, 129, 193, 150, 72, 5, 95, 159, 74, 158, 17, 85, 239, 118, 138, 44, 7, 238, 193, 150, 165, 5, 72, 158, 95, 11, 44, 159, 239, 129, 17, 85, 74, 7, 118, 5, 150, 165, 138, 72);
private static final KaldheimRun uncommonA = new KaldheimRun(true, 215, 236, 212, 208, 195, 224, 332, 6, 232, 18, 106, 268, 209, 162, 8, 76, 122, 88, 182, 206, 202, 62, 110, 132, 200, 325, 271, 211, 144, 103, 215, 236, 258, 56, 163, 113, 28, 226, 2, 58, 263, 148, 232, 162, 224, 208, 195, 323, 268, 18, 106, 6, 233, 8, 76, 122, 209, 88, 182, 206, 202, 62, 110, 132, 321, 220, 271, 211, 144, 258, 2, 28, 263, 113, 226, 103, 236, 163, 56, 215, 148, 58, 329, 195, 6, 232, 233, 18, 212, 162, 268, 106, 208, 103, 322, 76, 122, 88, 182, 206, 202, 62, 110, 132, 200, 220, 271, 211, 144, 8, 58, 28, 258, 113, 56, 148, 2, 263, 226, 163);
private static final KaldheimRun uncommonB = new KaldheimRun(true, 30, 166, 75, 201, 265, 222, 45, 135, 256, 191, 231, 235, 36, 250, 316, 128, 25, 247, 264, 35, 97, 186, 223, 59, 60, 130, 216, 80, 244, 259, 217, 133, 64, 245, 108, 189, 331, 137, 116, 253, 30, 166, 75, 201, 265, 327, 45, 128, 256, 247, 235, 36, 191, 25, 170, 250, 135, 231, 186, 35, 60, 324, 97, 130, 59, 264, 244, 80, 328, 259, 133, 217, 64, 245, 108, 189, 230, 137, 116, 253, 30, 166, 75, 201, 265, 222, 45, 256, 191, 235, 170, 135, 36, 128, 25, 247, 250, 231, 35, 223, 60, 130, 97, 264, 216, 186, 59, 244, 80, 259, 217, 133, 304, 245, 108, 189, 230, 137, 116, 253);
private static final KaldheimRun rareA = new KaldheimRun(false, 9, 20, 21, 24, 26, 29, 43, 50, 51, 52, 61, 63, 69, 73, 82, 86, 90, 92, 107, 109, 112, 115, 120, 123, 125, 131, 142, 146, 161, 169, 179, 181, 185, 188, 197, 203, 204, 205, 207, 210, 213, 219, 227, 228, 229, 234, 237, 240, 241, 251, 252, 254, 255, 260, 272, 275, 9, 20, 21, 24, 26, 29, 43, 50, 51, 52, 61, 63, 69, 73, 82, 86, 90, 92, 107, 109, 112, 115, 120, 123, 125, 131, 142, 146, 161, 169, 179, 181, 185, 188, 197, 203, 204, 205, 207, 210, 213, 219, 227, 228, 229, 234, 237, 240, 241, 251, 252, 254, 255, 260, 272, 275, 15, 22, 33, 40, 41, 70, 94, 98, 114, 145, 154, 160, 168, 198, 218, 221, 225, 320);
private static final KaldheimRun rareB = new KaldheimRun(false, 9, 20, 300, 24, 26, 301, 43, 303, 51, 52, 61, 63, 69, 73, 82, 86, 90, 306, 107, 109, 307, 309, 310, 311, 125, 131, 312, 146, 161, 315, 317, 318, 185, 188, 319, 203, 204, 205, 207, 210, 213, 219, 227, 330, 229, 234, 237, 240, 241, 290, 291, 292, 255, 293, 272, 275, 9, 20, 300, 24, 26, 301, 43, 303, 51, 52, 61, 63, 69, 73, 82, 86, 90, 306, 107, 109, 307, 309, 310, 311, 125, 131, 312, 146, 161, 315, 317, 318, 185, 188, 319, 203, 204, 205, 207, 210, 213, 219, 227, 330, 229, 234, 237, 240, 241, 290, 291, 292, 255, 293, 272, 275, 299, 22, 294, 302, 295, 305, 94, 296, 308, 297, 313, 298, 314, 287, 288, 326, 289, 320);
private static final KaldheimRun land = new KaldheimRun(true, 276, 277, 283, 249, 278, 285, 248, 276, 285, 279, 261, 269, 257, 249, 248, 283, 270, 285, 277, 282, 284, 270, 278, 248, 279, 269, 281, 274, 280, 279, 257, 281, 284, 277, 257, 274, 273, 279, 276, 262, 266, 284, 281, 273, 282, 278, 262, 280, 279, 274, 262, 282, 283, 278, 262, 279, 261, 285, 273, 266, 283, 261, 280, 284, 266, 278, 270, 285, 282, 280, 276, 277, 273, 278, 269, 273, 249, 261, 274);
private KaldheimRun(boolean keepOrder, Integer... names) {
super(keepOrder, names);
}
}
private static class KaldheimStructure extends BoosterStructure {
private static final KaldheimStructure C1 = new KaldheimStructure(
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonB,
KaldheimRun.commonB,
KaldheimRun.commonC1,
KaldheimRun.commonC1,
KaldheimRun.commonC1,
KaldheimRun.commonC1,
KaldheimRun.commonC1,
KaldheimRun.commonC1
);
private static final KaldheimStructure C2 = new KaldheimStructure(
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonB,
KaldheimRun.commonB,
KaldheimRun.commonC1,
KaldheimRun.commonC1,
KaldheimRun.commonC1,
KaldheimRun.commonC1,
KaldheimRun.commonC1
);
private static final KaldheimStructure C3 = new KaldheimStructure(
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonB,
KaldheimRun.commonB,
KaldheimRun.commonB,
KaldheimRun.commonC2,
KaldheimRun.commonC2,
KaldheimRun.commonC2,
KaldheimRun.commonC2
);
private static final KaldheimStructure C4 = new KaldheimStructure(
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonB,
KaldheimRun.commonB,
KaldheimRun.commonB,
KaldheimRun.commonC2,
KaldheimRun.commonC2,
KaldheimRun.commonC2
);
private static final KaldheimStructure C5 = new KaldheimStructure(
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonA,
KaldheimRun.commonB,
KaldheimRun.commonB,
KaldheimRun.commonC2,
KaldheimRun.commonC2,
KaldheimRun.commonC2,
KaldheimRun.commonC2
);
private static final KaldheimStructure U1 = new KaldheimStructure(
KaldheimRun.uncommonA,
KaldheimRun.uncommonA,
KaldheimRun.uncommonA
);
private static final KaldheimStructure U2 = new KaldheimStructure(
KaldheimRun.uncommonB,
KaldheimRun.uncommonB,
KaldheimRun.uncommonB
);
private static final KaldheimStructure R1 = new KaldheimStructure(
KaldheimRun.rareA
);
private static final KaldheimStructure R2 = new KaldheimStructure(
KaldheimRun.rareB
);
private static final KaldheimStructure L1 = new KaldheimStructure(
KaldheimRun.land
);
private KaldheimStructure(CardRun... runs) {
super(runs);
}
}
private final RarityConfiguration commonRuns = new RarityConfiguration(
false,
KaldheimStructure.C1,
KaldheimStructure.C2,
KaldheimStructure.C3,
KaldheimStructure.C4,
KaldheimStructure.C5,
KaldheimStructure.C1,
KaldheimStructure.C2,
KaldheimStructure.C3,
KaldheimStructure.C4,
KaldheimStructure.C5,
KaldheimStructure.C4,
KaldheimStructure.C5
);
private final RarityConfiguration uncommonRuns = new RarityConfiguration(
KaldheimStructure.U1,
KaldheimStructure.U2
);
private final RarityConfiguration rareRuns = new RarityConfiguration(
false,
KaldheimStructure.R1,
KaldheimStructure.R1,
KaldheimStructure.R2
);
private final RarityConfiguration landRuns = new RarityConfiguration(
KaldheimStructure.L1
);
@Override
public void shuffle() {
commonRuns.shuffle();
uncommonRuns.shuffle();
rareRuns.shuffle();
landRuns.shuffle();
}
@Override
public List<Integer> makeBooster() {
List<Integer> booster = new ArrayList<>();
booster.addAll(commonRuns.getNext().makeRun());
booster.addAll(uncommonRuns.getNext().makeRun());
booster.addAll(rareRuns.getNext().makeRun());
booster.addAll(landRuns.getNext().makeRun());
return booster;
}
}

View file

@ -1,9 +1,16 @@
package mage.sets;
import mage.cards.ExpansionSet;
import mage.collation.BoosterCollator;
import mage.collation.BoosterStructure;
import mage.collation.CardRun;
import mage.collation.RarityConfiguration;
import mage.constants.Rarity;
import mage.constants.SetType;
import java.util.ArrayList;
import java.util.List;
/**
* @author TheElk801
*/
@ -16,7 +23,7 @@ public final class TherosBeyondDeath extends ExpansionSet {
}
private TherosBeyondDeath() {
super("Theros Beyond Death", "THB", ExpansionSet.buildDate(2020, 1, 24), SetType.EXPANSION);
super("Theros Beyond Death", "THB", ExpansionSet.buildDate(2020, 1, 24), SetType.EXPANSION, new TherosBeyondDeathCollator());
this.blockName = "Theros Beyond Death";
this.hasBoosters = true;
this.numBoosterLands = 1;
@ -385,3 +392,158 @@ public final class TherosBeyondDeath extends ExpansionSet {
cards.add(new SetCardInfo("Wrap in Flames", 164, Rarity.COMMON, mage.cards.w.WrapInFlames.class));
}
}
// Booster collation info from https://www.lethe.xyz/mtg/collation/thb.html
// Using USA collation for common/uncommon, rare collation inferred from other sets
class TherosBeyondDeathCollator implements BoosterCollator {
private static class TherosBeyondDeathRun extends CardRun {
private static final TherosBeyondDeathRun commonA = new TherosBeyondDeathRun(true, 155, 29, 79, 127, 38, 57, 159, 41, 66, 140, 30, 78, 163, 28, 56, 137, 25, 68, 144, 20, 67, 146, 26, 49, 134, 40, 61, 159, 29, 51, 164, 17, 57, 149, 38, 66, 127, 30, 47, 144, 36, 79, 155, 41, 67, 137, 28, 78, 140, 25, 56, 163, 20, 49, 146, 40, 68, 134, 17, 51, 149, 26, 47, 164, 36, 61);
private static final TherosBeyondDeathRun commonB = new TherosBeyondDeathRun(true, 186, 85, 191, 116, 201, 103, 202, 115, 184, 120, 194, 110, 192, 88, 177, 113, 171, 86, 195, 109, 179, 114, 202, 85, 201, 103, 184, 116, 186, 115, 192, 110, 191, 114, 177, 120, 194, 88, 171, 113, 179, 86, 195, 109, 201, 85, 184, 116, 202, 110, 186, 103, 191, 115, 192, 114, 179, 113, 194, 109, 195, 86, 177, 88, 171, 120);
private static final TherosBeyondDeathRun commonC1 = new TherosBeyondDeathRun(true, 203, 154, 106, 77, 10, 174, 58, 16, 141, 238, 122, 46, 173, 152, 22, 240, 100, 74, 200, 142, 97, 11, 48, 203, 241, 154, 106, 35, 82, 174, 77, 10, 240, 141, 100, 58, 238, 122, 232, 152, 22, 46, 111, 173, 241, 16, 74, 97, 48, 11, 200, 142, 111, 82, 35);
private static final TherosBeyondDeathRun commonC2 = new TherosBeyondDeathRun(true, 44, 96, 197, 145, 232, 34, 126, 204, 249, 54, 135, 231, 187, 175, 44, 143, 95, 96, 197, 135, 107, 6, 32, 204, 126, 34, 54, 249, 145, 231, 187, 96, 6, 143, 44, 107, 34, 175, 135, 249, 95, 197, 54, 204, 126, 32, 6, 175, 95, 231, 145, 107, 187, 32, 143);
private static final TherosBeyondDeathRun uncommonA = new TherosBeyondDeathRun(true, 223, 65, 153, 8, 112, 227, 99, 167, 33, 138, 4, 189, 228, 45, 59, 180, 105, 1, 136, 196, 206, 139, 83, 89, 233, 31, 131, 91, 219, 193, 27, 133, 64, 199, 213, 264, 42, 153, 205, 8, 136, 4, 189, 33, 223, 2, 138, 112, 27, 233, 260, 180, 31, 59, 99, 131, 105, 267, 81, 139, 228, 167, 133, 219, 65, 1, 83, 125, 206, 193, 42, 91, 227, 89, 199, 153, 8, 81, 213, 64, 112, 223, 4, 136, 205, 105, 139, 99, 65, 2, 180, 228, 59, 1, 233, 45, 189, 227, 33, 196, 83, 138, 206, 42, 219, 167, 131, 31, 89, 193, 91, 125, 213, 199, 81, 27, 2, 64, 133, 205);
private static final TherosBeyondDeathRun uncommonB = new TherosBeyondDeathRun(true, 226, 101, 128, 183, 21, 234, 87, 50, 242, 176, 239, 132, 9, 216, 62, 119, 172, 160, 104, 69, 168, 225, 130, 237, 63, 15, 102, 166, 5, 129, 121, 53, 239, 70, 182, 128, 21, 234, 92, 69, 101, 160, 23, 230, 75, 130, 104, 172, 50, 7, 162, 87, 183, 226, 62, 216, 258, 132, 176, 237, 263, 15, 242, 63, 5, 225, 168, 129, 121, 53, 230, 21, 70, 102, 166, 128, 92, 234, 23, 183, 160, 104, 75, 226, 162, 7, 239, 182, 9, 132, 101, 69, 172, 216, 242, 50, 176, 87, 225, 62, 15, 168, 119, 237, 130, 5, 70, 102, 166, 63, 23, 129, 121, 53, 182, 7, 162, 230, 92, 75);
private static final TherosBeyondDeathRun rareA = new TherosBeyondDeathRun(false, 207, 84, 165, 3, 43, 209, 210, 212, 214, 169, 90, 12, 13, 215, 94, 217, 98, 218, 19, 24, 222, 243, 178, 55, 181, 108, 188, 235, 148, 60, 151, 198, 236, 37, 156, 157, 39, 158, 244, 245, 246, 247, 248, 72, 73, 124, 170, 76, 117, 118, 161, 80, 123, 207, 84, 165, 3, 43, 209, 210, 212, 214, 169, 90, 12, 13, 215, 94, 217, 98, 218, 19, 24, 222, 243, 178, 55, 181, 108, 188, 235, 148, 60, 151, 198, 236, 37, 156, 157, 39, 158, 244, 245, 246, 247, 248, 72, 73, 124, 170, 76, 117, 118, 161, 80, 123, 14, 18, 52, 71, 93, 147, 150, 185, 190, 208, 211, 220, 221, 224, 229);
private static final TherosBeyondDeathRun rareB = new TherosBeyondDeathRun(false, 207, 84, 165, 3, 43, 209, 210, 212, 214, 169, 90, 12, 13, 215, 94, 217, 98, 218, 19, 24, 222, 243, 178, 55, 181, 108, 188, 235, 148, 60, 151, 198, 236, 37, 156, 157, 39, 158, 244, 245, 246, 247, 248, 72, 73, 124, 170, 76, 117, 118, 161, 80, 123, 207, 84, 165, 3, 43, 209, 210, 212, 214, 169, 90, 12, 13, 215, 94, 217, 98, 218, 19, 24, 222, 243, 178, 55, 181, 108, 188, 235, 148, 60, 151, 198, 236, 37, 156, 157, 39, 158, 244, 245, 246, 247, 248, 72, 73, 124, 170, 76, 117, 118, 161, 80, 123, 255, 259, 52, 261, 262, 147, 265, 266, 190, 256, 257, 268, 221, 224, 229);
private static final TherosBeyondDeathRun land = new TherosBeyondDeathRun(false, 250, 251, 252, 253, 254);
private TherosBeyondDeathRun(boolean keepOrder, Integer... names) {
super(keepOrder, names);
}
}
private static class TherosBeyondDeathStructure extends BoosterStructure {
private static final TherosBeyondDeathStructure C1 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1
);
private static final TherosBeyondDeathStructure C2 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1
);
private static final TherosBeyondDeathStructure C3 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2
);
private static final TherosBeyondDeathStructure C4 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2
);
private static final TherosBeyondDeathStructure C5 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonB,
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2
);
private static final TherosBeyondDeathStructure U1 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.uncommonA,
TherosBeyondDeathRun.uncommonB,
TherosBeyondDeathRun.uncommonB
);
private static final TherosBeyondDeathStructure U2 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.uncommonA,
TherosBeyondDeathRun.uncommonA,
TherosBeyondDeathRun.uncommonB
);
private static final TherosBeyondDeathStructure R1 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.rareA
);
private static final TherosBeyondDeathStructure R2 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.rareB
);
private static final TherosBeyondDeathStructure L1 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.land
);
private TherosBeyondDeathStructure(CardRun... runs) {
super(runs);
}
}
private final RarityConfiguration commonRuns = new RarityConfiguration(
false,
TherosBeyondDeathStructure.C1,
TherosBeyondDeathStructure.C2,
TherosBeyondDeathStructure.C3,
TherosBeyondDeathStructure.C4,
TherosBeyondDeathStructure.C5,
TherosBeyondDeathStructure.C1,
TherosBeyondDeathStructure.C2,
TherosBeyondDeathStructure.C3,
TherosBeyondDeathStructure.C4,
TherosBeyondDeathStructure.C5,
TherosBeyondDeathStructure.C4,
TherosBeyondDeathStructure.C5
);
private final RarityConfiguration uncommonRuns = new RarityConfiguration(
TherosBeyondDeathStructure.U1,
TherosBeyondDeathStructure.U2
);
private final RarityConfiguration rareRuns = new RarityConfiguration(
false,
TherosBeyondDeathStructure.R1,
TherosBeyondDeathStructure.R1,
TherosBeyondDeathStructure.R2
);
private final RarityConfiguration landRuns = new RarityConfiguration(
TherosBeyondDeathStructure.L1
);
@Override
public void shuffle() {
commonRuns.shuffle();
uncommonRuns.shuffle();
rareRuns.shuffle();
landRuns.shuffle();
}
@Override
public List<Integer> makeBooster() {
List<Integer> booster = new ArrayList<>();
booster.addAll(commonRuns.getNext().makeRun());
booster.addAll(uncommonRuns.getNext().makeRun());
booster.addAll(rareRuns.getNext().makeRun());
booster.addAll(landRuns.getNext().makeRun());
return booster;
}
}

View file

@ -335,6 +335,7 @@ public class BoosterGenerationTest extends MageTestBase {
boolean foundVale = false;
boolean foundMDFC = false;
boolean foundNoMDFC = false;
for (int i = 1; i <= 100; i++) {
List<Card> booster = Kaldheim.getInstance().createBooster();

View file

@ -6,6 +6,7 @@ import mage.abilities.keyword.PartnerWithAbility;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.collation.BoosterCollator;
import mage.constants.Rarity;
import mage.constants.SetType;
import mage.util.CardUtil;
@ -26,7 +27,7 @@ public abstract class ExpansionSet implements Serializable {
public static final CardGraphicInfo FULL_ART_BFZ_VARIOUS = new CardGraphicInfo(FrameStyle.BFZ_FULL_ART_BASIC, true);
public static final CardGraphicInfo FULL_ART_ZEN_VARIOUS = new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true);
public class SetCardInfo implements Serializable {
public static class SetCardInfo implements Serializable {
private final String name;
private final String cardNumber;
@ -92,6 +93,7 @@ public abstract class ExpansionSet implements Serializable {
protected Date releaseDate;
protected ExpansionSet parentSet;
protected SetType setType;
protected BoosterCollator boosterCollator;
// TODO: 03.10.2018, hasBasicLands can be removed someday -- it's uses to optimize lands search in deck generation and lands adding (search all available lands from sets)
protected boolean hasBasicLands = true;
@ -120,14 +122,23 @@ public abstract class ExpansionSet implements Serializable {
protected int maxCardNumberInBooster; // used to omit cards with collector numbers beyond the regular cards in a set for boosters
protected final EnumMap<Rarity, List<CardInfo>> savedCards;
protected final Map<Integer, CardInfo> inBoosterMap = new HashMap<>();
public ExpansionSet(String name, String code, Date releaseDate, SetType setType) {
this(name, code, releaseDate, setType, null);
}
public ExpansionSet(String name, String code, Date releaseDate, SetType setType, BoosterCollator boosterCollator) {
this.name = name;
this.code = code;
this.releaseDate = releaseDate;
this.setType = setType;
this.maxCardNumberInBooster = Integer.MAX_VALUE;
savedCards = new EnumMap<>(Rarity.class);
this.boosterCollator = boosterCollator;
if (this.boosterCollator != null) {
this.boosterCollator.shuffle();
}
}
public String getName() {
@ -240,6 +251,9 @@ public abstract class ExpansionSet implements Serializable {
}
public List<Card> createBooster() {
if (boosterCollator != null) {
return createBoosterUsingCollator();
}
for (int i = 0; i < 100; i++) {//don't want to somehow loop forever
@ -262,6 +276,30 @@ public abstract class ExpansionSet implements Serializable {
return tryBooster();
}
public void shuffleCollator() {
if (boosterCollator != null) {
boosterCollator.shuffle();
}
}
private List<Card> createBoosterUsingCollator() {
if (inBoosterMap.isEmpty()) {
CardCriteria criteria = new CardCriteria();
criteria.setCodes(code);
CardRepository
.instance
.findCards(criteria)
.stream()
.forEach(cardInfo -> inBoosterMap.put(cardInfo.getCardNumberAsInt(), cardInfo));
}
return boosterCollator
.makeBooster()
.stream()
.map(inBoosterMap::get)
.map(CardInfo::getCard)
.collect(Collectors.toList());
}
protected boolean boosterIsValid(List<Card> booster) {
if (validateBoosterColors) {
if (!validateColors(booster)) {

View file

@ -0,0 +1,13 @@
package mage.collation;
import java.util.List;
/**
* @author TheElk801
*/
public interface BoosterCollator {
public void shuffle();
public List<Integer> makeBooster();
}

View file

@ -0,0 +1,36 @@
package mage.collation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Current implementation is built only for sequential collation
* Boosters are collated through a variety of different methods
* Striped collation not supported yet
* For more information: https://www.lethe.xyz/mtg/collation/
*
* @author TheElk801
*/
public abstract class BoosterStructure {
private final List<CardRun> slots;
protected BoosterStructure(CardRun... runs) {
this.slots = Arrays.asList(runs);
}
public List<Integer> makeRun() {
List<Integer> cards = new ArrayList<>();
for (CardRun run : this.slots) {
cards.add(run.getNext());
}
return cards;
}
public void shuffle() {
for (CardRun run : this.slots) {
run.shuffle();
}
}
}

View file

@ -0,0 +1,11 @@
package mage.collation;
/**
* @author TheElk801
*/
public abstract class CardRun extends Rotater<Integer> {
public CardRun(boolean keepOrder, Integer... names) {
super(keepOrder, names);
}
}

View file

@ -0,0 +1,27 @@
package mage.collation;
/**
* @author TheElk801
*/
public class RarityConfiguration extends Rotater<BoosterStructure> {
public RarityConfiguration(BoosterStructure item) {
super(item);
}
public RarityConfiguration(BoosterStructure item1, BoosterStructure item2) {
super(item1, item2);
}
public RarityConfiguration(boolean keepOrder, BoosterStructure... items) {
super(keepOrder, items);
}
@Override
public void shuffle() {
for (BoosterStructure structure : this.items) {
structure.shuffle();
}
super.shuffle();
}
}

View file

@ -0,0 +1,50 @@
package mage.collation;
import mage.util.RandomUtil;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* A class for shuffling a list by choosing a random starting point and looping through it
*
* @author TheElk801
*/
public class Rotater<T> {
protected final List<T> items;
private final boolean keepOrder;
private int position = 0;
public Rotater(T item) {
this(true, item);
}
public Rotater(T item1, T item2) {
this(true, item1, item2);
}
public Rotater(boolean keepOrder, T... items) {
this.items = Arrays.asList(items);
this.keepOrder = keepOrder;
}
public int iterate() {
int i = position;
position++;
position %= items.size();
return i;
}
public T getNext() {
return items.get(iterate());
}
public void shuffle() {
position = RandomUtil.nextInt(items.size());
if (!keepOrder) {
Collections.shuffle(items, RandomUtil.getRandom());
}
}
}