Advertisement
Krythic

GrimoireRandom

Jun 24th, 2016
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 17.95 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using GrimoireTactics.Framework.Maths;
  8. using OpenTK.Graphics;
  9.  
  10. namespace GrimoireTactics.Framework.Probability
  11. {
  12.     /*
  13.      * Someone needs to generate documentation for this.
  14.      */
  15.     public sealed class GrimoireRandom
  16.     {
  17.         //
  18.         // Private Constants
  19.         //
  20.         private int _inext;
  21.         private int _inextp;
  22.         private int[] _seedArray = new int[56];
  23.         private int _seed;
  24.  
  25.         public int Seed
  26.         {
  27.             get
  28.             {
  29.                 return _seed;
  30.             }
  31.             set
  32.             {
  33.                 _seed = value;
  34.                 int subtraction = (_seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(_seed);
  35.                 int mj = 161803398 - subtraction;
  36.                 _seedArray[55] = mj;
  37.                 int mk = 1;
  38.                 for (int i = 1; i < 55; i++)
  39.                 {
  40.                     int ii = (21 * i) % 55;
  41.                     _seedArray[ii] = mk;
  42.                     mk = mj - mk;
  43.                     if (mk < 0)
  44.                     {
  45.                         mk += Int32.MaxValue;
  46.                     }
  47.                     mj = _seedArray[ii];
  48.                 }
  49.                 for (int k = 1; k < 5; k++)
  50.                 {
  51.                     for (int i = 1; i < 56; i++)
  52.                     {
  53.                         _seedArray[i] -= _seedArray[1 + (i + 30) % 55];
  54.                         if (_seedArray[i] < 0)
  55.                         {
  56.                             _seedArray[i] += Int32.MaxValue;
  57.                         }
  58.                     }
  59.                 }
  60.                 _inext = 0;
  61.                 _inextp = 21;
  62.             }
  63.         }
  64.  
  65.         public GrimoireRandom()
  66.           : this(Environment.TickCount)
  67.         {
  68.         }
  69.  
  70.         public GrimoireRandom(int seed)
  71.         {
  72.             Seed = seed;
  73.         }
  74.  
  75.         #region Random Integer
  76.  
  77.         /// <summary>
  78.         /// Nexts this instance.
  79.         /// </summary>
  80.         /// <returns></returns>
  81.         public int GenerateInteger()
  82.         {
  83.             return InternalSample();
  84.         }
  85.  
  86.         /// <summary>
  87.         /// Nexts the specified maximum value.
  88.         /// </summary>
  89.         /// <param name="maxValue">The maximum value.</param>
  90.         /// <returns></returns>
  91.         /// <exception cref="ArgumentOutOfRangeException">Input must be greater than zero.</exception>
  92.         public int GenerateInteger(int maxValue)
  93.         {
  94.             return (int) (Sample()*maxValue);
  95.         }
  96.  
  97.         /// <summary>
  98.         /// Nexts the specified minimum value.
  99.         /// </summary>
  100.         /// <param name="minValue">The minimum value.</param>
  101.         /// <param name="maxValue">The maximum value.</param>
  102.         /// <returns></returns>
  103.         /// <exception cref="ArgumentOutOfRangeException">Input must be greater than zero.</exception>
  104.         public int GenerateInteger(int minValue, int maxValue)
  105.         {
  106.             long range = (long) maxValue - minValue;
  107.             if (range <= Int32.MaxValue)
  108.             {
  109.                 return (int) (Sample()*range) + minValue;
  110.             }
  111.             int result = InternalSample();
  112.             bool negative = (InternalSample()%2 == 0);
  113.             if (negative)
  114.             {
  115.                 result = -result;
  116.             }
  117.             double d = result;
  118.             d += (Int32.MaxValue - 1);
  119.             d /= 2*(uint) Int32.MaxValue - 1;
  120.             return (int) ((long) (d*range) + minValue);
  121.         }
  122.  
  123.         public int GenerateInteger(Range<int> range)
  124.         {
  125.             return GenerateInteger(range.Minimum,range.Maximum);
  126.         }
  127.  
  128.         public void GenerateIntegers(int[] buffer)
  129.         {
  130.             for (int i = 0; i < buffer.Length; i++)
  131.             {
  132.                 buffer[i] = GenerateInteger();
  133.             }
  134.         }
  135.  
  136.         public int[] GenerateIntegers(int count)
  137.         {
  138.             int[] buffer = new int[count];
  139.             GenerateIntegers(buffer);
  140.             return buffer;
  141.         }
  142.  
  143.         public void GenerateIntegers(int[] buffer, int maxValue)
  144.         {
  145.             for (int i = 0; i < buffer.Length; i++)
  146.             {
  147.                 buffer[i] = GenerateInteger(0,maxValue);
  148.             }
  149.         }
  150.  
  151.         public int[] GenerateIntegers(int count, int maxValue)
  152.         {
  153.             int[] buffer = new int[count];
  154.             GenerateIntegers(buffer, maxValue);
  155.             return buffer;
  156.         }
  157.  
  158.         public void GenerateIntegers(int[] buffer, int minValue, int maxValue)
  159.         {
  160.             for (int i = 0; i < buffer.Length; i++)
  161.             {
  162.                 buffer[i] = GenerateInteger(minValue,maxValue);
  163.             }
  164.         }
  165.  
  166.         public int[] GenerateIntegers(int count, int minValue, int maxValue)
  167.         {
  168.             int[] buffer = new int[count];
  169.             GenerateIntegers(buffer,minValue,maxValue);
  170.             return buffer;
  171.         }
  172.  
  173.         public void GenerateIntegers(int[] buffer, Range<int> range )
  174.         {
  175.             for (int i = 0; i < buffer.Length; i++)
  176.             {
  177.                 buffer[i] = GenerateInteger(range.Minimum, range.Maximum);
  178.             }
  179.         }
  180.  
  181.         public int[] GenerateIntegers(int count, Range<int> range )
  182.         {
  183.             int[] buffer = new int[count];
  184.             GenerateIntegers(buffer, range);
  185.             return buffer;
  186.         }
  187.  
  188.         #endregion
  189.  
  190.         #region Random Double
  191.  
  192.         /// <summary>
  193.         /// Nexts the double.
  194.         /// </summary>
  195.         /// <returns></returns>
  196.         public double GenerateDouble()
  197.         {
  198.             return Sample();
  199.         }
  200.  
  201.         public double GenerateDouble(double minValue, double maxValue)
  202.         {
  203.             return GenerateDouble() * (maxValue - minValue) + minValue;
  204.         }
  205.  
  206.         public double GenerateDouble(Range<double> range)
  207.         {
  208.             return GenerateDouble(range.Minimum, range.Maximum);
  209.         }
  210.  
  211.         public void GenerateDoubles(double[] buffer)
  212.         {
  213.             for (int i = 0; i < buffer.Length; i++)
  214.             {
  215.                 buffer[i] = GenerateDouble();
  216.             }
  217.         }
  218.  
  219.         public double[] GenerateDoubles(int count)
  220.         {
  221.             double[] buffer = new double[count];
  222.             GenerateDoubles(buffer);
  223.             return buffer;
  224.         }
  225.  
  226.  
  227.         //
  228.         public void GenerateDoubles(double[] buffer, double minValue, double maxValue)
  229.         {
  230.             for (int i = 0; i < buffer.Length; i++)
  231.             {
  232.                 buffer[i] = GenerateDouble(minValue,maxValue);
  233.             }
  234.         }
  235.  
  236.         public double[] GenerateDoubles(int count, double minValue, double maxValue)
  237.         {
  238.             double[] buffer = new double[count];
  239.             GenerateDoubles(buffer,minValue,maxValue);
  240.             return buffer;
  241.         }
  242.  
  243.         //
  244.         public void GenerateDoubles(double[] buffer, Range<double> range )
  245.         {
  246.             for (int i = 0; i < buffer.Length; i++)
  247.             {
  248.                 buffer[i] = GenerateDouble(range);
  249.             }
  250.         }
  251.  
  252.         public double[] GenerateDoubles(int count, Range<double> range )
  253.         {
  254.             double[] buffer = new double[count];
  255.             GenerateDoubles(buffer, range);
  256.             return buffer;
  257.         }
  258.  
  259.         #endregion
  260.  
  261.         #region Random Byte
  262.  
  263.         public byte GenerateByte()
  264.         {
  265.             return (byte) GenerateInteger(0, 256);
  266.         }
  267.  
  268.         public byte GenerateByte(byte maxValue)
  269.         {
  270.             return (byte) GenerateInteger(0, maxValue);
  271.         }
  272.  
  273.         public byte GenerateByte(byte minValue, byte maxValue)
  274.         {
  275.             return (byte)GenerateInteger(minValue, maxValue);
  276.         }
  277.  
  278.         /// <summary>
  279.         /// Nexts the bytes.
  280.         /// </summary>
  281.         /// <param name="buffer">The buffer.</param>
  282.         /// <exception cref="ArgumentNullException"></exception>
  283.         public void GenerateBytes(byte[] buffer)
  284.         {
  285.             if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  286.             for (int i = 0; i < buffer.Length; i++)
  287.             {
  288.                 buffer[i] = GenerateByte();
  289.             }
  290.         }
  291.  
  292.         /// <summary>
  293.         /// Allocates an array with random Boolean values.
  294.         /// </summary>
  295.         /// <param name="count">The count.</param>
  296.         /// <returns></returns>
  297.         public byte[] GenerateBytes(int count)
  298.         {
  299.             byte[] buffer = new byte[count];
  300.             GenerateBytes(buffer);
  301.             return buffer;
  302.         }
  303.  
  304.         /// <summary>
  305.         /// Nexts the bytes.
  306.         /// </summary>
  307.         /// <param name="buffer">The buffer.</param>
  308.         /// <param name="maxValue"></param>
  309.         /// <exception cref="ArgumentNullException"></exception>
  310.         public void GenerateBytes(byte[] buffer, byte maxValue)
  311.         {
  312.             if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  313.             for (int i = 0; i < buffer.Length; i++)
  314.             {
  315.                 buffer[i] = GenerateByte( 0, maxValue);
  316.             }
  317.         }
  318.  
  319.         /// <summary>
  320.         /// Allocates an array with random Boolean values.
  321.         /// </summary>
  322.         /// <param name="count">The count.</param>
  323.         /// <param name="maxValue"></param>
  324.         /// <returns></returns>
  325.         public byte[] GenerateBytes(int count, byte maxValue)
  326.         {
  327.             byte[] buffer = new byte[count];
  328.             GenerateBytes(buffer, maxValue);
  329.             return buffer;
  330.         }
  331.  
  332.         /// <summary>
  333.         /// Nexts the bytes.
  334.         /// </summary>
  335.         /// <param name="buffer">The buffer.</param>
  336.         /// <param name="minValue"></param>
  337.         /// <param name="maxValue"></param>
  338.         /// <exception cref="ArgumentNullException"></exception>
  339.         public void GenerateBytes(byte[] buffer,byte minValue, byte maxValue)
  340.         {
  341.             if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  342.             for (int i = 0; i < buffer.Length; i++)
  343.             {
  344.                 buffer[i] = GenerateByte(minValue, maxValue);
  345.             }
  346.         }
  347.  
  348.         /// <summary>
  349.         /// Allocates an array with random Boolean values.
  350.         /// </summary>
  351.         /// <param name="count">The count.</param>
  352.         /// <param name="minValue"></param>
  353.         /// <param name="maxValue"></param>
  354.         /// <returns></returns>
  355.         public byte[] GenerateBytes(int count,byte minValue, byte maxValue)
  356.         {
  357.             byte[] buffer = new byte[count];
  358.             GenerateBytes(buffer, minValue, maxValue);
  359.             return buffer;
  360.         }
  361.  
  362.         /// <summary>
  363.         /// Nexts the bytes.
  364.         /// </summary>
  365.         /// <param name="buffer">The buffer.</param>
  366.         /// <param name="range"></param>
  367.         /// <exception cref="ArgumentNullException"></exception>
  368.         public void GenerateBytes(byte[] buffer, Range<byte> range )
  369.         {
  370.             if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  371.             for (int i = 0; i < buffer.Length; i++)
  372.             {
  373.                 buffer[i] = GenerateByte(range.Minimum, range.Maximum);
  374.             }
  375.         }
  376.  
  377.         /// <summary>
  378.         /// Allocates an array with random Boolean values.
  379.         /// </summary>
  380.         /// <param name="count">The count.</param>
  381.         /// <param name="range"></param>
  382.         /// <returns></returns>
  383.         public byte[] GenerateBytes(int count, Range<byte> range)
  384.         {
  385.             byte[] buffer = new byte[count];
  386.             GenerateBytes(buffer,range);
  387.             return buffer;
  388.         }
  389.  
  390.         #endregion
  391.  
  392.         #region Random Bool
  393.  
  394.         /// <summary>
  395.         /// Generates a Random Boolean value.
  396.         /// </summary>
  397.         /// <returns></returns>
  398.         public bool GenerateBool()
  399.         {
  400.             return GenerateInteger(2) == 1;
  401.         }
  402.  
  403.         /// <summary>
  404.         /// Allocates an array with random Boolean values.
  405.         /// </summary>
  406.         /// <param name="buffer">The buffer.</param>
  407.         /// <exception cref="ArgumentNullException"></exception>
  408.         public void GenerateBools(bool[] buffer)
  409.         {
  410.             for (int i = 0; i < buffer.Length; i++)
  411.             {
  412.                 buffer[i] = GenerateBool();
  413.             }
  414.         }
  415.  
  416.         /// <summary>
  417.         /// Allocates an array with random Boolean values.
  418.         /// </summary>
  419.         /// <param name="count">The count.</param>
  420.         /// <returns></returns>
  421.         public bool[] GenerateBools(int count)
  422.         {
  423.             bool[] buffer = new bool[count];
  424.             GenerateBools(buffer);
  425.             return buffer;
  426.         }
  427.  
  428.         #endregion
  429.  
  430.         #region Random String
  431.  
  432.         public string GenerateString(char[] possibleCharacters, int length)
  433.         {
  434.             char[] buffer = new char[length];
  435.             for (int i = 0; i < buffer.Length; i++)
  436.             {
  437.                 buffer[i] = possibleCharacters[GenerateInteger(possibleCharacters.Length)];
  438.             }
  439.             return new string(buffer);
  440.         }
  441.  
  442.         public string[] GenerateStrings(char[] possibleCharacters, int length, int count)
  443.         {
  444.             string[] buffer = new string[count];
  445.             for (int i = 0; i < buffer.Length; i++)
  446.             {
  447.                 buffer[i] = GenerateString(possibleCharacters, length);
  448.             }
  449.             return buffer;
  450.         }
  451.  
  452.         #endregion
  453.  
  454.         #region Random Color
  455.  
  456.         public Color GenerateColor()
  457.         {
  458.             int red = GenerateInteger(0, 256);
  459.             int green = GenerateInteger(0, 256);
  460.             int blue = GenerateInteger(0, 256);
  461.             return Color.FromArgb(255, red, green, blue);
  462.         }
  463.  
  464.         public Color[] GenerateColors(int quantity)
  465.         {
  466.             Color[] buffer = new Color[quantity];
  467.             for (int i = 0; i < buffer.Length; i++)
  468.             {
  469.                 buffer[i] = GenerateColor();
  470.             }
  471.             return buffer;
  472.         }
  473.  
  474.         public Color4 GenerateOpenGLColor()
  475.         {
  476.             return GenerateColor();
  477.         }
  478.  
  479.         public Color4[] GenerateOpenGLColors(int quantity)
  480.         {
  481.             Color4[] buffer = new Color4[quantity];
  482.             for (int i = 0; i < buffer.Length; i++)
  483.             {
  484.                 buffer[i] = GenerateColor();
  485.             }
  486.             return buffer;
  487.         }
  488.  
  489.         #endregion
  490.  
  491.         #region Randomization Functions
  492.  
  493.         /// <summary>
  494.         /// Randomizes the specified list.
  495.         /// </summary>
  496.         /// <typeparam name="T"></typeparam>
  497.         /// <param name="list">The list.</param>
  498.         public void Randomize<T>(List<T> list)
  499.         {
  500.             int n = list.Count;
  501.             while (n > 1)
  502.             {
  503.                 n--;
  504.                 int k = GenerateInteger(n + 1);
  505.                 T value = list[k];
  506.                 list[k] = list[n];
  507.                 list[n] = value;
  508.             }
  509.         }
  510.  
  511.         /// <summary>
  512.         /// Randomizes the specified list.
  513.         /// </summary>
  514.         /// <typeparam name="T"></typeparam>
  515.         /// <param name="list">The list.</param>
  516.         public void Randomize<T>(T[] list)
  517.         {
  518.             int n = list.Length;
  519.             while (n > 1)
  520.             {
  521.                 n--;
  522.                 int k = GenerateInteger(n + 1);
  523.                 T value = list[k];
  524.                 list[k] = list[n];
  525.                 list[n] = value;
  526.             }
  527.         }
  528.  
  529.         public T Choose<T>(T[] items)
  530.         {
  531.             return items[GenerateInteger(items.Length)];
  532.         }
  533.  
  534.         public T[] Choose<T>(T[] items, int quantity)
  535.         {
  536.             T[] chosenItems = new T[quantity];
  537.             for (int i = 0; i < chosenItems.Length; i++)
  538.             {
  539.                 chosenItems[i] = Choose(items);
  540.             }
  541.             return chosenItems;
  542.         }
  543.  
  544.         #endregion
  545.  
  546.         #region Probability Functions
  547.  
  548.         /// <summary>
  549.         /// Nexts the probability.
  550.         /// </summary>
  551.         /// <param name="percent">The percent.</param>
  552.         /// <returns></returns>
  553.         public bool GenerateProbability(double percent)
  554.         {
  555.             if (percent >= 1.0)
  556.             {
  557.                 return true;
  558.             }
  559.             if (percent <= 0.0)
  560.             {
  561.                 return false;
  562.             }
  563.             return GenerateDouble() <= percent;
  564.         }
  565.  
  566.         public void GenerateProbabilities(double percent, bool[] buffer)
  567.         {
  568.             for (int i = 0; i < buffer.Length; i++)
  569.             {
  570.                 buffer[i] = GenerateProbability(percent);
  571.             }
  572.         }
  573.  
  574.         public bool[] GenerateProbabilities(double percent, int count)
  575.         {
  576.             bool[] buffer = new bool[count];
  577.             GenerateProbabilities(percent, buffer);
  578.             return buffer;
  579.         }
  580.  
  581.         #endregion
  582.  
  583.         #region Internals
  584.  
  585.         public double Sample()
  586.         {
  587.             return (InternalSample()*(1.0/ Int32.MaxValue));
  588.         }
  589.  
  590.         private int InternalSample()
  591.         {
  592.             int locINext = _inext;
  593.             int locINextp = _inextp;
  594.  
  595.             if (++locINext >= 56)
  596.             {
  597.                 locINext = 1;
  598.             }
  599.             if (++locINextp >= 56)
  600.             {
  601.                 locINextp = 1;
  602.             }
  603.             int retVal = _seedArray[locINext] - _seedArray[locINextp];
  604.             if (retVal == Int32.MaxValue)
  605.             {
  606.                 retVal--;
  607.             }
  608.             if (retVal < 0)
  609.             {
  610.                 retVal += Int32.MaxValue;
  611.             }
  612.             _seedArray[locINext] = retVal;
  613.             _inext = locINext;
  614.             _inextp = locINextp;
  615.             return retVal;
  616.         }
  617.  
  618.         #endregion
  619.  
  620.     }
  621. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement