Add initial new themed chaos draft functionality

Add new randomizer
This commit is contained in:
pfirpfel
2020-10-21 14:43:51 +02:00
parent 7b5984557a
commit 01992c62e6
9 changed files with 292 additions and 35 deletions

View File

@@ -124,6 +124,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
private boolean smallSetOverride = false;
private String boosterMustContain = "";
private String boosterReplaceSlotFromPrintSheet = "";
private String[] chaosDraftThemes = new String[0];
private boolean doublePickToStartRound = false;
private final CardInSet[] cards;
private final Map<String, Integer> tokenNormalized;
@@ -195,6 +196,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public boolean getDoublePickToStartRound() { return doublePickToStartRound; }
public String getBoosterMustContain() { return boosterMustContain; }
public String getBoosterReplaceSlotFromPrintSheet() { return boosterReplaceSlotFromPrintSheet; }
public String[] getChaosDraftThemes() { return chaosDraftThemes; }
public CardInSet[] getCards() { return cards; }
public boolean isModern() { return getDate().after(parseDate("2003-07-27")); } //8ED and above are modern except some promo cards and others
@@ -385,6 +387,9 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
res.boosterMustContain = section.get("BoosterMustContain", ""); // e.g. Dominaria guaranteed legendary creature
res.boosterReplaceSlotFromPrintSheet = section.get("BoosterReplaceSlotFromPrintSheet", ""); // e.g. Zendikar Rising guaranteed double-faced card
res.chaosDraftThemes = section.get("ChaosDraftThemes", "").split(";"); // semicolon separated list of theme names
return res;
}

View File

@@ -1,25 +1,26 @@
package forge.item.generation;
import com.google.common.collect.Iterables;
import forge.card.CardEdition;
import forge.item.BoosterPack;
import forge.item.PaperCard;
import forge.util.BagRandomizer;
import java.util.List;
public class ChaosBoosterSupplier implements IUnOpenedProduct {
private List<CardEdition> sets;
private BagRandomizer<CardEdition> randomizer;
public ChaosBoosterSupplier(List<CardEdition> sets) {
this.sets = sets;
public ChaosBoosterSupplier(Iterable<CardEdition> sets) throws Exception {
if (Iterables.size(sets) <= 0) {
throw new Exception("At least one set needed to generate chaos draft!");
}
randomizer = new BagRandomizer<>(sets);
}
@Override
public List<PaperCard> get() {
if (sets.size() == 0) {
System.out.println("No chaos boosters left to supply.");
return null;
}
final CardEdition set = sets.remove(0);
final CardEdition set = randomizer.getNextItem();
final BoosterPack pack = new BoosterPack(set.getCode(), set.getBoosterTemplate());
return pack.getCards();
}

View File

@@ -0,0 +1,68 @@
package forge.util;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
/**
* Data structure that allows random draws from a set number of items,
* where all items are returned once before the first will be retrieved.
* The bag will be shuffled after each time all items have been returned.
* @param <T> an object
*/
public class BagRandomizer<T > implements Iterable<T>{
private static Random random = new SecureRandom();
private T[] bag;
private int currentPosition = 0;
public BagRandomizer(T[] items) {
bag = items;
}
public BagRandomizer(Iterable<T> items) {
ArrayList<T> list = new ArrayList<>();
for (T item : items) {
list.add(item);
}
bag = (T[]) list.toArray();
}
public T getNextItem() {
// reset bag if last position is reached
if (currentPosition >= bag.length) {
shuffleBag();
currentPosition = 0;
}
return bag[currentPosition++];
}
private void shuffleBag() {
int n = bag.length;
for (int i = 0; i < n; i++) {
int r = (int) (random.nextDouble() * (i + 1));
T swap = bag[r];
bag[r] = bag[i];
bag[i] = swap;
}
}
@Override
public Iterator<T> iterator() {
return new BagRandomizerIterator<T>();
}
private class BagRandomizerIterator<T> implements Iterator<T> {
@Override
public boolean hasNext() {
return bag.length > 0;
}
@Override
public T next() {
return (T) BagRandomizer.this.getNextItem();
}
}
}