host.anzo.commons.utils.Rnd Maven / Gradle / Ivy
package host.anzo.commons.utils;
import host.anzo.commons.model.RouletteRandomEntry;
import org.apache.commons.lang3.RandomStringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author ANZO
*/
public class Rnd {
public static double get() { // get random number from 0 to 1
return ThreadLocalRandom.current().nextDouble();
}
/**
* Gets a random number between 0(inclusive) and n(exclusive)
*
* @param n The superior limit (exclusive)
* @return if positive: A number from 0 to n-1, if negative A number from n-1 to 0
*/
public static int get(int n) {
if (n == 0) {
return 0;
}
final int sign = n > 0 ? 1 : -1;
return sign * (ThreadLocalRandom.current().nextInt(Math.abs(n)));
}
public static long get(long n) {
if (n == 0) {
return 0;
}
final int sign = n > 0 ? 1 : -1;
return sign * (long) (ThreadLocalRandom.current().nextDouble() * n);
}
public static double get(double n) {
if (n == 0) {
return 0;
}
final int sign = n > 0 ? 1 : -1;
return sign * (ThreadLocalRandom.current().nextDouble() * n);
}
public static float get(float n) {
if (n == 0) {
return 0;
}
final int sign = n > 0 ? 1 : -1;
return sign * (ThreadLocalRandom.current().nextFloat() * n);
}
// get random number from min to max (not max-1 !)
public static int get(int min, int max) {
return min + get(max - min + 1);
}
// get random number from min to max (not max-1 !)
public static long get(long min, long max) {
return min + get(max - min + 1);
}
public static float get(float min, float max) {
return min + get(max - min);
}
public static double get(double min, double max) {
return min + get(max - min);
}
public static int nextInt() {
return ThreadLocalRandom.current().nextInt();
}
public static double nextDouble() {
return ThreadLocalRandom.current().nextDouble();
}
public static double nextGaussian() {
return ThreadLocalRandom.current().nextGaussian();
}
public static boolean nextBoolean() {
return ThreadLocalRandom.current().nextBoolean();
}
public static byte[] nextBytes(final byte[] bytes) {
ThreadLocalRandom.current().nextBytes(bytes);
return bytes;
}
/**
* Randomizer for chance calculation
* Recommending to use instead Rnd.get(n, n)
*
* @param chance in percent from 0 to 100
* @return {@code true} if success
* If chance <= 0, return false
* If chance >= 100, return true
*/
public static boolean getChance(int chance) {
return chance >= 1 && (chance > 99 || ThreadLocalRandom.current().nextInt(99) + 1 <= chance);
}
/**
* Randomizer for chance calculation
* Recommending to use instead Rnd.get(n, n) if we need high precision values
*
* @param chance in percent from 0 to 100
* @return {@code true} if success
* If chance <= 0, return false
* If chance >= 100, return true
*/
public static boolean getChance(double chance) {
return ThreadLocalRandom.current().nextDouble() * 100. <= chance;
}
public static boolean getChance(int chance, int divider) {
return getChance((double)chance / (double) divider);
}
public static E get(E @NotNull [] list) {
return list[get(list.length)];
}
public static int get(int @NotNull [] list) {
return list[get(list.length)];
}
public static @Nullable E get(@NotNull List list) {
if (list.isEmpty()) {
return null;
}
return list.get(get(list.size()));
}
public static E get(@NotNull List list, E defaultValue) {
if (list.isEmpty()) {
return defaultValue;
}
return list.get(get(list.size()));
}
@SuppressWarnings("unchecked")
public static @Nullable E get(@NotNull Collection collection) {
if (collection.isEmpty()) {
return null;
}
return (E) collection.toArray()[get(collection.size())];
}
public static > E get(@NotNull Class clazz) {
return clazz.getEnumConstants()[Rnd.get(clazz.getEnumConstants().length)];
}
public static @NotNull List getRouletteEntries(List input, int count) {
final List selectedMainTemplates = new ArrayList<>();
final List copyItems = new ArrayList<>(input);
for (int i = 0; i < count; i++) {
final int totalChance = copyItems.stream().mapToInt(RouletteRandomEntry::chance).sum();
final int randomValue = Rnd.get(totalChance);
int accumulatedChance = 0;
int selectedIndex = -1;
for (int j = 0; j < copyItems.size(); j++) {
accumulatedChance += copyItems.get(j).chance();
if (randomValue < accumulatedChance) {
selectedIndex = j;
break;
}
}
if (selectedIndex != -1) {
selectedMainTemplates.add(copyItems.remove(selectedIndex));
}
}
return selectedMainTemplates;
}
public static @Nullable RouletteRandomEntry getRouletteEntry(List input) {
return getRouletteEntries(input, 1).stream().findFirst().orElse(null);
}
public static double getRandomWithTick(double min, double max, long serverTick, long randomSeed) {
final long randomizeSeed = ((serverTick + randomSeed) * 0x01234567 * 0x89ABCDEF * 0x01234567 * 0x89ABCDEF * 'R' * 'a' * 'n' * 'd' * 'o' * 'm' * (randomSeed + 0x89ABCDEF)) & 0xffffffffL;
final long FIXED_RANDOM = randomizeSeed + (((randomizeSeed) % 11 - (randomizeSeed) % 10 + (randomizeSeed) % 9 - (randomizeSeed) % 8 + (randomizeSeed) % 7 - (randomizeSeed) % 6 + (randomizeSeed) % 5 - (randomizeSeed) % 4 + (randomizeSeed) % 3 - (randomizeSeed) % 2 + (randomizeSeed))) & 0xffffffffL;
return FIXED_RANDOM % (10000) / (10000.0f - 1.0f) * (max - min) + min;
}
public static @NotNull String getString(int length) {
return RandomStringUtils.randomAlphabetic(length);
}
public static @NotNull String getStringHex(int length) {
return RandomStringUtils.random(length, "0123456789abcdef");
}
}