Created
January 9, 2021 18:06
-
-
Save Silthus/683f0b7d11dd5af0c2f2b094f0cb8f73 to your computer and use it in GitHub Desktop.
Pseudo Random Generator Comparison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IPseudoRandomGenerator { | |
/** | |
* The iteration count is increased on every failure and reset on a success. | |
* <p>You can reset it manually by calling {@link #reset()}. | |
* | |
* @return the current iteration count | |
*/ | |
int iteration(); | |
float chance(); | |
float baseChance(); | |
/** | |
* Hits the generator with a random number and checks if it is below the next chance. | |
* <p>Returns true if the check was successful and resets the iteration count. | |
* <p>Returns false if the check was a failure and increases the iteration count by one. | |
* | |
* @return the result of the random chance check against the iteration and base chance | |
*/ | |
boolean hit(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Random; | |
public class Main { | |
private static final long SEED = 1610212414097L; | |
private static final int ITERATIONS = Integer.MAX_VALUE; | |
private static final float CHANCE = 0.25f; | |
public static void main(String[] args) { | |
IPseudoRandomGenerator silthus = PseudoRandomGenerator.create(CHANCE, 1.0f, new Random(SEED)); | |
System.out.println("----- Silthus's Generator -----"); | |
System.out.println("resets iteration to 0 on success"); | |
System.out.println("nextChance: chance(" + CHANCE + ") * (iteration + 1)"); | |
System.out.println(); | |
calculate(silthus); | |
System.out.println(); | |
IPseudoRandomGenerator fs = PseudoRandomGeneratorFS.create(CHANCE, 1.0f, new Random(SEED)); | |
System.out.println("----- ForbiddenSoul's Generator -----"); | |
System.out.println("resets iteration to 0 on success"); | |
System.out.println("nextChance: chance(" + CHANCE + ") + (iteration * baseChance(" + fs.baseChance() + ")"); | |
System.out.println(); | |
calculate(fs); | |
System.out.println(); | |
IPseudoRandomGenerator fs2 = PseudoRandomGeneratorFS2.create(CHANCE, 1.0f, new Random(SEED)); | |
System.out.println("----- ForbiddenSoul's v2 Generator -----"); | |
System.out.println("nextChance: chance(" + CHANCE + ") + (failures * baseChance(" + fs.baseChance() + ") - (successes * baseChance(" + fs.baseChance() + ")"); | |
System.out.println(); | |
calculate(fs2); | |
} | |
private static void calculate(IPseudoRandomGenerator generator) { | |
Map<Integer, Integer> hitCount = new HashMap<>(); | |
int successes = 0; | |
for (int i = 0; i < ITERATIONS; i++) { | |
int iteration = generator.iteration() + 1; | |
if (generator.hit()) { | |
successes++; | |
hitCount.put(iteration, hitCount.getOrDefault(iteration, 0) + 1); | |
} | |
} | |
for (Map.Entry<Integer, Integer> entry : hitCount.entrySet()) { | |
System.out.println(entry.getKey() + ": " + entry.getValue() + " (" + String.format("%.2f", (entry.getValue() * 1.0d / successes) * 100.0d) + "%)"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Random; | |
import java.util.concurrent.ThreadLocalRandom; | |
/** | |
* The PseudoRandomGenerator is used to test an increasing chance based of the initial chance. | |
* <p> | |
* Use it to align the preceived chance of randomness for users with the actual randomness. | |
* <p> | |
* The generator will keep track of an iteration counter that will increase with every | |
* failed check and increase the chance for the next check. It resets after the chance was hit. | |
* <p> | |
* By default the base chance is multiplied with the iteration count. You can modify this | |
* by adjusting the {@link #multiplier()}. It defaults to 1.0f. | |
* <p> | |
* The base {@link #chance()} is calculated when creating the pseudo random generator based off | |
* the following formula: <pre>chance / ((1.0f / chance) - 1.0f)</pre> | |
* The chance cannot not be greater than 1 or less than 0. | |
* Any value above or below will be set to the min or max value. | |
* <br><p> | |
* You can {@link #reset()} the current iteration at any time and calculate the {@link #nextChance()} | |
* for the current iteration. | |
* <p>However when using this generator your practically only need to create it with your | |
* chance and optional multiplier and then call the {@link #hit()} method everytime the chance | |
* should be checked. The iteration counter will increase and reset automatically every time {@code hit()} is called. | |
* <br><pre>{@code | |
* // a chance of 25% will result in an initial base chance of 8.3% | |
* // and increase with every failed hit multiplied by the failed iterations | |
* // e.g.: after three failed iterations the nextChance() will be 33% and 41,5% after four failed attempts | |
* PseudoRandomGenerator random = PseudoRandomGenerator.create(0.25f); | |
* if (random.hit()) { | |
* // success | |
* } | |
* }</pre> | |
* | |
* @author Michael Reichenbach<michael@reichenbach.in> | |
* @since 08-01-2020 | |
* @version 2 | |
*/ | |
public final class PseudoRandomGenerator implements IPseudoRandomGenerator { | |
/** | |
* Creates a new PseudoRandomGenerator with the given chance. | |
* <p>The generator will use a default interation multiplier of 1.0f. | |
* | |
* @param chance the chance of the pseudo random generator as percentage. | |
* A chance greater than {@code 1.0} will be set to {@code 1.0} and less then {@code 0} will become {@code 0}. | |
* e.g.: {@code 0.25f} represents a chance of 25%. | |
* @return the created {@link PseudoRandomGenerator} with a fresh {@link Random} seed. | |
*/ | |
public static IPseudoRandomGenerator create(float chance) { | |
return new PseudoRandomGenerator(chance); | |
} | |
/** | |
* Creates a new PseudoRandomGenerator with the given chance using the supplied iteration multiplier. | |
* | |
* @param chance the chance of the pseudo random generator as percentage. | |
* A chance greater than {@code 1.0} will be set to {@code 1.0} and less then {@code 0} will become {@code 0}. | |
* e.g.: {@code 0.25f} represents a chance of 25%. | |
* @param multiplier the multiplier that is multiplied with the iteration count and base chance. | |
* This defaults to {@code 1.0f} when using the {@link #create(float)} method. | |
* @return the created {@link PseudoRandomGenerator} with a fresh {@link Random} seed. | |
*/ | |
public static IPseudoRandomGenerator create(float chance, float multiplier) { | |
return new PseudoRandomGenerator(chance, multiplier); | |
} | |
public static IPseudoRandomGenerator create(float chance, float multiplier, Random random) { | |
return new PseudoRandomGenerator(chance, multiplier, random); | |
} | |
private final Random random; | |
private final float chance; | |
private final float multiplier; | |
private int iteration = 0; | |
private PseudoRandomGenerator(float chance, float multiplier, Random random) { | |
this.random = random; | |
this.chance = calculateBaseChance(chance); | |
this.multiplier = multiplier; | |
} | |
private PseudoRandomGenerator(float chance, float multiplier) { | |
this(chance, multiplier, ThreadLocalRandom.current()); | |
} | |
private PseudoRandomGenerator(float chance) { | |
this(chance, 1.0f); | |
} | |
/** | |
* Gets the base chance that was intially calculated when creating the generator. | |
* <p>Use the {@link #nextChance()} method the retrieve the relative chance based off the current iteration. | |
* | |
* @return the base chance of this pseudo random generator | |
*/ | |
public float chance() { | |
return this.chance; | |
} | |
public float baseChance() { | |
return this.chance; | |
} | |
/** | |
* The multiplier is multiplied with the iteration count | |
* and base chance to calculate the {@link #nextChance()}. | |
* | |
* @return the multiplier that calculates the next chance | |
*/ | |
public float multiplier() { | |
return this.multiplier; | |
} | |
@Override | |
public int iteration() { | |
return this.iteration; | |
} | |
/** | |
* Sets the iteration of this generator to the given value. | |
* <p>Any value below zero will be set to zero. | |
* | |
* @param iteration the iteration that this generator is set to | |
* @return this generator | |
*/ | |
public IPseudoRandomGenerator iteration(int iteration) { | |
if (iteration < 0) iteration = 0; | |
this.iteration = iteration; | |
return this; | |
} | |
/** | |
* Calculates the chance for the next iteration. | |
* <p>The next chance is calculated like this: | |
* <pre>{@code | |
* chance() * ((iteration() + 1) * multiplier()) | |
* }</pre> | |
* | |
* @return the chance of the next iteration | |
*/ | |
public float nextChance() { | |
return chance() * ((iteration() + 1) * multiplier()); | |
} | |
/** | |
* Resets the iteration count of this generator back to zero. | |
* | |
* @return this generator | |
*/ | |
public IPseudoRandomGenerator reset() { | |
return iteration(0); | |
} | |
@Override | |
public boolean hit() { | |
if (random.nextFloat() < nextChance()) { | |
reset(); | |
return true; | |
} | |
iteration++; | |
return false; | |
} | |
private float calculateBaseChance(float chance) { | |
if (chance > 1.0) chance = 1.0f; | |
if (chance <= 0) chance = 1.0f; | |
// lets calculate the base chance by taking the number of times the action should hit | |
// e.g. with a chance of 0.25 -> 25% 1/4 should be a hit | |
return chance / ((1.0f / chance) - 1.0f); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Random; | |
import java.util.concurrent.ThreadLocalRandom; | |
/** | |
* The PseudoRandomGenerator is used to test an increasing chance based of the initial chance. | |
* <p> | |
* Use it to align the preceived chance of randomness for users with the actual randomness. | |
* <p> | |
* The generator will keep track of an iteration counter that will increase with every | |
* failed check and increase the chance for the next check. It resets after the chance was hit. | |
* <p> | |
* By default the base chance is multiplied with the iteration count. You can modify this | |
* by adjusting the {@link #multiplier()}. It defaults to 1.0f. | |
* <p> | |
* The base {@link #chance()} is calculated when creating the pseudo random generator based off | |
* the following formula: <pre>chance / ((1.0f / chance) - 1.0f)</pre> | |
* The chance cannot not be greater than 1 or less than 0. | |
* Any value above or below will be set to the min or max value. | |
* <br><p> | |
* You can {@link #reset()} the current iteration at any time and calculate the {@link #nextChance()} | |
* for the current iteration. | |
* <p>However when using this generator your practically only need to create it with your | |
* chance and optional multiplier and then call the {@link #hit()} method everytime the chance | |
* should be checked. The iteration counter will increase and reset automatically every time {@code hit()} is called. | |
* <br><pre>{@code | |
* // a chance of 25% will result in an initial base chance of 8.3% | |
* // and increase with every failed hit multiplied by the failed iterations | |
* // e.g.: after three failed iterations the nextChance() will be 33% and 41,5% after four failed attempts | |
* PseudoRandomGenerator random = PseudoRandomGenerator.create(0.25f); | |
* if (random.hit()) { | |
* // success | |
* } | |
* }</pre> | |
* | |
* @author Michael Reichenbach<michael@reichenbach.in> | |
* @since 08-01-2020 | |
* @version 2 | |
*/ | |
public final class PseudoRandomGeneratorFS implements IPseudoRandomGenerator { | |
/** | |
* Creates a new PseudoRandomGenerator with the given chance. | |
* <p>The generator will use a default interation multiplier of 1.0f. | |
* | |
* @param chance the chance of the pseudo random generator as percentage. | |
* A chance greater than {@code 1.0} will be set to {@code 1.0} and less then {@code 0} will become {@code 0}. | |
* e.g.: {@code 0.25f} represents a chance of 25%. | |
* @return the created {@link PseudoRandomGeneratorFS} with a fresh {@link Random} seed. | |
*/ | |
public static IPseudoRandomGenerator create(float chance) { | |
return new PseudoRandomGeneratorFS(chance); | |
} | |
/** | |
* Creates a new PseudoRandomGenerator with the given chance using the supplied iteration multiplier. | |
* | |
* @param chance the chance of the pseudo random generator as percentage. | |
* A chance greater than {@code 1.0} will be set to {@code 1.0} and less then {@code 0} will become {@code 0}. | |
* e.g.: {@code 0.25f} represents a chance of 25%. | |
* @param multiplier the multiplier that is multiplied with the iteration count and base chance. | |
* This defaults to {@code 1.0f} when using the {@link #create(float)} method. | |
* @return the created {@link PseudoRandomGeneratorFS} with a fresh {@link Random} seed. | |
*/ | |
public static IPseudoRandomGenerator create(float chance, float multiplier) { | |
return new PseudoRandomGeneratorFS(chance, multiplier); | |
} | |
public static IPseudoRandomGenerator create(float chance, float multiplier, Random random) { | |
return new PseudoRandomGeneratorFS(chance, multiplier, random); | |
} | |
private final Random random; | |
private final float chance; | |
private final float baseChance; | |
private final float multiplier; | |
private int iteration = 0; | |
private PseudoRandomGeneratorFS(float chance, float multiplier, Random random) { | |
this.random = random; | |
this.chance = chance; | |
this.baseChance = calculateBaseChance(chance); | |
this.multiplier = multiplier; | |
} | |
private PseudoRandomGeneratorFS(float chance, float multiplier) { | |
this(chance, multiplier, ThreadLocalRandom.current()); | |
} | |
private PseudoRandomGeneratorFS(float chance) { | |
this(chance, 1.0f); | |
} | |
/** | |
* Gets the base chance that was intially calculated when creating the generator. | |
* <p>Use the {@link #nextChance()} method the retrieve the relative chance based off the current iteration. | |
* | |
* @return the base chance of this pseudo random generator | |
*/ | |
public float chance() { | |
return this.chance; | |
} | |
public float baseChance() { | |
return this.baseChance; | |
} | |
/** | |
* The multiplier is multiplied with the iteration count | |
* and base chance to calculate the {@link #nextChance()}. | |
* | |
* @return the multiplier that calculates the next chance | |
*/ | |
public float multiplier() { | |
return this.multiplier; | |
} | |
/** | |
* The iteration count is increased on every failure and reset on a success. | |
* <p>You can reset it manually by calling {@link #reset()}. | |
* | |
* @return the current iteration count | |
*/ | |
public int iteration() { | |
return this.iteration; | |
} | |
/** | |
* Sets the iteration of this generator to the given value. | |
* <p>Any value below zero will be set to zero. | |
* | |
* @param iteration the iteration that this generator is set to | |
* @return this generator | |
*/ | |
public PseudoRandomGeneratorFS iteration(int iteration) { | |
if (iteration < 0) iteration = 0; | |
this.iteration = iteration; | |
return this; | |
} | |
/** | |
* Calculates the chance for the next iteration. | |
* <p>The next chance is calculated like this: | |
* <pre>{@code | |
* chance() * ((iteration() + 1) * multiplier()) | |
* }</pre> | |
* | |
* @return the chance of the next iteration | |
*/ | |
public float nextChance() { | |
return chance() + (iteration() * baseChance); | |
} | |
/** | |
* Resets the iteration count of this generator back to zero. | |
* | |
* @return this generator | |
*/ | |
public PseudoRandomGeneratorFS reset() { | |
return iteration(0); | |
} | |
/** | |
* Hits the generator with a random number and checks if it is below the next chance. | |
* <p>Returns true if the check was successful and resets the iteration count. | |
* <p>Returns false if the check was a failure and increases the iteration count by one. | |
* | |
* @return the result of the random chance check against the iteration and base chance | |
*/ | |
public boolean hit() { | |
if (random.nextFloat() < nextChance()) { | |
reset(); | |
return true; | |
} | |
iteration++; | |
return false; | |
} | |
private float calculateBaseChance(float chance) { | |
if (chance > 1.0) chance = 1.0f; | |
if (chance <= 0) chance = 1.0f; | |
// lets calculate the base chance by taking the number of times the action should hit | |
// e.g. with a chance of 0.25 -> 25% 1/4 should be a hit | |
return chance / ((1.0f / chance) - 1.0f); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Random; | |
import java.util.concurrent.ThreadLocalRandom; | |
/** | |
* The PseudoRandomGenerator is used to test an increasing chance based of the initial chance. | |
* <p> | |
* Use it to align the preceived chance of randomness for users with the actual randomness. | |
* <p> | |
* The generator will keep track of an iteration counter that will increase with every | |
* failed check and increase the chance for the next check. It resets after the chance was hit. | |
* <p> | |
* By default the base chance is multiplied with the iteration count. You can modify this | |
* by adjusting the {@link #multiplier()}. It defaults to 1.0f. | |
* <p> | |
* The base {@link #chance()} is calculated when creating the pseudo random generator based off | |
* the following formula: <pre>chance / ((1.0f / chance) - 1.0f)</pre> | |
* The chance cannot not be greater than 1 or less than 0. | |
* Any value above or below will be set to the min or max value. | |
* <br><p> | |
* You can {@link #reset()} the current iteration at any time and calculate the {@link #nextChance()} | |
* for the current iteration. | |
* <p>However when using this generator your practically only need to create it with your | |
* chance and optional multiplier and then call the {@link #hit()} method everytime the chance | |
* should be checked. The iteration counter will increase and reset automatically every time {@code hit()} is called. | |
* <br><pre>{@code | |
* // a chance of 25% will result in an initial base chance of 8.3% | |
* // and increase with every failed hit multiplied by the failed iterations | |
* // e.g.: after three failed iterations the nextChance() will be 33% and 41,5% after four failed attempts | |
* PseudoRandomGenerator random = PseudoRandomGenerator.create(0.25f); | |
* if (random.hit()) { | |
* // success | |
* } | |
* }</pre> | |
* | |
* @author Michael Reichenbach<michael@reichenbach.in> | |
* @since 08-01-2020 | |
* @version 2 | |
*/ | |
public final class PseudoRandomGeneratorFS2 implements IPseudoRandomGenerator { | |
/** | |
* Creates a new PseudoRandomGenerator with the given chance. | |
* <p>The generator will use a default interation multiplier of 1.0f. | |
* | |
* @param chance the chance of the pseudo random generator as percentage. | |
* A chance greater than {@code 1.0} will be set to {@code 1.0} and less then {@code 0} will become {@code 0}. | |
* e.g.: {@code 0.25f} represents a chance of 25%. | |
* @return the created {@link PseudoRandomGeneratorFS2} with a fresh {@link Random} seed. | |
*/ | |
public static IPseudoRandomGenerator create(float chance) { | |
return new PseudoRandomGeneratorFS2(chance); | |
} | |
/** | |
* Creates a new PseudoRandomGenerator with the given chance using the supplied iteration multiplier. | |
* | |
* @param chance the chance of the pseudo random generator as percentage. | |
* A chance greater than {@code 1.0} will be set to {@code 1.0} and less then {@code 0} will become {@code 0}. | |
* e.g.: {@code 0.25f} represents a chance of 25%. | |
* @param multiplier the multiplier that is multiplied with the iteration count and base chance. | |
* This defaults to {@code 1.0f} when using the {@link #create(float)} method. | |
* @return the created {@link PseudoRandomGeneratorFS2} with a fresh {@link Random} seed. | |
*/ | |
public static IPseudoRandomGenerator create(float chance, float multiplier) { | |
return new PseudoRandomGeneratorFS2(chance, multiplier); | |
} | |
public static IPseudoRandomGenerator create(float chance, float multiplier, Random random) { | |
return new PseudoRandomGeneratorFS2(chance, multiplier, random); | |
} | |
private final Random random; | |
private final float chance; | |
private final float baseChance; | |
private final float multiplier; | |
private int iteration = 0; | |
private int successes = 0; | |
private int failures = 0; | |
private PseudoRandomGeneratorFS2(float chance, float multiplier, Random random) { | |
this.random = random; | |
this.chance = chance; | |
this.baseChance = calculateBaseChance(chance); | |
this.multiplier = multiplier; | |
} | |
private PseudoRandomGeneratorFS2(float chance, float multiplier) { | |
this(chance, multiplier, ThreadLocalRandom.current()); | |
} | |
private PseudoRandomGeneratorFS2(float chance) { | |
this(chance, 1.0f); | |
} | |
/** | |
* Gets the base chance that was intially calculated when creating the generator. | |
* <p>Use the {@link #nextChance()} method the retrieve the relative chance based off the current iteration. | |
* | |
* @return the base chance of this pseudo random generator | |
*/ | |
public float chance() { | |
return this.chance; | |
} | |
public float baseChance() { | |
return this.baseChance; | |
} | |
/** | |
* The multiplier is multiplied with the iteration count | |
* and base chance to calculate the {@link #nextChance()}. | |
* | |
* @return the multiplier that calculates the next chance | |
*/ | |
public float multiplier() { | |
return this.multiplier; | |
} | |
/** | |
* The iteration count is increased on every failure and reset on a success. | |
* <p>You can reset it manually by calling {@link #reset()}. | |
* | |
* @return the current iteration count | |
*/ | |
public int iteration() { | |
return this.iteration; | |
} | |
/** | |
* Sets the iteration of this generator to the given value. | |
* <p>Any value below zero will be set to zero. | |
* | |
* @param iteration the iteration that this generator is set to | |
* @return this generator | |
*/ | |
public PseudoRandomGeneratorFS2 iteration(int iteration) { | |
if (iteration < 0) iteration = 0; | |
this.iteration = iteration; | |
return this; | |
} | |
/** | |
* Calculates the chance for the next iteration. | |
* <p>The next chance is calculated like this: | |
* <pre>{@code | |
* chance() * ((iteration() + 1) * multiplier()) | |
* }</pre> | |
* | |
* @return the chance of the next iteration | |
*/ | |
public float nextChance() { | |
return chance() + (failures * baseChance) - (successes * baseChance); | |
} | |
/** | |
* Resets the iteration count of this generator back to zero. | |
* | |
* @return this generator | |
*/ | |
public PseudoRandomGeneratorFS2 reset() { | |
return iteration(0); | |
} | |
/** | |
* Hits the generator with a random number and checks if it is below the next chance. | |
* <p>Returns true if the check was successful and resets the iteration count. | |
* <p>Returns false if the check was a failure and increases the iteration count by one. | |
* | |
* @return the result of the random chance check against the iteration and base chance | |
*/ | |
public boolean hit() { | |
if (random.nextFloat() < nextChance()) { | |
reset(); | |
successes++; | |
return true; | |
} else { | |
failures++; | |
} | |
iteration++; | |
return false; | |
} | |
private float calculateBaseChance(float chance) { | |
if (chance > 1.0) chance = 1.0f; | |
if (chance <= 0) chance = 1.0f; | |
// lets calculate the base chance by taking the number of times the action should hit | |
// e.g. with a chance of 0.25 -> 25% 1/4 should be a hit | |
return chance / ((1.0f / chance) - 1.0f); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
----- Silthus's Generator ----- | |
resets iteration to 0 on success | |
nextChance: chance(0.25) * (iteration + 1) | |
1: 44341432 (8.33%) | |
2: 81295346 (15.28%) | |
3: 101611626 (19.10%) | |
4: 101614106 (19.10%) | |
5: 84672084 (15.91%) | |
6: 59274814 (11.14%) | |
7: 34576154 (6.50%) | |
8: 16465103 (3.09%) | |
9: 6170278 (1.16%) | |
10: 1715980 (0.32%) | |
11: 314819 (0.06%) | |
12: 28475 (0.01%) | |
----- ForbiddenSoul's Generator ----- | |
resets iteration to 0 on success | |
nextChance: chance(0.25) + (iteration * baseChance(0.083333336) | |
1: 193499790 (25.00%) | |
2: 193499148 (25.00%) | |
3: 161245141 (20.83%) | |
4: 112888333 (14.58%) | |
5: 65838645 (8.51%) | |
6: 31354807 (4.05%) | |
7: 11759047 (1.52%) | |
8: 3266233 (0.42%) | |
9: 598738 (0.08%) | |
10: 54290 (0.01%) | |
----- ForbiddenSoul's v2 Generator ----- | |
nextChance: chance(0.25) + (failures * baseChance(0.083333336) - (successes * baseChance(0.083333336) | |
64: 2796203 (0.26%) | |
1: 1011750155 (94.23%) | |
65: 1398101 (0.13%) | |
129: 1398101 (0.13%) | |
2: 16841046 (1.57%) | |
66: 2796202 (0.26%) | |
3: 8868130 (0.83%) | |
4: 4654513 (0.43%) | |
5: 2327695 (0.22%) | |
6: 1185080 (0.11%) | |
7: 646652 (0.06%) | |
8: 1853248 (0.17%) | |
9: 401736 (0.04%) | |
10: 1791473 (0.17%) | |
11: 379572 (0.04%) | |
12: 307903 (0.03%) | |
13: 170789 (0.02%) | |
14: 108401 (0.01%) | |
15: 53570 (0.00%) | |
16: 2821542 (0.26%) | |
17: 1404970 (0.13%) | |
18: 2796202 (0.26%) | |
26: 1 (0.00%) | |
32: 2796203 (0.26%) | |
33: 1398101 (0.13%) | |
34: 2796202 (0.26%) | |
50: 1 (0.00%) | |
BUILD SUCCESSFUL in 1m 49s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment