com.wallstop-studios.unity-helpers 2.0.0-rc07 → 2.0.0-rc09
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Runtime/Core/Extension/DirectionExtensions.cs +5 -2
- package/Runtime/Core/Extension/IEnumerableExtensions.cs +19 -6
- package/Runtime/Core/Extension/RandomExtensions.cs +9 -87
- package/Runtime/Core/Extension/UnityExtensions.cs +2 -2
- package/Runtime/Core/Random/AbstractRandom.cs +82 -128
- package/Runtime/Core/Random/IRandom.cs +26 -7
- package/Runtime/Core/Random/PerlinNoise.cs +369 -0
- package/Runtime/Core/Random/PerlinNoise.cs.meta +3 -0
- package/Runtime/Utils/RuntimeSingleton.cs +26 -4
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +27 -0
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs.meta +3 -0
- package/Tests/Runtime/Random/RandomTestBase.cs +300 -4
- package/Tests/Runtime/Random/SquirrelRandomTests.cs +1 -1
- package/package.json +1 -1
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
public static class DirectionExtensions
|
|
11
11
|
{
|
|
12
|
-
private static readonly
|
|
12
|
+
private static readonly Direction[] Directions = Enum.GetValues(typeof(Direction))
|
|
13
|
+
.OfType<Direction>()
|
|
14
|
+
.Except(Enumerables.Of(Direction.None))
|
|
15
|
+
.ToArray();
|
|
13
16
|
|
|
14
17
|
public static Direction Opposite(this Direction direction)
|
|
15
18
|
{
|
|
@@ -106,7 +109,7 @@
|
|
|
106
109
|
|
|
107
110
|
public static Direction AsDirection(this Vector2 vector, bool preferAngles = false)
|
|
108
111
|
{
|
|
109
|
-
if (vector
|
|
112
|
+
if (vector == Vector2.zero)
|
|
110
113
|
{
|
|
111
114
|
return Direction.None;
|
|
112
115
|
}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
namespace UnityHelpers.Core.Extension
|
|
2
2
|
{
|
|
3
|
-
using Random;
|
|
4
3
|
using System;
|
|
5
4
|
using System.Collections.Concurrent;
|
|
6
5
|
using System.Collections.Generic;
|
|
7
6
|
using System.Linq;
|
|
7
|
+
using Random;
|
|
8
8
|
|
|
9
9
|
public static class IEnumerableExtensions
|
|
10
10
|
{
|
|
11
11
|
private static readonly ConcurrentDictionary<object, object> ComparerCache = new();
|
|
12
12
|
|
|
13
|
+
public static LinkedList<T> ToLinkedList<T>(this IEnumerable<T> source)
|
|
14
|
+
{
|
|
15
|
+
return new LinkedList<T>(source);
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
public static IList<T> AsList<T>(this IEnumerable<T> enumeration)
|
|
14
19
|
{
|
|
15
20
|
if (enumeration is IList<T> list)
|
|
@@ -20,18 +25,27 @@
|
|
|
20
25
|
return enumeration.ToList();
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
public static IEnumerable<T> OrderBy<T>(
|
|
28
|
+
public static IEnumerable<T> OrderBy<T>(
|
|
29
|
+
this IEnumerable<T> enumeration,
|
|
30
|
+
Func<T, T, int> comparer
|
|
31
|
+
)
|
|
24
32
|
{
|
|
25
|
-
FuncBasedComparer<T> comparerObject =
|
|
33
|
+
FuncBasedComparer<T> comparerObject =
|
|
34
|
+
(FuncBasedComparer<T>)
|
|
35
|
+
ComparerCache.GetOrAdd(comparer, () => new FuncBasedComparer<T>(comparer));
|
|
26
36
|
return enumeration.OrderBy(_ => _, comparerObject);
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
public static IEnumerable<T> Ordered<T>(this IEnumerable<T> enumerable)
|
|
39
|
+
public static IEnumerable<T> Ordered<T>(this IEnumerable<T> enumerable)
|
|
40
|
+
where T : IComparable
|
|
30
41
|
{
|
|
31
42
|
return enumerable.OrderBy(_ => _);
|
|
32
43
|
}
|
|
33
44
|
|
|
34
|
-
public static IEnumerable<T> Shuffled<T>(
|
|
45
|
+
public static IEnumerable<T> Shuffled<T>(
|
|
46
|
+
this IEnumerable<T> enumerable,
|
|
47
|
+
IRandom random = null
|
|
48
|
+
)
|
|
35
49
|
{
|
|
36
50
|
random = random ?? ThreadLocalRandom<PcgRandom>.Instance;
|
|
37
51
|
return enumerable.OrderBy(_ => random.Next());
|
|
@@ -90,7 +104,6 @@
|
|
|
90
104
|
return list;
|
|
91
105
|
}
|
|
92
106
|
|
|
93
|
-
|
|
94
107
|
private class FuncBasedComparer<T> : IComparer<T>
|
|
95
108
|
{
|
|
96
109
|
private readonly Func<T, T, int> _comparer;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
namespace UnityHelpers.Core.Extension
|
|
2
2
|
{
|
|
3
|
-
using System;
|
|
4
|
-
using System.Collections.Generic;
|
|
5
|
-
using System.Linq;
|
|
6
3
|
using Helper;
|
|
7
4
|
using Random;
|
|
8
5
|
using UnityEngine;
|
|
@@ -14,15 +11,6 @@
|
|
|
14
11
|
return random.NextVector2(-amplitude, amplitude);
|
|
15
12
|
}
|
|
16
13
|
|
|
17
|
-
public static Vector2 NextVector2InRange(
|
|
18
|
-
this IRandom random,
|
|
19
|
-
float range,
|
|
20
|
-
Vector2? origin = null
|
|
21
|
-
)
|
|
22
|
-
{
|
|
23
|
-
return Helpers.GetRandomPointInCircle(origin ?? Vector2.zero, range, random);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
14
|
public static Vector2 NextVector2(
|
|
27
15
|
this IRandom random,
|
|
28
16
|
float minAmplitude,
|
|
@@ -34,6 +22,15 @@
|
|
|
34
22
|
return new Vector2(x, y);
|
|
35
23
|
}
|
|
36
24
|
|
|
25
|
+
public static Vector2 NextVector2InRange(
|
|
26
|
+
this IRandom random,
|
|
27
|
+
float range,
|
|
28
|
+
Vector2? origin = null
|
|
29
|
+
)
|
|
30
|
+
{
|
|
31
|
+
return Helpers.GetRandomPointInCircle(origin ?? Vector2.zero, range, random);
|
|
32
|
+
}
|
|
33
|
+
|
|
37
34
|
public static Vector3 NextVector3(this IRandom random, float amplitude)
|
|
38
35
|
{
|
|
39
36
|
return random.NextVector3(-amplitude, amplitude);
|
|
@@ -50,80 +47,5 @@
|
|
|
50
47
|
result.z = z;
|
|
51
48
|
return result;
|
|
52
49
|
}
|
|
53
|
-
|
|
54
|
-
public static T NextEnum<T>(this IRandom random)
|
|
55
|
-
where T : struct
|
|
56
|
-
{
|
|
57
|
-
T[] enumValues = (T[])Enum.GetValues(typeof(T));
|
|
58
|
-
if (enumValues.Length == 0)
|
|
59
|
-
{
|
|
60
|
-
return default(T);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (enumValues.Length == 1)
|
|
64
|
-
{
|
|
65
|
-
return enumValues[0];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (enumValues.Length == 2)
|
|
69
|
-
{
|
|
70
|
-
return random.NextBool() ? enumValues[0] : enumValues[1];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
int nextIndex = random.Next(0, enumValues.Length);
|
|
74
|
-
return enumValues[nextIndex];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
public static T Next<T>(this IRandom random, IList<T> elements)
|
|
78
|
-
{
|
|
79
|
-
if (ReferenceEquals(elements, null) || elements.Count == 0)
|
|
80
|
-
{
|
|
81
|
-
return default(T);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
switch (elements.Count)
|
|
85
|
-
{
|
|
86
|
-
case 1:
|
|
87
|
-
return elements[0];
|
|
88
|
-
case 2:
|
|
89
|
-
return random.NextBool() ? elements[0] : elements[1];
|
|
90
|
-
default:
|
|
91
|
-
int index = random.Next(0, elements.Count);
|
|
92
|
-
return elements[index];
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
public static T Next<T>(this IRandom random, IEnumerable<T> elements)
|
|
97
|
-
{
|
|
98
|
-
if (ReferenceEquals(elements, null))
|
|
99
|
-
{
|
|
100
|
-
return default(T);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
IList<T> elementsList = elements as IList<T>;
|
|
104
|
-
if (!ReferenceEquals(elementsList, null))
|
|
105
|
-
{
|
|
106
|
-
return Next(random, elementsList);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
ICollection<T> maybeCollection = elements as ICollection<T>;
|
|
110
|
-
if (!ReferenceEquals(maybeCollection, null))
|
|
111
|
-
{
|
|
112
|
-
int count = maybeCollection.Count;
|
|
113
|
-
int randomIndex = random.Next(0, count);
|
|
114
|
-
|
|
115
|
-
int i = 0;
|
|
116
|
-
foreach (T element in maybeCollection)
|
|
117
|
-
{
|
|
118
|
-
if (i++ == randomIndex)
|
|
119
|
-
{
|
|
120
|
-
return element;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
elementsList = elements.ToArray();
|
|
126
|
-
return Next(random, elementsList);
|
|
127
|
-
}
|
|
128
50
|
}
|
|
129
51
|
}
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
return convexHull;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
Vector3Int nextPoint = random.
|
|
269
|
+
Vector3Int nextPoint = random.NextOf(points);
|
|
270
270
|
Vector2 currentPointWorldPosition = CellToWorld(currentPoint);
|
|
271
271
|
Vector2 nextPointWorldPosition = CellToWorld(nextPoint);
|
|
272
272
|
foreach (Vector3Int point in points)
|
|
@@ -389,7 +389,7 @@
|
|
|
389
389
|
return convexHull;
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
-
FastVector3Int nextPoint = random.
|
|
392
|
+
FastVector3Int nextPoint = random.NextOf(points);
|
|
393
393
|
Vector2 currentPointWorldPosition = CellToWorld(currentPoint);
|
|
394
394
|
Vector2 nextPointWorldPosition = CellToWorld(nextPoint);
|
|
395
395
|
foreach (FastVector3Int point in points)
|
|
@@ -55,102 +55,6 @@
|
|
|
55
55
|
return unchecked((int)(min + NextUint(range)));
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
public T Next<T>(IEnumerable<T> enumerable)
|
|
59
|
-
{
|
|
60
|
-
if (enumerable is ICollection<T> collection)
|
|
61
|
-
{
|
|
62
|
-
return Next(collection);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return Next((IReadOnlyList<T>)enumerable.ToList());
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
public T Next<T>(ICollection<T> collection)
|
|
69
|
-
{
|
|
70
|
-
int count = collection.Count;
|
|
71
|
-
if (count <= 0)
|
|
72
|
-
{
|
|
73
|
-
throw new ArgumentException("Collection size cannot be less-than or equal-to 0");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
switch (collection)
|
|
77
|
-
{
|
|
78
|
-
case IList<T> list:
|
|
79
|
-
return Next(list);
|
|
80
|
-
case IReadOnlyList<T> readOnlyList:
|
|
81
|
-
return Next(readOnlyList);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
int index = Next(count);
|
|
85
|
-
int i = 0;
|
|
86
|
-
foreach (T element in collection)
|
|
87
|
-
{
|
|
88
|
-
if (i++ == index)
|
|
89
|
-
{
|
|
90
|
-
return element;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Should never happen
|
|
95
|
-
return default;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
public T Next<T>(IList<T> list)
|
|
99
|
-
{
|
|
100
|
-
if (ReferenceEquals(list, null))
|
|
101
|
-
{
|
|
102
|
-
throw new ArgumentNullException(nameof(list));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/*
|
|
106
|
-
For small lists, it's much more efficient to simply return one of their elements
|
|
107
|
-
instead of trying to generate a random number within bounds (which is implemented as a while(true) loop)
|
|
108
|
-
*/
|
|
109
|
-
switch (list.Count)
|
|
110
|
-
{
|
|
111
|
-
case 1:
|
|
112
|
-
return list[0];
|
|
113
|
-
case 2:
|
|
114
|
-
return NextBool() ? list[0] : list[1];
|
|
115
|
-
default:
|
|
116
|
-
return list[Next(list.Count)];
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private T Next<T>(IReadOnlyList<T> list)
|
|
121
|
-
{
|
|
122
|
-
/*
|
|
123
|
-
For small lists, it's much more efficient to simply return one of their elements
|
|
124
|
-
instead of trying to generate a random number within bounds (which is implemented as a while(true) loop)
|
|
125
|
-
*/
|
|
126
|
-
switch (list.Count)
|
|
127
|
-
{
|
|
128
|
-
case 1:
|
|
129
|
-
return list[0];
|
|
130
|
-
case 2:
|
|
131
|
-
return NextBool() ? list[0] : list[1];
|
|
132
|
-
default:
|
|
133
|
-
return list[Next(list.Count)];
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
public T Next<T>()
|
|
138
|
-
where T : struct, Enum
|
|
139
|
-
{
|
|
140
|
-
Type enumType = typeof(T);
|
|
141
|
-
T[] enumValues;
|
|
142
|
-
if (EnumTypeCache.TryGetValue(enumType, out Array enumArray))
|
|
143
|
-
{
|
|
144
|
-
enumValues = (T[])enumArray;
|
|
145
|
-
}
|
|
146
|
-
else
|
|
147
|
-
{
|
|
148
|
-
enumValues = (T[])Enum.GetValues(enumType);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return RandomOf(enumValues);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
58
|
// Internal sampler
|
|
155
59
|
public abstract uint NextUint();
|
|
156
60
|
|
|
@@ -212,7 +116,7 @@
|
|
|
212
116
|
uint lower = NextUint();
|
|
213
117
|
unchecked
|
|
214
118
|
{
|
|
215
|
-
return (long)((((ulong)upper << 32) | lower) &
|
|
119
|
+
return (long)((((ulong)upper << 32) | lower) & 0x7FFFFFFFFFFFFFFF);
|
|
216
120
|
}
|
|
217
121
|
}
|
|
218
122
|
|
|
@@ -275,34 +179,36 @@
|
|
|
275
179
|
|
|
276
180
|
public void NextBytes(byte[] buffer)
|
|
277
181
|
{
|
|
278
|
-
if (
|
|
182
|
+
if (buffer == null)
|
|
279
183
|
{
|
|
280
184
|
throw new ArgumentException(nameof(buffer));
|
|
281
185
|
}
|
|
282
186
|
|
|
283
|
-
const
|
|
187
|
+
const int sizeOfInt = 4; // May differ on some platforms
|
|
284
188
|
|
|
285
189
|
// See how many ints we can slap into it.
|
|
286
190
|
int chunks = buffer.Length / sizeOfInt;
|
|
287
|
-
|
|
191
|
+
int spare = buffer.Length - chunks * sizeOfInt;
|
|
288
192
|
for (int i = 0; i < chunks; ++i)
|
|
289
193
|
{
|
|
290
|
-
int offset = i *
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
194
|
+
int offset = i * sizeOfInt;
|
|
195
|
+
uint random = NextUint();
|
|
196
|
+
for (int j = 0; j < sizeOfInt; ++j)
|
|
197
|
+
{
|
|
198
|
+
buffer[offset + j] = unchecked(
|
|
199
|
+
(byte)((random >> (j * sizeOfInt)) & 0x000000FF)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
296
202
|
}
|
|
297
203
|
|
|
204
|
+
if (0 < spare)
|
|
298
205
|
{
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
bit shifting along the position, but that is too much for me right now.
|
|
302
|
-
*/
|
|
303
|
-
for (byte i = 0; i < spare; ++i)
|
|
206
|
+
uint spareRandom = NextUint();
|
|
207
|
+
for (int i = 0; i < spare; ++i)
|
|
304
208
|
{
|
|
305
|
-
buffer[buffer.Length - 1 - i] = unchecked(
|
|
209
|
+
buffer[buffer.Length - 1 - i] = unchecked(
|
|
210
|
+
(byte)((spareRandom >> (i * sizeOfInt)) & 0x000000FF)
|
|
211
|
+
);
|
|
306
212
|
}
|
|
307
213
|
}
|
|
308
214
|
}
|
|
@@ -343,7 +249,7 @@
|
|
|
343
249
|
return NextDoubleWithInfiniteRange(min, max);
|
|
344
250
|
}
|
|
345
251
|
|
|
346
|
-
return min +
|
|
252
|
+
return min + NextDouble() * range;
|
|
347
253
|
}
|
|
348
254
|
|
|
349
255
|
protected double NextDoubleWithInfiniteRange(double min, double max)
|
|
@@ -408,7 +314,7 @@
|
|
|
408
314
|
x = 2 * NextDouble() - 1;
|
|
409
315
|
y = 2 * NextDouble() - 1;
|
|
410
316
|
square = x * x + y * y;
|
|
411
|
-
} while (square
|
|
317
|
+
} while (square is 0 or > 1);
|
|
412
318
|
|
|
413
319
|
double fac = Math.Sqrt(-2 * Math.Log(square) / square);
|
|
414
320
|
_cachedGaussian = x * fac;
|
|
@@ -454,7 +360,53 @@
|
|
|
454
360
|
return min + NextFloat(range);
|
|
455
361
|
}
|
|
456
362
|
|
|
457
|
-
public T
|
|
363
|
+
public T NextOf<T>(IEnumerable<T> enumerable)
|
|
364
|
+
{
|
|
365
|
+
return enumerable switch
|
|
366
|
+
{
|
|
367
|
+
IReadOnlyList<T> list => NextOf(list),
|
|
368
|
+
IReadOnlyCollection<T> collection => NextOf(collection),
|
|
369
|
+
null => throw new ArgumentNullException(nameof(enumerable)),
|
|
370
|
+
_ => NextOf(enumerable.ToArray()),
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
public T NextOf<T>(IReadOnlyCollection<T> collection)
|
|
375
|
+
{
|
|
376
|
+
if (collection is not { Count: > 0 })
|
|
377
|
+
{
|
|
378
|
+
throw new ArgumentException("Collection cannot be empty");
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (collection is IReadOnlyList<T> list)
|
|
382
|
+
{
|
|
383
|
+
return NextOf(list);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
int index = Next(collection.Count);
|
|
387
|
+
return collection.ElementAt(index);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
public T NextOf<T>(IReadOnlyList<T> list)
|
|
391
|
+
{
|
|
392
|
+
if (list is not { Count: > 0 })
|
|
393
|
+
{
|
|
394
|
+
throw new ArgumentNullException(nameof(list));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/*
|
|
398
|
+
For small lists, it's much more efficient to simply return one of their elements
|
|
399
|
+
instead of trying to generate a random number within bounds (which is implemented as a while(true) loop)
|
|
400
|
+
*/
|
|
401
|
+
return list.Count switch
|
|
402
|
+
{
|
|
403
|
+
1 => list[0],
|
|
404
|
+
2 => NextBool() ? list[0] : list[1],
|
|
405
|
+
_ => list[Next(list.Count)],
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
public T NextEnum<T>()
|
|
458
410
|
where T : struct, Enum
|
|
459
411
|
{
|
|
460
412
|
Type enumType = typeof(T);
|
|
@@ -479,7 +431,13 @@
|
|
|
479
431
|
|
|
480
432
|
// Advances the RNG
|
|
481
433
|
// https://code2d.wordpress.com/2020/07/21/perlin-noise/
|
|
482
|
-
public float[,] NextNoiseMap(
|
|
434
|
+
public float[,] NextNoiseMap(
|
|
435
|
+
int width,
|
|
436
|
+
int height,
|
|
437
|
+
PerlinNoise noise = null,
|
|
438
|
+
float scale = 2.5f,
|
|
439
|
+
int octaves = 8
|
|
440
|
+
)
|
|
483
441
|
{
|
|
484
442
|
if (width <= 0)
|
|
485
443
|
{
|
|
@@ -501,6 +459,7 @@
|
|
|
501
459
|
throw new ArgumentException(nameof(octaves));
|
|
502
460
|
}
|
|
503
461
|
|
|
462
|
+
noise ??= PerlinNoise.Instance;
|
|
504
463
|
float[,] noiseMap = new float[width, height];
|
|
505
464
|
|
|
506
465
|
Vector2[] octaveOffsets = new Vector2[octaves];
|
|
@@ -529,8 +488,7 @@
|
|
|
529
488
|
float sampleX = (x - halfWidth) / scale * frequency + octaveOffsets[i].x;
|
|
530
489
|
float sampleY = (y - halfHeight) / scale * frequency + octaveOffsets[i].y;
|
|
531
490
|
|
|
532
|
-
|
|
533
|
-
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
|
|
491
|
+
float perlinValue = noise.Noise(sampleX, sampleY) * 2 - 1;
|
|
534
492
|
noiseHeight += perlinValue * amplitude;
|
|
535
493
|
}
|
|
536
494
|
|
|
@@ -565,17 +523,13 @@
|
|
|
565
523
|
|
|
566
524
|
protected T RandomOf<T>(T[] values)
|
|
567
525
|
{
|
|
568
|
-
|
|
526
|
+
return values.Length switch
|
|
569
527
|
{
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
return NextBool() ? values[0] : values[1];
|
|
576
|
-
default:
|
|
577
|
-
return values[Next(values.Length)];
|
|
578
|
-
}
|
|
528
|
+
0 => default,
|
|
529
|
+
1 => values[0],
|
|
530
|
+
2 => NextBool() ? values[0] : values[1],
|
|
531
|
+
_ => values[Next(values.Length)],
|
|
532
|
+
};
|
|
579
533
|
}
|
|
580
534
|
|
|
581
535
|
public abstract IRandom Copy();
|
|
@@ -27,10 +27,12 @@
|
|
|
27
27
|
/// </summary>
|
|
28
28
|
/// <returns>A number within the range [0, uint.MaxValue].</returns>
|
|
29
29
|
uint NextUint();
|
|
30
|
+
|
|
30
31
|
/// <summary>
|
|
31
32
|
/// </summary>
|
|
32
33
|
/// <returns>A number within the range [0, max).</returns>
|
|
33
34
|
uint NextUint(uint max);
|
|
35
|
+
|
|
34
36
|
/// <summary>
|
|
35
37
|
/// </summary>
|
|
36
38
|
/// <returns>A number within the range [min, max).</returns>
|
|
@@ -45,6 +47,7 @@
|
|
|
45
47
|
/// </summary>
|
|
46
48
|
/// <returns>A number within the range [0, max).</returns>
|
|
47
49
|
short NextShort(short max);
|
|
50
|
+
|
|
48
51
|
/// <summary>
|
|
49
52
|
/// </summary>
|
|
50
53
|
/// <returns>A number within the range [min, max).</returns>
|
|
@@ -54,10 +57,12 @@
|
|
|
54
57
|
/// </summary>
|
|
55
58
|
/// <returns>A number within the range [0, byte.MaxValue).</returns>
|
|
56
59
|
byte NextByte();
|
|
60
|
+
|
|
57
61
|
/// <summary>
|
|
58
62
|
/// </summary>
|
|
59
63
|
/// <returns>A number within the range [0, max).</returns>
|
|
60
64
|
byte NextByte(byte max);
|
|
65
|
+
|
|
61
66
|
/// <summary>
|
|
62
67
|
/// </summary>
|
|
63
68
|
/// <returns>A number within the range [min, max).</returns>
|
|
@@ -67,10 +72,12 @@
|
|
|
67
72
|
/// </summary>
|
|
68
73
|
/// <returns>A number within the range [0, long.MaxValue).</returns>
|
|
69
74
|
long NextLong();
|
|
75
|
+
|
|
70
76
|
/// <summary>
|
|
71
77
|
/// </summary>
|
|
72
78
|
/// <returns>A number within the range [0, max).</returns>
|
|
73
79
|
long NextLong(long max);
|
|
80
|
+
|
|
74
81
|
/// <summary>
|
|
75
82
|
/// </summary>
|
|
76
83
|
/// <returns>A number within the range [min, max).</returns>
|
|
@@ -80,10 +87,12 @@
|
|
|
80
87
|
/// </summary>
|
|
81
88
|
/// <returns>A number within the range [0, ulong.MaxValue).</returns>
|
|
82
89
|
ulong NextUlong();
|
|
90
|
+
|
|
83
91
|
/// <summary>
|
|
84
92
|
/// </summary>
|
|
85
93
|
/// <returns>A number within the range [0, max).</returns>
|
|
86
94
|
ulong NextUlong(ulong max);
|
|
95
|
+
|
|
87
96
|
/// <summary>
|
|
88
97
|
/// </summary>
|
|
89
98
|
/// <returns>A number within the range [min, max).</returns>
|
|
@@ -100,10 +109,12 @@
|
|
|
100
109
|
/// </summary>
|
|
101
110
|
/// <returns>A number within the range [0, 1).</returns>
|
|
102
111
|
float NextFloat();
|
|
112
|
+
|
|
103
113
|
/// <summary>
|
|
104
114
|
/// </summary>
|
|
105
115
|
/// <returns>A number within the range [0, max).</returns>
|
|
106
116
|
float NextFloat(float max);
|
|
117
|
+
|
|
107
118
|
/// <summary>
|
|
108
119
|
/// </summary>
|
|
109
120
|
/// <returns>A number within the range min, max).</returns>
|
|
@@ -113,10 +124,12 @@
|
|
|
113
124
|
/// </summary>
|
|
114
125
|
/// <returns>A number within the range [0, 1).</returns>
|
|
115
126
|
double NextDouble();
|
|
127
|
+
|
|
116
128
|
/// <summary>
|
|
117
129
|
/// </summary>
|
|
118
130
|
/// <returns>A number within the range [0, max).</returns>
|
|
119
131
|
double NextDouble(double max);
|
|
132
|
+
|
|
120
133
|
/// <summary>
|
|
121
134
|
/// </summary>
|
|
122
135
|
/// <returns>A number within the range min, max).</returns>
|
|
@@ -127,15 +140,21 @@
|
|
|
127
140
|
Guid NextGuid();
|
|
128
141
|
KGuid NextKGuid();
|
|
129
142
|
|
|
130
|
-
T
|
|
131
|
-
T
|
|
132
|
-
T
|
|
143
|
+
T NextOf<T>(IEnumerable<T> enumerable);
|
|
144
|
+
T NextOf<T>(IReadOnlyCollection<T> collection);
|
|
145
|
+
T NextOf<T>(IReadOnlyList<T> list);
|
|
133
146
|
|
|
134
|
-
T
|
|
135
|
-
|
|
147
|
+
T NextEnum<T>()
|
|
148
|
+
where T : struct, Enum;
|
|
136
149
|
|
|
137
|
-
float[,] NextNoiseMap(
|
|
150
|
+
float[,] NextNoiseMap(
|
|
151
|
+
int width,
|
|
152
|
+
int height,
|
|
153
|
+
PerlinNoise noise = null,
|
|
154
|
+
float scale = 2.5f,
|
|
155
|
+
int octaves = 8
|
|
156
|
+
);
|
|
138
157
|
|
|
139
158
|
IRandom Copy();
|
|
140
159
|
}
|
|
141
|
-
}
|
|
160
|
+
}
|