Added seeds support to random util:

* all xmage code uses shared util to generate random values;
 * tests can uses seeds to repeat "random" results like deck builds or AI plays;
This commit is contained in:
Oleg Agafonov 2018-12-30 03:52:30 +04:00
parent 52df594396
commit 2ebad63595
13 changed files with 415 additions and 265 deletions

View file

@ -1,4 +1,3 @@
package mage.cards;
import mage.Mana;
@ -22,7 +21,6 @@ import java.io.PrintWriter;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class Sets extends HashMap<String, ExpansionSet> {
@ -75,6 +73,10 @@ public class Sets extends HashMap<String, ExpansionSet> {
}
public static List<Card> generateRandomCardPool(int cardsCount, List<ColoredManaSymbol> allowedColors, boolean onlyBasicLands) {
return generateRandomCardPool(cardsCount, allowedColors, onlyBasicLands, null);
}
public static List<Card> generateRandomCardPool(int cardsCount, List<ColoredManaSymbol> allowedColors, boolean onlyBasicLands, List<String> allowedSets) {
CardCriteria criteria = new CardCriteria();
if (onlyBasicLands) {
@ -94,6 +96,12 @@ public class Sets extends HashMap<String, ExpansionSet> {
criteria.colorless(false); // colorless is not allowed for gen
}
if (allowedSets != null && allowedSets.size() > 0) {
for (String code : allowedSets) {
criteria.setCodes(code);
}
}
FilterMana manaNeed = new FilterMana();
for (ColoredManaSymbol color : allowedColors) {
switch (color) {
@ -120,6 +128,9 @@ public class Sets extends HashMap<String, ExpansionSet> {
}
}
List<CardInfo> cards = CardRepository.instance.findCards(criteria);
if (cards.isEmpty()) {
throw new IllegalStateException("Can't find cards for chosen colors to generate deck: " + allowedColors);
}
int count = 0;
int tries = 0;
@ -137,21 +148,43 @@ public class Sets extends HashMap<String, ExpansionSet> {
// discard not needed color by mana produce
Assert.assertEquals("only basic lands allow, but found " + card.getName(), 1, card.getMana().size());
for (Mana manaLand : card.getMana()) {
if (manaLand.getWhite() > 0 && !manaNeed.isWhite()) { cardManaOK = false; }
if (manaLand.getBlue() > 0 && !manaNeed.isBlue()) { cardManaOK = false; }
if (manaLand.getBlack() > 0 && !manaNeed.isBlack()) { cardManaOK = false; }
if (manaLand.getRed() > 0 && !manaNeed.isRed()) { cardManaOK = false; }
if (manaLand.getGreen() > 0 && !manaNeed.isGreen()) { cardManaOK = false; }
if (manaLand.getColorless() > 0) { cardManaOK = false; } // ignore colorless land (wastes)
if (manaLand.getWhite() > 0 && !manaNeed.isWhite()) {
cardManaOK = false;
}
if (manaLand.getBlue() > 0 && !manaNeed.isBlue()) {
cardManaOK = false;
}
if (manaLand.getBlack() > 0 && !manaNeed.isBlack()) {
cardManaOK = false;
}
if (manaLand.getRed() > 0 && !manaNeed.isRed()) {
cardManaOK = false;
}
if (manaLand.getGreen() > 0 && !manaNeed.isGreen()) {
cardManaOK = false;
}
if (manaLand.getColorless() > 0) {
cardManaOK = false;
} // ignore colorless land (wastes)
}
} else {
// cards
// discard any card that have not needed color
if (manaCard.isWhite() && !manaNeed.isWhite()) { cardManaOK = false; }
if (manaCard.isBlue() && !manaNeed.isBlue()) { cardManaOK = false; }
if (manaCard.isBlack() && !manaNeed.isBlack()) { cardManaOK = false; }
if (manaCard.isRed() && !manaNeed.isRed()) { cardManaOK = false; }
if (manaCard.isGreen() && !manaNeed.isGreen()) { cardManaOK = false; }
if (manaCard.isWhite() && !manaNeed.isWhite()) {
cardManaOK = false;
}
if (manaCard.isBlue() && !manaNeed.isBlue()) {
cardManaOK = false;
}
if (manaCard.isBlack() && !manaNeed.isBlack()) {
cardManaOK = false;
}
if (manaCard.isRed() && !manaNeed.isRed()) {
cardManaOK = false;
}
if (manaCard.isGreen() && !manaNeed.isGreen()) {
cardManaOK = false;
}
}
if (cardManaOK) {

View file

@ -1,12 +1,11 @@
package mage.choices;
import mage.util.RandomUtil;
import java.io.Serializable;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class ChoiceImpl implements Choice, Serializable {
@ -22,7 +21,6 @@ public class ChoiceImpl implements Choice, Serializable {
protected String subMessage;
protected boolean searchEnabled = true; // enable for all windows by default
protected String searchText;
private static Random rnd = new Random();
public ChoiceImpl() {
this(false);
@ -69,10 +67,14 @@ public class ChoiceImpl implements Choice, Serializable {
}
@Override
public String getSubMessage(){ return subMessage; }
public String getSubMessage() {
return subMessage;
}
@Override
public void setSubMessage(String subMessage){ this.subMessage = subMessage; }
public void setSubMessage(String subMessage) {
this.subMessage = subMessage;
}
@Override
public Set<String> getChoices() {
@ -124,9 +126,9 @@ public class ChoiceImpl implements Choice, Serializable {
@Override
public String getChoiceValue() {
if ((keyChoices != null) && (keyChoices.containsKey(choiceKey))){
if ((keyChoices != null) && (keyChoices.containsKey(choiceKey))) {
return keyChoices.get(choiceKey);
}else{
} else {
return null;
}
}
@ -147,67 +149,67 @@ public class ChoiceImpl implements Choice, Serializable {
}
@Override
public boolean isSearchEnabled(){
public boolean isSearchEnabled() {
return this.searchEnabled;
};
}
@Override
public void setSearchEnabled(boolean isEnabled){
public void setSearchEnabled(boolean isEnabled) {
this.searchEnabled = isEnabled;
};
}
@Override
public void setSearchText(String searchText){
public void setSearchText(String searchText) {
this.searchText = searchText;
};
}
@Override
public String getSearchText(){
public String getSearchText() {
return this.searchText;
};
}
@Override
public boolean isSortEnabled(){
public boolean isSortEnabled() {
return (this.sortData != null) && !this.sortData.isEmpty();
};
}
@Override
public void setSortData(Map<String, Integer> sortData){
public void setSortData(Map<String, Integer> sortData) {
this.sortData = sortData;
};
}
@Override
public Map<String, Integer> getSortData(){
public Map<String, Integer> getSortData() {
return this.sortData;
};
}
@Override
public void setRandomChoice() {
if(this.isKeyChoice()){
if (this.isKeyChoice()) {
// key mode
String[] vals = this.getKeyChoices().keySet().toArray(new String[0]);
if(vals.length > 0) {
int choiceNum = rnd.nextInt(vals.length);
if (vals.length > 0) {
int choiceNum = RandomUtil.nextInt(vals.length);
this.setChoiceByKey(vals[choiceNum]);
}
} else {
// string mode
String[] vals = this.getChoices().toArray(new String[0]);
if(vals.length > 0) {
int choiceNum = rnd.nextInt(vals.length);
if (vals.length > 0) {
int choiceNum = RandomUtil.nextInt(vals.length);
this.setChoice(vals[choiceNum]);
}
}
}
@Override
public boolean setChoiceByAnswers(List<String> answers, boolean removeSelectAnswerFromList){
public boolean setChoiceByAnswers(List<String> answers, boolean removeSelectAnswerFromList) {
// select by answers
if(this.isKeyChoice()){
if (this.isKeyChoice()) {
// keys mode
for (String needChoice : answers) {
for (Map.Entry<String, String> currentChoice: this.getKeyChoices().entrySet()) {
for (Map.Entry<String, String> currentChoice : this.getKeyChoices().entrySet()) {
if (currentChoice.getKey().equals(needChoice)) {
this.setChoiceByKey(needChoice);
answers.remove(needChoice);

View file

@ -1,10 +1,5 @@
package mage.game.command;
import java.lang.reflect.Constructor;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.ObjectColor;
@ -26,8 +21,14 @@ import mage.constants.SuperType;
import mage.game.Game;
import mage.game.events.ZoneChangeEvent;
import mage.util.GameLog;
import mage.util.RandomUtil;
import mage.util.SubTypeList;
import java.lang.reflect.Constructor;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
/**
* @author spjspj
*/
@ -288,7 +289,7 @@ public class Plane implements CommandObject {
}
public static Plane getRandomPlane() {
int pick = new Random().nextInt(Planes.values().length);
int pick = RandomUtil.nextInt(Planes.values().length);
String planeName = Planes.values()[pick].toString();
planeName = "mage.game.command.planes." + planeName;
try {

View file

@ -1,33 +1,38 @@
package mage.util;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* Created by IGOUDT on 5-9-2016.
*/
public final class RandomUtil {
private static Random random = new Random(); // thread safe with seed support
private RandomUtil() {
}
public static Random getRandom() {
return ThreadLocalRandom.current();
return random;
}
public static int nextInt() {
return ThreadLocalRandom.current().nextInt();
return random.nextInt();
}
public static int nextInt(int max) {
return ThreadLocalRandom.current().nextInt(max);
return random.nextInt(max);
}
public static boolean nextBoolean() {
return ThreadLocalRandom.current().nextBoolean();
return random.nextBoolean();
}
public static double nextDouble() {
return ThreadLocalRandom.current().nextDouble();
return random.nextDouble();
}
public static void setSeed(long newSeed) {
random.setSeed(newSeed);
}
}