Advertisement
Guest User

Grimoire Random

a guest
Sep 15th, 2017
966
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 17.40 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using GrimoireEngine.Framework.Logic;
  4. using GrimoireEngine.Framework.Maths;
  5. using OpenTK;
  6.  
  7. namespace GrimoireEngine.Framework.Utilities
  8. {
  9.     public sealed class GrimoireRandom
  10.     {
  11.         private int _seed;
  12.         private int _inext;
  13.         private int _inextp;
  14.         private int[] _seedArray = new int[56];
  15.  
  16.         /// <summary>
  17.         /// The current seed of this instance.
  18.         /// </summary>
  19.         public int Seed
  20.         {
  21.             get
  22.             {
  23.                 return _seed;
  24.             }
  25.             set
  26.             {
  27.                 _seed = value;
  28.                 int subtraction = (_seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(_seed);
  29.                 int mj = 0x9a4ec86 - subtraction;
  30.                 _seedArray[0x37] = mj;
  31.                 int mk = 1;
  32.                 for (int i = 1; i < 0x37; i++)
  33.                 {
  34.                     int ii = (0x15 * i) % 0x37;
  35.                     _seedArray[ii] = mk;
  36.                     mk = mj - mk;
  37.                     if (mk < 0x0)
  38.                     {
  39.                         mk += Int32.MaxValue;
  40.                     }
  41.                     mj = _seedArray[ii];
  42.                 }
  43.                 for (int k = 1; k < 0x5; k++)
  44.                 {
  45.                     for (int i = 1; i < 0x38; i++)
  46.                     {
  47.                         _seedArray[i] -= _seedArray[1 + (i + 0x1e) % 0x37];
  48.                         if (_seedArray[i] < 0)
  49.                         {
  50.                             _seedArray[i] += Int32.MaxValue;
  51.                         }
  52.                     }
  53.                 }
  54.                 _inext = 0;
  55.                 _inextp = 21;
  56.             }
  57.         }
  58.  
  59.         public GrimoireRandom()
  60.             // Used to generate a varying seed, regardless of close-frequency allocation
  61.             : this(Guid.NewGuid().GetHashCode())
  62.         { }
  63.  
  64.         public GrimoireRandom(string seed)
  65.             : this(seed.GetHashCode())
  66.         { }
  67.  
  68.         public GrimoireRandom(int[] saveState)
  69.         {
  70.             LoadState(saveState);
  71.         }
  72.  
  73.         public GrimoireRandom(int seed)
  74.         {
  75.             Seed = seed;
  76.         }
  77.  
  78.         /// <summary>
  79.         /// Resets this instance using it's current seed.
  80.         /// This means that the RNG will start over again,
  81.         /// repeating the same values that it originally had.
  82.         /// </summary>
  83.         public void Reset()
  84.         {
  85.             Reseed(this.Seed);
  86.         }
  87.  
  88.         /// <summary>
  89.         /// Reseeds this instance using a new GUID Hashcode
  90.         /// </summary>
  91.         public void Reseed()
  92.         {
  93.             Reseed(Guid.NewGuid().GetHashCode());
  94.         }
  95.  
  96.         /// <summary>
  97.         /// Reseeds this instance using the hashcode of a given string.
  98.         /// </summary>
  99.         /// <param name="seed"></param>
  100.         public void Reseed(string seed)
  101.         {
  102.             Reseed(seed.GetHashCode());
  103.         }
  104.  
  105.         /// <summary>
  106.         /// Reseeds this instance using a given integer seed.
  107.         /// </summary>
  108.         /// <param name="seed"></param>
  109.         public void Reseed(int seed)
  110.         {
  111.             this.Seed = seed;
  112.         }
  113.  
  114.         public int NextInteger()
  115.         {
  116.             return NextSample();
  117.         }
  118.  
  119.         public void NextIntegers(int[] buffer)
  120.         {
  121.             for (int i = 0; i < buffer.Length; i++)
  122.             {
  123.                 buffer[i] = NextInteger();
  124.             }
  125.         }
  126.  
  127.         public int[] NextIntegers(int quantity)
  128.         {
  129.             int[] buffer = new int[quantity];
  130.             NextIntegers(buffer);
  131.             return buffer;
  132.         }
  133.  
  134.  
  135.         public int NextInteger(int minValue, int maxValue)
  136.         {
  137.             return (int)(this.NextSample() * (1.0D / Int32.MaxValue) * (maxValue - minValue)) + minValue;
  138.         }
  139.  
  140.  
  141.         public void NextIntegers(int minValue, int maxValue, int[] buffer)
  142.         {
  143.             for (int i = 0; i < buffer.Length; i++)
  144.             {
  145.                 buffer[i] = NextInteger(minValue, maxValue);
  146.             }
  147.         }
  148.  
  149.  
  150.         public int[] NextIntegers(int minValue, int maxValue, int quantity)
  151.         {
  152.             int[] buffer = new int[quantity];
  153.             NextIntegers(minValue, maxValue, buffer);
  154.             return buffer;
  155.         }
  156.  
  157.         public int NextInteger(int maxValue)
  158.         {
  159.             return NextInteger(0, maxValue);
  160.         }
  161.  
  162.         public void NextIntegers(int maxValue, int[] buffer)
  163.         {
  164.             for (int i = 0; i < buffer.Length; i++)
  165.             {
  166.                 buffer[i] = NextInteger(maxValue);
  167.             }
  168.         }
  169.  
  170.         public int[] NextIntegers(int maxValue, int quantity)
  171.         {
  172.             int[] buffer = new int[quantity];
  173.             NextIntegers(maxValue, buffer);
  174.             return buffer;
  175.         }
  176.  
  177.         public double NextDouble()
  178.         {
  179.             return NextSample() * (1.0D / Int32.MaxValue);
  180.         }
  181.  
  182.         public void NextDoubles(double[] buffer)
  183.         {
  184.             for (int i = 0; i < buffer.Length; i++)
  185.             {
  186.                 buffer[i] = NextDouble();
  187.             }
  188.         }
  189.  
  190.         public double[] NextDoubles(int quantity)
  191.         {
  192.             double[] buffer = new double[quantity];
  193.             NextDoubles(buffer);
  194.             return buffer;
  195.         }
  196.  
  197.         public double NextDouble(double minValue, double maxValue)
  198.         {
  199.             return NextDouble() * (maxValue - minValue) + minValue;
  200.         }
  201.  
  202.         public void NextDoubles(double minValue, double maxValue, double[] buffer)
  203.         {
  204.             for (int i = 0; i < buffer.Length; i++)
  205.             {
  206.                 buffer[i] = NextDouble(minValue, maxValue);
  207.             }
  208.         }
  209.  
  210.         public double[] NextDoubles(double minValue, double maxValue, int quantity)
  211.         {
  212.             double[] buffer = new double[quantity];
  213.             NextDoubles(minValue, maxValue, buffer);
  214.             return buffer;
  215.         }
  216.  
  217.         public float NextFloat()
  218.         {
  219.             return (float)(NextSample() * (1.0D / Int32.MaxValue));
  220.         }
  221.  
  222.         public void NextFloats(float[] buffer)
  223.         {
  224.             for (int i = 0; i < buffer.Length; i++)
  225.             {
  226.                 buffer[i] = NextFloat();
  227.             }
  228.         }
  229.  
  230.         public float[] NextFloats(int quantity)
  231.         {
  232.             float[] buffer = new float[quantity];
  233.             NextFloats(buffer);
  234.             return buffer;
  235.         }
  236.  
  237.         public float NextFloat(float minValue, float maxValue)
  238.         {
  239.             return NextFloat() * (maxValue - minValue) + minValue;
  240.         }
  241.  
  242.         public void NextFloats(float minValue, float maxValue, float[] buffer)
  243.         {
  244.             for (int i = 0; i < buffer.Length; i++)
  245.             {
  246.                 buffer[i] = NextFloat(minValue, maxValue);
  247.             }
  248.         }
  249.  
  250.         public float[] NextFloats(float minValue, float maxValue, int quantity)
  251.         {
  252.             float[] buffer = new float[quantity];
  253.             NextFloats(minValue, maxValue, buffer);
  254.             return buffer;
  255.         }
  256.  
  257.         public int NextRange(Range range)
  258.         {
  259.             return NextInteger(range.Minimum, range.Maximum + 1);
  260.         }
  261.  
  262.         public void NextRanges(Range range, int[] buffer)
  263.         {
  264.             for (int i = 0; i < buffer.Length; i++)
  265.             {
  266.                 buffer[i] = NextRange(range);
  267.             }
  268.         }
  269.  
  270.         public int[] NextRanges(Range range, int quantity)
  271.         {
  272.             int[] buffer = new int[quantity];
  273.             NextRanges(range, buffer);
  274.             return buffer;
  275.         }
  276.  
  277.         public int NextRange(int minValue, int maxValue)
  278.         {
  279.             return NextInteger(minValue, maxValue + 1);
  280.         }
  281.  
  282.         public void NextRanges(int minValue, int maxValue, int[] buffer)
  283.         {
  284.             for (int i = 0; i < buffer.Length; i++)
  285.             {
  286.                 buffer[i] = NextRange(minValue, maxValue);
  287.             }
  288.         }
  289.  
  290.         public int[] NextRanges(int minValue, int maxValue, int quantity)
  291.         {
  292.             int[] buffer = new int[quantity];
  293.             NextRanges(minValue, maxValue, buffer);
  294.             return buffer;
  295.         }
  296.  
  297.         public byte NextByte()
  298.         {
  299.             return (byte)NextInteger(0, 256);
  300.         }
  301.  
  302.         public void NextBytes(byte[] buffer)
  303.         {
  304.             for (int i = 0; i < buffer.Length; i++)
  305.             {
  306.                 buffer[i] = NextByte();
  307.             }
  308.         }
  309.  
  310.         public byte[] NextBytes(int quantity)
  311.         {
  312.             byte[] buffer = new byte[quantity];
  313.             NextBytes(buffer);
  314.             return buffer;
  315.         }
  316.  
  317.         public byte NextByte(byte minValue, byte maxValue)
  318.         {
  319.             return (byte)NextInteger(minValue, maxValue);
  320.         }
  321.  
  322.         public void NextBytes(byte minValue, byte maxValue, byte[] buffer)
  323.         {
  324.             for (int i = 0; i < buffer.Length; i++)
  325.             {
  326.                 buffer[i] = NextByte(minValue, maxValue);
  327.             }
  328.         }
  329.  
  330.         public byte[] NextBytes(byte minValue, byte maxValue, int quantity)
  331.         {
  332.             byte[] buffer = new byte[quantity];
  333.             NextBytes(minValue, maxValue, buffer);
  334.             return buffer;
  335.         }
  336.  
  337.         public byte NextByte(byte maxValue)
  338.         {
  339.             return (byte)NextInteger(0, maxValue);
  340.         }
  341.  
  342.         public void NextBytes(byte maxValue, byte[] buffer)
  343.         {
  344.             for (int i = 0; i < buffer.Length; i++)
  345.             {
  346.                 buffer[i] = NextByte(maxValue);
  347.             }
  348.         }
  349.  
  350.         public byte[] NextBytes(byte maxValue, int quantity)
  351.         {
  352.             byte[] buffer = new byte[quantity];
  353.             NextBytes(maxValue, buffer);
  354.             return buffer;
  355.         }
  356.  
  357.         public bool NextBool()
  358.         {
  359.             return NextInteger(0, 2) == 1;
  360.         }
  361.  
  362.         public void NextBools(bool[] buffer)
  363.         {
  364.             for (int i = 0; i < buffer.Length; i++)
  365.             {
  366.                 buffer[i] = NextBool();
  367.             }
  368.         }
  369.  
  370.         public bool[] NextBools(int quantity)
  371.         {
  372.             bool[] buffer = new bool[quantity];
  373.             NextBools(buffer);
  374.             return buffer;
  375.         }
  376.  
  377.         public string NextString(char[] possibleCharacters, int length)
  378.         {
  379.             char[] buffer = new char[length];
  380.             for (int i = 0; i < buffer.Length; i++)
  381.             {
  382.                 buffer[i] = possibleCharacters[NextInteger(0, possibleCharacters.Length)];
  383.             }
  384.             return new string(buffer);
  385.         }
  386.  
  387.         public void NextStrings(char[] possibleCharacters, int length, string[] buffer)
  388.         {
  389.             for (int i = 0; i < buffer.Length; i++)
  390.             {
  391.                 buffer[i] = NextString(possibleCharacters, length);
  392.             }
  393.         }
  394.  
  395.         public string[] NextStrings(char[] possibleCharacters, int length, int quantity)
  396.         {
  397.             string[] buffer = new string[quantity];
  398.             NextStrings(possibleCharacters, length, buffer);
  399.             return buffer;
  400.         }
  401.  
  402.         public void Shuffle<T>(List<T> list)
  403.         {
  404.             int n = list.Count;
  405.             while (n > 1)
  406.             {
  407.                 n--;
  408.                 int k = NextInteger(0, n + 1);
  409.                 T value = list[k];
  410.                 list[k] = list[n];
  411.                 list[n] = value;
  412.             }
  413.         }
  414.  
  415.         public void Shuffle<T>(T[] list)
  416.         {
  417.             int n = list.Length;
  418.             while (n > 1)
  419.             {
  420.                 n--;
  421.                 int k = NextInteger(0, n + 1);
  422.                 T value = list[k];
  423.                 list[k] = list[n];
  424.                 list[n] = value;
  425.             }
  426.         }
  427.  
  428.         public int NextIndex<T>(T[] array)
  429.         {
  430.             return NextInteger(array.Length);
  431.         }
  432.  
  433.         public int NextIndex<T>(List<T> list)
  434.         {
  435.             return NextInteger(list.Count);
  436.         }
  437.  
  438.         public T Choose<T>(T[] items)
  439.         {
  440.             return items[NextInteger(items.Length)];
  441.         }
  442.  
  443.         public void Choose<T>(T[] items, T[] resultBuffer)
  444.         {
  445.             for (int i = 0; i < resultBuffer.Length; i++)
  446.             {
  447.                 resultBuffer[i] = Choose(items);
  448.             }
  449.         }
  450.  
  451.         public T[] Choose<T>(T[] items, int quantity)
  452.         {
  453.             T[] buffer = new T[quantity];
  454.             Choose(items, buffer);
  455.             return buffer;
  456.         }
  457.  
  458.         public T Choose<T>(List<T> items)
  459.         {
  460.             return items[NextInteger(0, items.Count)];
  461.         }
  462.  
  463.         public List<T> Choose<T>(List<T> items, int quantity)
  464.         {
  465.             List<T> buffer = new List<T>(quantity);
  466.             for (int i = 0; i < quantity; i++)
  467.             {
  468.                 buffer.Add(Choose(items));
  469.             }
  470.             return buffer;
  471.         }
  472.  
  473.         public bool NextProbability(float percent)
  474.         {
  475.             if (percent >= 1.0f) return true;
  476.             if (percent <= 0.0f) return false;
  477.             return NextDouble() <= percent;
  478.         }
  479.  
  480.         public void NextProbability(float percent, bool[] buffer)
  481.         {
  482.             for (int i = 0; i < buffer.Length; i++)
  483.             {
  484.                 buffer[i] = NextProbability(percent);
  485.             }
  486.         }
  487.  
  488.         public bool[] NextProbabilities(float percent, int quantity)
  489.         {
  490.             bool[] buffer = new bool[quantity];
  491.             NextProbability(percent, buffer);
  492.             return buffer;
  493.         }
  494.  
  495.         public bool NextProbability(int percent)
  496.         {
  497.             if (percent >= 100) return true;
  498.             if (percent <= 0) return false;
  499.             return NextInteger(101) <= percent;
  500.         }
  501.  
  502.         public void NextProbabilities(int percent, bool[] buffer)
  503.         {
  504.             for (int i = 0; i < buffer.Length; i++)
  505.             {
  506.                 buffer[i] = NextProbability(percent);
  507.             }
  508.         }
  509.  
  510.         public bool[] NextProbabilities(int percent, int quantity)
  511.         {
  512.             bool[] buffer = new bool[quantity];
  513.             NextProbabilities(percent, buffer);
  514.             return buffer;
  515.         }
  516.  
  517.         public bool NextOdds(int a, int b)
  518.         {
  519.             return NextProbability(((float)a / b));
  520.         }
  521.  
  522.         public void NextOdds(int a, int b, bool[] buffer)
  523.         {
  524.             for (int i = 0; i < buffer.Length; i++)
  525.             {
  526.                 buffer[i] = NextOdds(a, b);
  527.             }
  528.         }
  529.  
  530.         public bool[] NextOdds(int a, int b, int quantity)
  531.         {
  532.             bool[] buffer = new bool[quantity];
  533.             NextOdds(a, b, buffer);
  534.             return buffer;
  535.         }
  536.         public int NextDiceRoll(DiceType d)
  537.         {
  538.             return NextInteger(1, (int)d + 1);
  539.         }
  540.  
  541.         public void NextDiceRolls(DiceType d, int[] buffer)
  542.         {
  543.             for (int i = 0; i < buffer.Length; i++)
  544.             {
  545.                 buffer[i] = NextDiceRoll(d);
  546.             }
  547.         }
  548.  
  549.         public int[] NextDiceRolls(DiceType d, int quantity)
  550.         {
  551.             int[] buffer = new int[quantity];
  552.             NextDiceRolls(d, buffer);
  553.             return buffer;
  554.         }
  555.  
  556.         public Vector3 NextVector3(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax)
  557.         {
  558.             return new Vector3(NextFloat(xMin, xMax), NextFloat(yMin, yMax), NextFloat(zMin, zMax));
  559.         }
  560.  
  561.         public Vector3 NextVector3(Vector3 min, Vector3 max)
  562.         {
  563.             return NextVector3(min.X, max.X, min.Y, max.Y, min.Z, max.Z);
  564.         }
  565.  
  566.         public Vector3 NextVector3(float min, float max)
  567.         {
  568.             return NextVector3(min, max, min, max, min, max);
  569.         }
  570.  
  571.         private int NextSample()
  572.         {
  573.             int locINext = _inext;
  574.             int locINextp = _inextp;
  575.             if (++locINext >= 56)
  576.             {
  577.                 locINext = 1;
  578.             }
  579.             if (++locINextp >= 56)
  580.             {
  581.                 locINextp = 1;
  582.             }
  583.             int retVal = _seedArray[locINext] - _seedArray[locINextp];
  584.             if (retVal == Int32.MaxValue)
  585.             {
  586.                 retVal--;
  587.             }
  588.             if (retVal < 0)
  589.             {
  590.                 retVal += Int32.MaxValue;
  591.             }
  592.             _seedArray[locINext] = retVal;
  593.             _inext = locINext;
  594.             _inextp = locINextp;
  595.             return retVal;
  596.         }
  597.  
  598.         public int[] GetState()
  599.         {
  600.             int[] state = new int[59];
  601.             state[0] = _seed;
  602.             state[1] = _inext;
  603.             state[2] = _inextp;
  604.             for (int i = 3; i < this._seedArray.Length; i++)
  605.             {
  606.                 state[i] = _seedArray[i - 3];
  607.             }
  608.             return state;
  609.         }
  610.  
  611.         public void LoadState(int[] saveState)
  612.         {
  613.             if (saveState.Length != 59)
  614.             {
  615.                 throw new Exception("GrimoireRandom state was corrupted!");
  616.             }
  617.             _seed = saveState[0];
  618.             _inext = saveState[1];
  619.             _inextp = saveState[2];
  620.             _seedArray = new int[59];
  621.             for (int i = 3; i < this._seedArray.Length; i++)
  622.             {
  623.                 _seedArray[i - 3] = saveState[i];
  624.             }
  625.         }
  626.     }
  627. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement