11using System ;
2+ using System . Collections . Generic ;
23
34namespace GameLovers . Services
45{
56 /// <summary>
6- /// Contains all the data in the scope to generate and maintain the random generated values
7+ /// Implement this interface if you use a data structure in a class to pass the values by reference
8+ /// and thus updating directly your internal data container.
79 /// </summary>
8- [ Serializable ]
9- public struct RngData
10+ public interface IRngData
1011 {
11- public int Seed ;
12- public int Count ;
13- public int [ ] State ;
12+ /// <summary>
13+ /// Gets the seed used to initialize the RNG.
14+ /// </summary>
15+ int Seed { get ; }
16+
17+ /// <summary>
18+ /// Gets the number of random numbers generated so far.
19+ /// </summary>
20+ int Count { get ; }
21+
22+ /// <summary>
23+ /// Gets the current state of the RNG.
24+ /// </summary>
25+ IReadOnlyList < int > State { get ; }
1426 }
1527
1628 /// <summary>
17- /// Implement this interface if you use a data structure in a class to pass the values by reference
18- /// and thus updating directly your internal data container
29+ /// Represents a data structure for storing random number generation (RNG) state.
1930 /// </summary>
20- public interface IRngData
31+ public class RngData : IRngData
2132 {
2233 /// <summary>
23- /// The data container the state of the RNG information change .
34+ /// The seed used to initialize the RNG.
2435 /// </summary>
25- RngData Data { get ; set ; }
26- }
36+ public int Seed ;
37+
38+ /// <summary>
39+ /// The number of random numbers generated so far.
40+ /// </summary>
41+ public int Count ;
42+
43+ /// <summary>
44+ /// The current state of the RNG.
45+ /// </summary>
46+ public int [ ] State ;
2747
48+ /// <inheritdoc/>
49+ int IRngData . Seed => Seed ;
50+ /// <inheritdoc/>
51+ int IRngData . Count => Count ;
52+ /// <inheritdoc/>
53+ IReadOnlyList < int > IRngData . State => Array . AsReadOnly ( State ) ;
54+ }
2855 /// <summary>
2956 /// This Service provides the necessary behaviour to manage the random generated values with always a deterministic result
3057 /// Based on the .Net library Random class <see cref="https://referencesource.microsoft.com/#mscorlib/system/random.cs"/>
3158 /// </summary>
3259 public interface IRngService
3360 {
3461 /// <summary>
35- /// The <see cref="RngData "/> that this service is manipulating
62+ /// The <see cref="IRngData "/> that this service is manipulating
3663 /// </summary>
37- public RngData Data { get ; }
64+ public IRngData Data { get ; }
3865
3966 /// <summary>
4067 /// Returns the number of times the Rng has been counted;
@@ -96,7 +123,7 @@ public class RngService : IRngService
96123 private const int _helperInc = 21 ;
97124 private const int _valueIndex = 0 ;
98125
99- private IRngData _rngData ;
126+ private RngData _rngData ;
100127
101128 /// <inheritdoc />
102129 public int Counter => Data . Count ;
@@ -114,67 +141,46 @@ public class RngService : IRngService
114141 public floatP Nextfloat => Range ( ( floatP ) 0 , floatP . MaxValue ) ;
115142
116143 /// <inheritdoc />
117- public RngData Data
118- {
119- get => _rngData . Data ;
120- private set => _rngData . Data = value ;
121- }
144+ public IRngData Data => _rngData ;
122145
123146 public RngService ( RngData rngData )
124147 {
125- _rngData = new InternalRngData { Data = rngData } ;
126- }
127-
128- public RngService ( IRngData data )
129- {
130- _rngData = data ;
148+ _rngData = rngData ;
131149 }
132150
133151 /// <inheritdoc />
134152 public int PeekRange ( int min , int max , bool maxInclusive = false )
135153 {
136- return Range ( min , max , CopyRngState ( Data . State ) , maxInclusive ) ;
154+ return Range ( min , max , CopyRngState ( _rngData . State ) , maxInclusive ) ;
137155 }
138156
139157 /// <inheritdoc />
140158 public floatP PeekRange ( floatP min , floatP max , bool maxInclusive = true )
141159 {
142- return Range ( min , max , CopyRngState ( Data . State ) , maxInclusive ) ;
160+ return Range ( min , max , CopyRngState ( _rngData . State ) , maxInclusive ) ;
143161 }
144162
145163 /// <inheritdoc />
146164 public int Range ( int min , int max , bool maxInclusive = false )
147165 {
148- var data = Data ;
149-
150- data . Count ++ ;
151-
152- Data = data ;
166+ _rngData . Count ++ ;
153167
154- return Range ( min , max , Data . State , maxInclusive ) ;
168+ return Range ( min , max , _rngData . State , maxInclusive ) ;
155169 }
156170
157171 /// <inheritdoc />
158172 public floatP Range ( floatP min , floatP max , bool maxInclusive = true )
159173 {
160- var data = Data ;
174+ _rngData . Count ++ ;
161175
162- data . Count ++ ;
163-
164- Data = data ;
165-
166- return Range ( min , max , Data . State , maxInclusive ) ;
176+ return Range ( min , max , _rngData . State , maxInclusive ) ;
167177 }
168178
169179 /// <inheritdoc />
170180 public void Restore ( int count )
171181 {
172- var data = Data ;
173-
174- data . Count = count ;
175- data . State = Restore ( count , Data . Seed ) ;
176-
177- Data = data ;
182+ _rngData . Count = count ;
183+ _rngData . State = Restore ( count , _rngData . Seed ) ;
178184 }
179185
180186 /// <summary>
@@ -254,6 +260,21 @@ public static int[] CopyRngState(int[] state)
254260 return newState ;
255261 }
256262
263+ /// <summary>
264+ /// Creates a new instance of <see cref="RngData"/> with the given <paramref name="seed"/>.
265+ /// </summary>
266+ /// <param name="seed">The seed value for the RNG.</param>
267+ /// <returns>A new instance of <see cref="RngData"/> with the given <paramref name="seed"/> and an initial count of 0.</returns>
268+ public static RngData CreateRngData ( int seed )
269+ {
270+ return new RngData
271+ {
272+ Seed = seed ,
273+ Count = 0 ,
274+ State = GenerateRngState ( seed )
275+ } ;
276+ }
277+
257278 /// <summary>
258279 /// Generates a completely new state rng state based on the given <paramref name="seed"/>.
259280 /// Based on the publish work of D.E. Knuth <see cref="https://www.informit.com/articles/article.aspx?p=2221790"/>
@@ -319,14 +340,5 @@ private static int NextNumber(int[] rndState)
319340
320341 return ret ;
321342 }
322-
323- /// <summary>
324- /// Used only in the scope of this service in case that no class is passed into the object
325- /// </summary>
326- private class InternalRngData : IRngData
327- {
328- /// <inheritdoc />
329- public RngData Data { get ; set ; }
330- }
331343 }
332344}
0 commit comments