Advertisement
BlackJar72

Spatially based Xorshift variation

Apr 30th, 2016
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.12 KB | None | 0 0
  1. /**
  2.  * This class will be for generating per-tile random numbers, based on location
  3.  * rather than time (i.e., coordinates rather than appearance in a sequence.
  4.  *
  5.  * It will use similar principle to Xorshift, and may even be a form of Xorshift
  6.  * with different values per tile.  The general idea is to derive shift sizes
  7.  * based on coordinates and add a non-linear perturbation based on sector
  8.  * coordinates -- or something along those lines.  Should be simple, but still
  9.  * some details to work out.
  10.  *
  11.  * IMPORTANT: This is intended for procedural content generation in games;
  12.  * it is NOT cryptographic, and is NOT INTENDED NOR SUITED FOR SECURITY.
  13.  *
  14.  * @author Jared Blackburn
  15.  */
  16. public class SpatialRandom {
  17.     private final long seed;
  18.    
  19.    
  20.     /*=====================================*
  21.      * CONSTRUCTORS & BASIC CLASS METHODS  *
  22.      *=====================================*/
  23.    
  24.    
  25.     public SpatialRandom() {
  26.         long theSeed = System.nanoTime();
  27.         seed = theSeed ^ (theSeed << 32);
  28.     }
  29.    
  30.    
  31.     public SpatialRandom(long theSeed) {
  32.         seed = theSeed ^ (theSeed << 32);
  33.     }
  34.    
  35.    
  36.     /*====================================*
  37.      *  NON-STATIC METHODS USING THE SEED *
  38.      *====================================*/
  39.    
  40.    
  41.     /**
  42.      * Generate a boolean from a given seed and coords.
  43.      *
  44.      * @param x
  45.      * @param y
  46.      * @param z
  47.      * @param t a fake iteration
  48.      * @return
  49.      */
  50.     public boolean booleanFor(int x, int y, int z, int t) {
  51.         return ((longFromSeed(seed, x, y, z, t) % 2) == 0);
  52.     }
  53.    
  54.    
  55.     /**
  56.      * Should generate num boolean values using longFor.
  57.      *
  58.      * @param x
  59.      * @param y
  60.      * @param z
  61.      * @param t a fake iteration
  62.      * @param num
  63.      * @return
  64.      */
  65.     public boolean[] booleansFor(int x, int y, int z, int t, int num) {
  66.         boolean[] out = new boolean[num];
  67.         long nextSeed = intFor(x, y, z, t);
  68.         for(int i = 0; i < num; i++) {
  69.             out[i] = booleanFromSeed(nextSeed, x, y, z, t);
  70.             nextSeed = longFromSeed(nextSeed, x, y, z, t);
  71.         }
  72.         return out;
  73.     }
  74.    
  75.    
  76.     /**
  77.      * Generate a float from a given seed and coords.
  78.      *
  79.      * @param x
  80.      * @param y
  81.      * @param z
  82.      * @param t a fake iteration
  83.      * @return
  84.      */
  85.     public float floatFor(int x, int y, int z, int t) {
  86.         return Math.abs(((float)(longFromSeed(seed, x, y, z, t))) /
  87.                ((float)Long.MAX_VALUE));
  88.     }
  89.    
  90.    
  91.     /**
  92.      * should generate num float values using longFor.
  93.      *
  94.      * @param x
  95.      * @param y
  96.      * @param z
  97.      * @param t a fake iteration
  98.      * @param num
  99.      * @return
  100.      */
  101.     public float[] floatsFor(int x, int y, int z, int t, int num) {
  102.         float[] out = new float[num];
  103.         long nextSeed = intFromSeed(seed, x, y, z, t);
  104.         for(int i = 0; i < num; i++) {
  105.             out[i] = floatFromSeed(nextSeed, x, y, z, t);
  106.             nextSeed = longFromSeed(nextSeed, x, y, z, t);
  107.         }
  108.         return out;
  109.     }
  110.    
  111.    
  112.     /**
  113.      * Generate a double from a given seed and coords.
  114.      *
  115.      * @param x
  116.      * @param y
  117.      * @param z
  118.      * @param t a fake iteration
  119.      * @return
  120.      */
  121.     public double doubleFor(int x, int y, int z, int t) {
  122.         return Math.abs(((double)(longFromSeed(seed, x, y, z, t))) /
  123.                ((double)Long.MAX_VALUE));
  124.     }
  125.    
  126.    
  127.     /**
  128.      * should generate num double values using longFor.
  129.      *
  130.      * @param x
  131.      * @param y
  132.      * @param z
  133.      * @param t a fake iteration
  134.      * @param num
  135.      * @return
  136.      */
  137.     public double[] doublesFor(int x, int y, int z, int t, int num) {
  138.         double[] out = new double[num];
  139.         long nextSeed = longFromSeed(seed, x, y, z, t);
  140.         for(int i = 0; i < num; i++) {
  141.             out[i] = doubleFromSeed(nextSeed, x, y, z, t);
  142.             nextSeed = longFromSeed(nextSeed, x, y, z, t);
  143.         }
  144.         return out;
  145.     }
  146.    
  147.    
  148.     /**
  149.      * Should produce a random int from seed at coordinates x, y, t
  150.      *
  151.      * @param seed
  152.      * @param x
  153.      * @param y
  154.      * @param z
  155.      * @param t a fake iteration
  156.      * @return
  157.      */
  158.     public int intFor(int x, int y, int z, int t) {
  159.         return (int) longFromSeed(seed, x, y, z, t);
  160.     }
  161.    
  162.    
  163.     /**
  164.      * should generate num int values using longFor.
  165.      *
  166.      * @param x
  167.      * @param y
  168.      * @param z
  169.      * @param t a fake iteration
  170.      * @param num
  171.      * @return
  172.      */
  173.     public int[] intsFor(int x, int y, int z, int t, int num) {
  174.         int[] out = new int[num];
  175.         out[0] = intFromSeed(seed, x, y, z, t);
  176.         for(int i = 1; i < num; i++) {
  177.             out[i] = intFromSeed(out[i-1], x, y, z, t);
  178.         }
  179.         return out;
  180.     }
  181.    
  182.    
  183.     /**
  184.      * Should produce a random long from seed at coordinates x, y, t
  185.      *
  186.      * @param x
  187.      * @param y
  188.      * @param z
  189.      * @param t a fake iteration
  190.      * @return
  191.      */
  192.     public long longFor(int x, int y, int z, int t) {
  193.         long out = seed + (15485077L * (long)t)
  194.                         + (12338621L * (long)x)
  195.                         + (15485863L * (long)y)
  196.                         + (14416417L * (long)z);
  197.         out ^= lshift(out, (x % 29) + 13);
  198.         out ^= rshift(out, (y % 31) + 7);  
  199.         out ^= lshift(out, (z % 23) + 19);
  200.         out ^= rshift(out, (t % 43) + 11);
  201.         return out;
  202.     }
  203.    
  204.    
  205.     /**
  206.      * should generate num long values using longFor.
  207.      *
  208.      * @param x
  209.      * @param y
  210.      * @param z
  211.      * @param t a fake iteration
  212.      * @param num
  213.      * @return
  214.      */
  215.     public long[] longsFor(int x, int y, int z, int t, int num) {
  216.         long[] out = new long[num];
  217.         out[0] = longFromSeed(seed, x, y, z, t);
  218.         for(int i = 1; i < num; i++) {
  219.             out[i] = longFromSeed(out[i-1], x, y, z, t);
  220.         }
  221.         return out;
  222.     }
  223.    
  224.    
  225.     /*==========================================*
  226.      *  STATIC METHODS TAKING A   SEED DIRECTLY *
  227.      *==========================================*/
  228.    
  229.    
  230.     /**
  231.      * Generate a boolean from a given seed and coords.
  232.      *
  233.      * @param seed
  234.      * @param x
  235.      * @param y
  236.      * @param z
  237.      * @param t a fake iteration
  238.      * @return
  239.      */
  240.     public static boolean booleanFromSeed(long seed, int x, int y, int z, int t) {
  241.         return ((longFromSeed(seed, x, y, z, t) % 2) == 0);
  242.     }
  243.    
  244.    
  245.     /**
  246.      * Generate a float from a given seed and coords.
  247.      *
  248.      * @param seed
  249.      * @param x
  250.      * @param y
  251.      * @param z
  252.      * @param t a fake iteration
  253.      * @return
  254.      */
  255.     public static float floatFromSeed(long seed, int x, int y, int z, int t) {
  256.         return Math.abs(((float)(longFromSeed(seed, x, y, z, t))) /
  257.                ((float)Long.MAX_VALUE));
  258.     }
  259.    
  260.    
  261.     /**
  262.      * Generate a double from a given seed and coords.
  263.      *
  264.      * @param seed
  265.      * @param x
  266.      * @param y
  267.      * @param z
  268.      * @param t a fake iteration
  269.      * @return
  270.      */
  271.     public static double doubleFromSeed(long seed, int x, int y, int z, int t) {
  272.         return Math.abs(((double)(longFromSeed(seed, x, y, z, t))) /
  273.                ((double)Long.MAX_VALUE));
  274.     }
  275.    
  276.    
  277.     /**
  278.      * Should produce a random int from seed at coordinates x, y, t
  279.      *
  280.      * @param seed
  281.      * @param x
  282.      * @param y
  283.      * @param z
  284.      * @param t a fake iteration
  285.      * @return
  286.      */
  287.     public static int intFromSeed(long seed, int x, int y, int z, int t) {
  288.         return (int) longFromSeed(seed, x, y, z, t);
  289.     }
  290.    
  291.    
  292.     /**
  293.      * Should produce a random long from seed at coordinates x, y, t
  294.      *
  295.      * @param seed
  296.      * @param x
  297.      * @param y
  298.      * @param z
  299.      * @param t a fake iteration
  300.      * @return
  301.      */
  302.     public static long longFromSeed(long seed, int x, int y, int z, int t) {
  303.         long out = seed + (15485077L * (long)t)
  304.                         + (12338621L * (long)x)
  305.                         + (15485863L * (long)y)
  306.                         + (14416417L * (long)z);
  307.         out ^= lshift(out, (x % 29) + 13);
  308.         out ^= rshift(out, (y % 31) + 7);  
  309.         out ^= lshift(out, (z % 23) + 19);
  310.         out ^= rshift(out, (t % 43) + 11);
  311.         return out;
  312.     }
  313.    
  314.    
  315.     /*=============================*
  316.      *  INTERNAL UNTILITY METHODS  *
  317.      ==============================*/
  318.    
  319.    
  320.     /**
  321.      * Performs left bit shift (<<) with wrap-around.
  322.      *
  323.      * @param in
  324.      * @param dist
  325.      * @return
  326.      */
  327.     private static long lshift(long in, long dist) {
  328.         long out = in << dist;
  329.         out += (in >>> (64 - dist));    
  330.         return out;
  331.     }
  332.    
  333.    
  334.     /**
  335.      * Performs right bit shift (>>) with wrap-around.
  336.      *
  337.      * @param in
  338.      * @param dist
  339.      * @return
  340.      */
  341.     private static long rshift(long in, long dist) {
  342.         long out = in >>> dist;
  343.         out += (in << (64 - dist));    
  344.         return out;
  345.     }
  346. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement