A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5
6namespace osu.Framework.Utils
7{
8 /// <summary>
9 /// Static utility class for random number generation.
10 /// </summary>
11 public static class RNG
12 {
13 // Base RNG. Maybe expose methods for re-seeding in the future?
14 private static readonly Random random = new Random();
15
16 /// <summary>
17 /// Returns a non-negative signed integer.
18 /// </summary>
19 /// <returns>A non-negative signed integer.</returns>
20 public static int Next() => random.Next();
21
22 /// <summary>
23 /// Returns a signed integer in the range [0,maxValue).
24 /// </summary>
25 /// <param name="maxValue">The maximum value that should be returned (exclusive, the highest possible result is maxValue - 1).</param>
26 /// <returns>A signed integer in the range [0,maxValue).</returns>
27 public static int Next(int maxValue) => random.Next(maxValue);
28
29 /// <summary>
30 /// Returns a signed integer in the range [minValue,maxValue).
31 /// </summary>
32 /// <param name="minValue">The minimum value that should be returned (inclusive).</param>
33 /// <param name="maxValue">The maximum value that should be returned (exclusive, the highest possible result is maxValue - 1).</param>
34 /// <returns>A signed integer in the range [minValue,maxValue).</returns>
35 public static int Next(int minValue, int maxValue) => random.Next(minValue, maxValue);
36
37 /// <summary>
38 /// Returns a double-precision floating point number in the range [0,1).
39 /// </summary>
40 /// <returns>A double-precision floating point number in the range [0,1).</returns>
41 public static double NextDouble() => random.NextDouble();
42
43 /// <summary>
44 /// Returns a double-precision floating point number in the range [0,maxValue).
45 /// </summary>
46 /// <param name="maxValue">The maximum value that should be returned (exclusive).</param>
47 /// <returns>A double-precision floating point number in the range [0,maxValue).</returns>
48 public static double NextDouble(double maxValue)
49 {
50 if (maxValue < 0.0)
51 throw new ArgumentOutOfRangeException(nameof(maxValue), "The given maximum value must be greater than or equal to 0.");
52
53 return random.NextDouble() * maxValue;
54 }
55
56 /// <summary>
57 /// Returns a double-precision floating point number in the range [minValue,maxValue).
58 /// </summary>
59 /// <param name="minValue">The minimum value that should be returned (inclusive).</param>
60 /// <param name="maxValue">The maximum value that should be returned (exclusive).</param>
61 /// <returns>A double-precision floating point number in the range [minValue,maxValue).</returns>
62 public static double NextDouble(double minValue, double maxValue)
63 {
64 if (minValue > maxValue)
65 throw new ArgumentOutOfRangeException(nameof(minValue), "The given minimum value must be less than or equal to the given maximum value.");
66
67 return minValue + random.NextDouble() * (maxValue - minValue);
68 }
69
70 /// <summary>
71 /// Returns a single-precision floating point number in the range [0,1).
72 /// </summary>
73 /// <returns>A single-precision floating point number in the range [0,1).</returns>
74 public static float NextSingle() => (float)NextDouble();
75
76 /// <summary>
77 /// Returns a single-precision floating point number in the range [0,maxValue).
78 /// </summary>
79 /// <param name="maxValue">The maximum value that should be returned (exclusive).</param>
80 /// <returns>A single-precision floating point number in the range [0,maxValue).</returns>
81 public static float NextSingle(float maxValue)
82 {
83 if (maxValue < 0.0f)
84 throw new ArgumentOutOfRangeException(nameof(maxValue), "The given maximum value must be greater than or equal to 0.");
85
86 return NextSingle() * maxValue;
87 }
88
89 /// <summary>
90 /// Returns a single-precision floating point number in the range [minValue,maxValue).
91 /// </summary>
92 /// <param name="minValue">The minimum value that should be returned (inclusive).</param>
93 /// <param name="maxValue">The maximum value that should be returned (exclusive).</param>
94 /// <returns>A single-precision floating point number in the range [minValue,maxValue).</returns>
95 public static float NextSingle(float minValue, float maxValue)
96 {
97 if (minValue > maxValue)
98 throw new ArgumentOutOfRangeException(nameof(minValue), "The given minimum value must be less than or equal to the given maximum value.");
99
100 return minValue + NextSingle() * (maxValue - minValue);
101 }
102
103 /// <summary>
104 /// Returns true or false. The likelihood of true and false are determined by trueChance.
105 /// </summary>
106 /// <param name="trueChance">The chance that the result is true (a value from 0.0 to 1.0).</param>
107 /// <returns>True or false with the given probability.</returns>
108 public static bool NextBool(double trueChance = 0.5) => NextDouble() < trueChance;
109
110 /// <summary>
111 /// Fills the given buffer with random bytes.
112 /// </summary>
113 /// <param name="buffer">The buffer that should be filled.</param>
114 public static void NextBytes(byte[] buffer) => random.NextBytes(buffer);
115
116 /// <summary>
117 /// Creates a new byte array with the given length and fills it with random values.
118 /// </summary>
119 /// <param name="length">The length the byte array should have.</param>
120 /// <returns>The newly created byte array.</returns>
121 public static byte[] NextBytes(int length)
122 {
123 byte[] bytes = new byte[length];
124 NextBytes(bytes);
125 return bytes;
126 }
127 }
128}