Create bare godot project
This commit is contained in:
119
FixPoint/IntRandom.cs
Normal file
119
FixPoint/IntRandom.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
|
||||
namespace MagmaEngine.Math;
|
||||
|
||||
/// <summary>
|
||||
/// Implements a XorShift* PRNG, with 64 bits of internal state.
|
||||
/// See http://en.wikipedia.org/wiki/Xorshift
|
||||
/// </summary>
|
||||
public struct SIntRandom
|
||||
{
|
||||
public SIntRandom(ulong seed)
|
||||
{
|
||||
if (seed == 0)
|
||||
throw new InvalidOperationException("Seed needs to be bigger than zero.");
|
||||
|
||||
m_Seed = seed;
|
||||
}
|
||||
|
||||
public ulong Next()
|
||||
{
|
||||
m_Seed ^= m_Seed >> 12;
|
||||
m_Seed ^= m_Seed << 25;
|
||||
m_Seed ^= m_Seed >> 27;
|
||||
return m_Seed * 2685821657736338717UL; // multiplier taken from wikipedia article on XorShift PRNGs
|
||||
}
|
||||
|
||||
public ulong Next(ulong upperLimit)
|
||||
{
|
||||
if (upperLimit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Next() % upperLimit;
|
||||
}
|
||||
|
||||
public FixPoint16 NextFixPoint16()
|
||||
{
|
||||
return new() { m_Value = (int)(Next() & 0xffffUL) };
|
||||
}
|
||||
|
||||
public int RandomizedRound(FixPoint16 value)
|
||||
{
|
||||
int ret = value.ToIntFloor();
|
||||
if (NextFixPoint16() < FixPoint16.Fract(value))
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public uint Next(uint upperLimit)
|
||||
{
|
||||
if (upperLimit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (uint)(Next() % upperLimit);
|
||||
}
|
||||
|
||||
public uint Next(uint lowerLimit, uint upperLimit)
|
||||
{
|
||||
if (upperLimit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lowerLimit == upperLimit)
|
||||
{
|
||||
return lowerLimit;
|
||||
}
|
||||
|
||||
return lowerLimit + (uint)(Next() % (upperLimit - lowerLimit));
|
||||
}
|
||||
|
||||
public int Next(int upperLimit)
|
||||
{
|
||||
if (upperLimit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int)(Next() % (uint)(upperLimit & 0x7fffffff));
|
||||
}
|
||||
|
||||
public int Next(int lowerLimit, int upperLimit)
|
||||
{
|
||||
if (upperLimit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lowerLimit == upperLimit)
|
||||
{
|
||||
return lowerLimit;
|
||||
}
|
||||
|
||||
return lowerLimit + (int)(Next() % (uint)((upperLimit - lowerLimit) & 0x7fffffff));
|
||||
}
|
||||
|
||||
public double NextDouble()
|
||||
{
|
||||
return Next(int.MaxValue) * (1.0 / int.MaxValue);
|
||||
}
|
||||
|
||||
public float NextSingle()
|
||||
{
|
||||
return (float)NextDouble();
|
||||
}
|
||||
|
||||
public override readonly string ToString()
|
||||
{
|
||||
return $"0x{m_Seed:X}";
|
||||
}
|
||||
|
||||
public readonly ulong Seed => m_Seed;
|
||||
|
||||
private ulong m_Seed;
|
||||
}
|
||||
Reference in New Issue
Block a user