Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * This class will be for generating per-tile random numbers, based on location
- * rather than time (i.e., coordinates rather than appearance in a sequence.
- *
- * It will use similar principle to Xorshift, and may even be a form of Xorshift
- * with different values per tile. The general idea is to derive shift sizes
- * based on coordinates and add a non-linear perturbation based on sector
- * coordinates -- or something along those lines. Should be simple, but still
- * some details to work out.
- *
- * IMPORTANT: This is intended for procedural content generation in games;
- * it is NOT cryptographic, and is NOT INTENDED NOR SUITED FOR SECURITY.
- *
- * @author Jared Blackburn
- */
- public class SpatialRandom {
- private final long seed;
- /*=====================================*
- * CONSTRUCTORS & BASIC CLASS METHODS *
- *=====================================*/
- public SpatialRandom() {
- long theSeed = System.nanoTime();
- seed = theSeed ^ (theSeed << 32);
- }
- public SpatialRandom(long theSeed) {
- seed = theSeed ^ (theSeed << 32);
- }
- /*====================================*
- * NON-STATIC METHODS USING THE SEED *
- *====================================*/
- /**
- * Generate a boolean from a given seed and coords.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public boolean booleanFor(int x, int y, int z, int t) {
- return ((longFromSeed(seed, x, y, z, t) % 2) == 0);
- }
- /**
- * Should generate num boolean values using longFor.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @param num
- * @return
- */
- public boolean[] booleansFor(int x, int y, int z, int t, int num) {
- boolean[] out = new boolean[num];
- long nextSeed = intFor(x, y, z, t);
- for(int i = 0; i < num; i++) {
- out[i] = booleanFromSeed(nextSeed, x, y, z, t);
- nextSeed = longFromSeed(nextSeed, x, y, z, t);
- }
- return out;
- }
- /**
- * Generate a float from a given seed and coords.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public float floatFor(int x, int y, int z, int t) {
- return Math.abs(((float)(longFromSeed(seed, x, y, z, t))) /
- ((float)Long.MAX_VALUE));
- }
- /**
- * should generate num float values using longFor.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @param num
- * @return
- */
- public float[] floatsFor(int x, int y, int z, int t, int num) {
- float[] out = new float[num];
- long nextSeed = intFromSeed(seed, x, y, z, t);
- for(int i = 0; i < num; i++) {
- out[i] = floatFromSeed(nextSeed, x, y, z, t);
- nextSeed = longFromSeed(nextSeed, x, y, z, t);
- }
- return out;
- }
- /**
- * Generate a double from a given seed and coords.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public double doubleFor(int x, int y, int z, int t) {
- return Math.abs(((double)(longFromSeed(seed, x, y, z, t))) /
- ((double)Long.MAX_VALUE));
- }
- /**
- * should generate num double values using longFor.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @param num
- * @return
- */
- public double[] doublesFor(int x, int y, int z, int t, int num) {
- double[] out = new double[num];
- long nextSeed = longFromSeed(seed, x, y, z, t);
- for(int i = 0; i < num; i++) {
- out[i] = doubleFromSeed(nextSeed, x, y, z, t);
- nextSeed = longFromSeed(nextSeed, x, y, z, t);
- }
- return out;
- }
- /**
- * Should produce a random int from seed at coordinates x, y, t
- *
- * @param seed
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public int intFor(int x, int y, int z, int t) {
- return (int) longFromSeed(seed, x, y, z, t);
- }
- /**
- * should generate num int values using longFor.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @param num
- * @return
- */
- public int[] intsFor(int x, int y, int z, int t, int num) {
- int[] out = new int[num];
- out[0] = intFromSeed(seed, x, y, z, t);
- for(int i = 1; i < num; i++) {
- out[i] = intFromSeed(out[i-1], x, y, z, t);
- }
- return out;
- }
- /**
- * Should produce a random long from seed at coordinates x, y, t
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public long longFor(int x, int y, int z, int t) {
- long out = seed + (15485077L * (long)t)
- + (12338621L * (long)x)
- + (15485863L * (long)y)
- + (14416417L * (long)z);
- out ^= lshift(out, (x % 29) + 13);
- out ^= rshift(out, (y % 31) + 7);
- out ^= lshift(out, (z % 23) + 19);
- out ^= rshift(out, (t % 43) + 11);
- return out;
- }
- /**
- * should generate num long values using longFor.
- *
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @param num
- * @return
- */
- public long[] longsFor(int x, int y, int z, int t, int num) {
- long[] out = new long[num];
- out[0] = longFromSeed(seed, x, y, z, t);
- for(int i = 1; i < num; i++) {
- out[i] = longFromSeed(out[i-1], x, y, z, t);
- }
- return out;
- }
- /*==========================================*
- * STATIC METHODS TAKING A SEED DIRECTLY *
- *==========================================*/
- /**
- * Generate a boolean from a given seed and coords.
- *
- * @param seed
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public static boolean booleanFromSeed(long seed, int x, int y, int z, int t) {
- return ((longFromSeed(seed, x, y, z, t) % 2) == 0);
- }
- /**
- * Generate a float from a given seed and coords.
- *
- * @param seed
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public static float floatFromSeed(long seed, int x, int y, int z, int t) {
- return Math.abs(((float)(longFromSeed(seed, x, y, z, t))) /
- ((float)Long.MAX_VALUE));
- }
- /**
- * Generate a double from a given seed and coords.
- *
- * @param seed
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public static double doubleFromSeed(long seed, int x, int y, int z, int t) {
- return Math.abs(((double)(longFromSeed(seed, x, y, z, t))) /
- ((double)Long.MAX_VALUE));
- }
- /**
- * Should produce a random int from seed at coordinates x, y, t
- *
- * @param seed
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public static int intFromSeed(long seed, int x, int y, int z, int t) {
- return (int) longFromSeed(seed, x, y, z, t);
- }
- /**
- * Should produce a random long from seed at coordinates x, y, t
- *
- * @param seed
- * @param x
- * @param y
- * @param z
- * @param t a fake iteration
- * @return
- */
- public static long longFromSeed(long seed, int x, int y, int z, int t) {
- long out = seed + (15485077L * (long)t)
- + (12338621L * (long)x)
- + (15485863L * (long)y)
- + (14416417L * (long)z);
- out ^= lshift(out, (x % 29) + 13);
- out ^= rshift(out, (y % 31) + 7);
- out ^= lshift(out, (z % 23) + 19);
- out ^= rshift(out, (t % 43) + 11);
- return out;
- }
- /*=============================*
- * INTERNAL UNTILITY METHODS *
- ==============================*/
- /**
- * Performs left bit shift (<<) with wrap-around.
- *
- * @param in
- * @param dist
- * @return
- */
- private static long lshift(long in, long dist) {
- long out = in << dist;
- out += (in >>> (64 - dist));
- return out;
- }
- /**
- * Performs right bit shift (>>) with wrap-around.
- *
- * @param in
- * @param dist
- * @return
- */
- private static long rshift(long in, long dist) {
- long out = in >>> dist;
- out += (in << (64 - dist));
- return out;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement