mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Merge branch 'temp_dev6' into 'master'
Allow for Seeded RNG in simulation games! See merge request core-developers/forge!499
This commit is contained in:
@@ -2216,7 +2216,9 @@ public class ComputerUtil {
|
||||
}
|
||||
return ComputerUtilCard.getBestAI(list);
|
||||
} else {
|
||||
return Iterables.getFirst(votes.keySet(), null);
|
||||
// TODO: This is just picking randomly amongst already picked things. It should probably pick the worst instead.
|
||||
List<Object> a = Arrays.asList(votes.keySet().toArray());
|
||||
return a.get(MyRandom.getRandom().nextInt(a.size()));
|
||||
}
|
||||
case "Protection":
|
||||
if (votes.isEmpty()) {
|
||||
|
||||
@@ -134,7 +134,11 @@ public class ComputerUtilMana {
|
||||
Collections.sort(orderedCards, new Comparator<Card>() {
|
||||
@Override
|
||||
public int compare(final Card card1, final Card card2) {
|
||||
return Integer.compare(manaCardMap.get(card1), manaCardMap.get(card2));
|
||||
int result = Integer.compare(manaCardMap.get(card1), manaCardMap.get(card2));
|
||||
if(result == 0) {
|
||||
result = Float.compare(card1.getTimestamp(), card2.getTimestamp());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -308,7 +312,7 @@ public class ComputerUtilMana {
|
||||
}
|
||||
|
||||
// select which abilities may be used for each shard
|
||||
Multimap<ManaCostShard, SpellAbility> sourcesForShards = ComputerUtilMana.groupAndOrderToPayShards(ai, manaAbilityMap, cost);
|
||||
ListMultimap<ManaCostShard, SpellAbility> sourcesForShards = ComputerUtilMana.groupAndOrderToPayShards(ai, manaAbilityMap, cost);
|
||||
|
||||
sortManaAbilities(sourcesForShards);
|
||||
|
||||
@@ -858,7 +862,6 @@ public class ComputerUtilMana {
|
||||
}
|
||||
|
||||
AiController aic = ((PlayerControllerAi)ai.getController()).getAi();
|
||||
int chanceToReserve = aic.getIntProperty(AiProps.RESERVE_MANA_FOR_MAIN2_CHANCE);
|
||||
|
||||
PhaseType curPhase = ai.getGame().getPhaseHandler().getPhase();
|
||||
|
||||
@@ -877,7 +880,8 @@ public class ComputerUtilMana {
|
||||
// obey mana reservations for Main 2; otherwise, obey mana reservations depending on the "chance to reserve"
|
||||
// AI profile variable.
|
||||
if (sa.getSVar("LowPriorityAI").equals("")) {
|
||||
if (chanceToReserve == 0 || MyRandom.getRandom().nextInt(100) >= chanceToReserve) {
|
||||
float chanceToReserve = aic.getFloatProperty(AiProps.RESERVE_MANA_FOR_MAIN2_CHANCE);
|
||||
if (MyRandom.getRandom().nextDouble() >= chanceToReserve) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.ai.ComputerUtilAbility;
|
||||
|
||||
import forge.ai.ComputerUtilCard;
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.ai.ability;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.player.Player;
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.ai.ability;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.ai.ability;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilCost;
|
||||
import forge.ai.ComputerUtilMana;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.ComputerUtilMana;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CounterType;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilMana;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.SpecialCardAi;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
import forge.ai.ComputerUtilMana;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.ability.ApiType;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.card.CardSplitType;
|
||||
|
||||
@@ -34,22 +34,27 @@ public class MyRandom {
|
||||
private static Random random = new SecureRandom();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* percentTrue.<br>
|
||||
* If percent is like 30, then 30% of the time it will be true.
|
||||
* </p>
|
||||
*
|
||||
* @param percent
|
||||
* a int.
|
||||
* @return a boolean.
|
||||
* Changes into a non-CSPRNG, which can be seeded for use in tests/repeatable experiments.
|
||||
*/
|
||||
public static boolean percentTrue(final int percent) {
|
||||
return percent > MyRandom.getRandom().nextInt(100);
|
||||
public static void setSeed(int seed) {
|
||||
System.out.println("Setting the RNG seed to: " + seed);
|
||||
random = new Random(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns True with Percent probability.
|
||||
*
|
||||
* TODO: My guess is no one is passing in a number scaled to 100. This API should probably be cut.
|
||||
*/
|
||||
public static boolean percentTrue(final long percent) {
|
||||
return percent > MyRandom.getRandom().nextDouble() * 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the random.
|
||||
*
|
||||
* TODO: Make this private, and instead add a robust set of APIs here.
|
||||
*
|
||||
* @return the random
|
||||
*/
|
||||
public static Random getRandom() {
|
||||
@@ -60,7 +65,7 @@ public class MyRandom {
|
||||
int[] groups = new int[numGroups];
|
||||
|
||||
for (int i = 0; i < value; i++) {
|
||||
groups[random.nextInt(numGroups)]++;
|
||||
groups[MyRandom.getRandom().nextInt(numGroups)]++;
|
||||
}
|
||||
|
||||
return groups;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class KeywordCollection implements Iterable<String>, Serializable {
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.values().size();
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public int getAmount(Keyword keyword) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import forge.game.player.RegisteredPlayer;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.util.Lang;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class SimulateMatch {
|
||||
public static void simulate(String[] args) {
|
||||
@@ -55,6 +56,7 @@ public class SimulateMatch {
|
||||
}
|
||||
else {
|
||||
System.err.println("Illegal parameter usage");
|
||||
argumentHelp();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -78,6 +80,10 @@ public class SimulateMatch {
|
||||
type = GameType.valueOf(WordUtils.capitalize(params.get("f").get(0)));
|
||||
}
|
||||
|
||||
if (params.containsKey("s")) {
|
||||
MyRandom.setSeed(Integer.parseInt(params.get("s").get(0)));
|
||||
}
|
||||
|
||||
GameRules rules = new GameRules(type);
|
||||
rules.setAppliedVariants(EnumSet.of(type));
|
||||
|
||||
@@ -145,7 +151,7 @@ public class SimulateMatch {
|
||||
}
|
||||
|
||||
private static void argumentHelp() {
|
||||
System.out.println("Syntax: forge.exe sim -d <deck1[.dck]> ... <deckX[.dck]> -D [D] -n [N] -m [M] -t [T] -p [P] -f [F] -q");
|
||||
System.out.println("Syntax: forge.exe sim -d <deck1[.dck]> ... <deckX[.dck]> -D [D] -n [N] -m [M] -t [T] -p [P] -f [F] -s [S] -q");
|
||||
System.out.println("\tsim - stands for simulation mode");
|
||||
System.out.println("\tdeck1 (or deck2,...,X) - constructed deck name or filename (has to be quoted when contains multiple words)");
|
||||
System.out.println("\tdeck is treated as file if it ends with a dot followed by three numbers or letters");
|
||||
@@ -155,6 +161,7 @@ public class SimulateMatch {
|
||||
System.out.println("\tT - Type of tournament to run with all provided decks (Bracket, RoundRobin, Swiss)");
|
||||
System.out.println("\tP - Amount of players per match (used only with Tournaments, defaults to 2)");
|
||||
System.out.println("\tF - format of games, defaults to constructed");
|
||||
System.out.println("\ts - Set the RNG seed. Use if you want to play the same game twice.");
|
||||
System.out.println("\tq - Quiet flag. Output just the game result, not the entire game log.");
|
||||
}
|
||||
|
||||
@@ -167,7 +174,6 @@ public class SimulateMatch {
|
||||
final Game g1 = mc.createGame();
|
||||
// will run match in the same thread
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
TimeLimitedCodeBlock.runWithTimeout(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -183,7 +183,7 @@ public class GameSimulatorTest extends SimulationTestCase {
|
||||
GameSimulator sim = createSimulator(game, p);
|
||||
Game simGame = sim.getSimulatedGameState();
|
||||
|
||||
SpellAbility unmorphSA = findSAWithPrefix(ripper, "Morph—Reveal a black card");
|
||||
SpellAbility unmorphSA = findSAWithPrefix(ripper, "Morph"); // —Reveal a black card
|
||||
assertNotNull(unmorphSA);
|
||||
sim.simulateSpellAbility(unmorphSA);
|
||||
assertEquals(18, simGame.getPlayers().get(0).getLife());
|
||||
|
||||
@@ -29,12 +29,14 @@ import forge.item.IPaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.MyRandom;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SimulationTestCase extends TestCase {
|
||||
private static boolean initialized = false;
|
||||
|
||||
protected Game initAndCreateGame() {
|
||||
MyRandom.setSeed(0); // Initialize the random seed to create predictable tests.
|
||||
List<RegisteredPlayer> players = Lists.newArrayList();
|
||||
Deck d1 = new Deck();
|
||||
players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p2", null)));
|
||||
|
||||
@@ -368,9 +368,6 @@ public class QuestDraftUtils {
|
||||
// Update dialog with winner
|
||||
}
|
||||
|
||||
RegisteredPlayer regPlayer = mc.getWinner();
|
||||
//draft.setWinner(regPlayer.getPlayer().getName());
|
||||
//FModel.getQuest().save();
|
||||
gui.finishGame();
|
||||
} else {
|
||||
final HostedMatch newMatch = GuiBase.getInterface().hostMatch();
|
||||
|
||||
Reference in New Issue
Block a user