From 943616e21a915fdedf2496a2dc4ae1262cef0e9a Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Wed, 30 Nov 2022 23:11:37 +0100 Subject: [PATCH] moved SeedSource to its own file and added Rotate --- MLEM/Misc/SeedSource.cs | 104 ++++++++++++++++++++++++++++++++++++++ MLEM/Misc/SingleRandom.cs | 96 +---------------------------------- 2 files changed, 105 insertions(+), 95 deletions(-) create mode 100644 MLEM/Misc/SeedSource.cs diff --git a/MLEM/Misc/SeedSource.cs b/MLEM/Misc/SeedSource.cs new file mode 100644 index 0000000..ba686ee --- /dev/null +++ b/MLEM/Misc/SeedSource.cs @@ -0,0 +1,104 @@ +using System; + +namespace MLEM.Misc { + /// + /// A seed source contains an value which can be used as a seed for a or . Seed sources feature a convenient way to add multiple seeds using , which will be sufficiently scrambled to be deterministically pseudorandom and combined into a single . + /// This struct behaves similarly to System.HashCode in many ways, with an important distinction being that 's scrambling procedure is not considered an implementation detail, and will stay consistent between process executions. + /// + /// + /// For example, a seed source can be used to create a new based on an object's x and y coordinates by combining them into a using . The values generated by the created using will then be determined by the specific pair of x and y values used. + /// + public readonly struct SeedSource { + + private readonly int? value; + + /// + /// Creates a new seed source from the given seed, which will be added automatically using . + /// + /// The initial seed to use. + public SeedSource(int seed) : this() { + this = this.Add(seed); + } + + /// + /// Creates a new seed source from the given set of seeds, which will be added automatically using . + /// + /// The initial seeds to use. + public SeedSource(params int[] seeds) : this() { + foreach (var seed in seeds) + this = this.Add(seed); + } + + private SeedSource(int? value) { + this.value = value; + } + + /// + /// Adds the given seed to this seed source's value and returns the result as a new seed source. + /// The algorithm used for adding involves various scrambling operations that sufficiently pseudo-randomize the seed and final value. + /// + /// The seed to add. + /// A new seed source with the seed added. + public SeedSource Add(int seed) { + return new SeedSource(new int?(SeedSource.Scramble(this.Get()) + SeedSource.Scramble(seed))); + } + + /// + /// Adds the given seed to this seed source's value and returns the result as a new seed source. + /// Floating point values are scrambled by invoking using a typecast version, followed by invoking using the decimal value multiplied by . + /// + /// The seed to add. + /// A new seed source with the seed added. + public SeedSource Add(float seed) { + return this.Add((int) seed).Add((seed - (int) seed) * int.MaxValue); + } + + /// + /// Adds the given seed to this seed source's value and returns the result as a new seed source. + /// Strings are scrambled by invoking using every character contained in the string, in order. + /// + /// The seed to add. + /// A new seed source with the seed added. + public SeedSource Add(string seed) { + var ret = this; + foreach (var c in seed) + ret = ret.Add(c); + return ret; + } + + /// + /// Returns a new seed source whose value is this seed source's value, but scrambled further. + /// In essence, this creates a new seed source whose value is determined by the current seed source. + /// + /// A new seed source with a rotated value. + public SeedSource Rotate() { + return new SeedSource(new int?(SeedSource.Scramble(this.Get()))); + } + + /// + /// Returns this seed source's seed value, which can then be used in or elsewhere. + /// + /// This seed source's value. + public int Get() { + return this.value ?? 1623487; + } + + /// + /// Returns a new instance using this source seed's value, retrieved using . + /// + /// A new using this seed source's value. + public Random Random() { + return new Random(this.Get()); + } + + private static int Scramble(int x) { + x += 84317; + x ^= x << 7; + x *= 207398809; + x ^= x << 17; + x *= 928511849; + return x; + } + + } +} diff --git a/MLEM/Misc/SingleRandom.cs b/MLEM/Misc/SingleRandom.cs index 3a10fc0..a5b08d0 100644 --- a/MLEM/Misc/SingleRandom.cs +++ b/MLEM/Misc/SingleRandom.cs @@ -1,6 +1,4 @@ -using System; - -namespace MLEM.Misc { +namespace MLEM.Misc { /// /// The SingleRandom class allows generating single, one-off pseudorandom numbers based on a seed or a . /// The types of numbers that can be generated are and , both of which can be generated with specific minimum and maximum values if desired. @@ -141,96 +139,4 @@ namespace MLEM.Misc { } } - - /// - /// A seed source contains an value which can be used as a seed for a or . Seed sources feature a convenient way to add multiple seeds using , which will be sufficiently scrambled to be deterministically semi-random and combined into a single . - /// This struct behaves similarly to System.HashCode in many ways, with an important distinction being that 's scrambling procedure is not considered an implementation detail, and will stay consistent between process executions. - /// - /// - /// For example, a seed source can be used to create a new based on an object's x and y coordinates by combining them into a using . The values generated by the created using will then be determined by the specific pair of x and y values used. - /// - public readonly struct SeedSource { - - private readonly int? value; - - /// - /// Creates a new seed source from the given seed, which will be added automatically using . - /// - /// The initial seed to use. - public SeedSource(int seed) : this() { - this = this.Add(seed); - } - - /// - /// Creates a new seed source from the given set of seeds, which will be added automatically using . - /// - /// The initial seeds to use. - public SeedSource(params int[] seeds) : this() { - foreach (var seed in seeds) - this = this.Add(seed); - } - - private SeedSource(int? value) { - this.value = value; - } - - /// - /// Adds the given seed to this seed source's value and returns the result as a new seed source. - /// The algorithm used for adding involves various scrambling operations that sufficiently semi-randomize the seed and final value. - /// - /// The seed to add. - /// A new seed source with the seed added. - public SeedSource Add(int seed) { - return new SeedSource(new int?(SeedSource.Scramble(this.Get()) + SeedSource.Scramble(seed))); - } - - /// - /// Adds the given seed to this seed source's value and returns the result as a new seed source. - /// Floating point values are scrambled by invoking using a typecast version, followed by invoking using the decimal value multiplied by . - /// - /// The seed to add. - /// A new seed source with the seed added. - public SeedSource Add(float seed) { - return this.Add((int) seed).Add((seed - (int) seed) * int.MaxValue); - } - - /// - /// Adds the given seed to this seed source's value and returns the result as a new seed source. - /// Strings are scrambled by invoking using every character contained in the string, in order. - /// - /// The seed to add. - /// A new seed source with the seed added. - public SeedSource Add(string seed) { - var ret = this; - foreach (var c in seed) - ret = ret.Add(c); - return ret; - } - - /// - /// Returns this seed source's seed value, which can then be used in or elsewhere. - /// - /// This seed source's value. - public int Get() { - return this.value ?? 1623487; - } - - /// - /// Returns a new instance using this source seed's value, retrieved using . - /// - /// A new using this seed source's value. - public Random Random() { - return new Random(this.Get()); - } - - private static int Scramble(int x) { - x += 84317; - x ^= x << 7; - x *= 207398809; - x ^= x << 17; - x *= 928511849; - return x; - } - - } }