1
0
mirror of https://github.com/lidgren/lidgren-network-gen3.git synced 2026-05-06 02:11:06 +09:00
Files
lidgren-network-gen3/Lidgren.Network/NetRandom.cs
lidgren 54ff6f1c37 Changed target framework to 4.5.1 for all projects
Changed some minor things after running .net portability analyzer
Fixed a bunch of warnings (mostly CLS compliance)
2014-08-10 09:27:36 +00:00

163 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
namespace Lidgren.Network
{
/// <summary>
/// NetRandom base class
/// </summary>
public abstract class NetRandom : Random
{
public static NetRandom Instance = new MWCRandom();
private const double c_realUnitInt = 1.0 / ((double)int.MaxValue + 1.0);
public NetRandom()
{
Initialize(NetRandomSeed.GetUInt32());
}
public NetRandom(int seed)
{
Initialize((uint)seed);
}
[CLSCompliant(false)]
public virtual void Initialize(uint seed)
{
// should be abstract, but non-CLS compliant methods can't be abstract!
throw new NotImplementedException("Implement this in inherited classes");
}
/// <summary>
/// Generates a random value from UInt32.MinValue to UInt32.MaxValue, inclusively
/// </summary>
[CLSCompliant(false)]
public virtual uint NextUInt32()
{
// should be abstract, but non-CLS compliant methods can't be abstract!
throw new NotImplementedException("Implement this in inherited classes");
}
/// <summary>
/// Generates a random value that is >= 0 and < Int32.MaxValue
/// </summary>
public override int Next()
{
var retval = (int)(0x7FFFFFFF & NextUInt32());
if (retval == 0x7FFFFFFF)
return NextInt32();
return retval;
}
/// <summary>
/// Generates a random value >= 0 and <= Int32.MaxValue (inclusively)
/// </summary>
public int NextInt32()
{
return (int)(0x7FFFFFFF & NextUInt32());
}
/// <summary>
/// Returns random value >= 0.0 and < 1.0
/// </summary>
public override double NextDouble()
{
return c_realUnitInt * NextInt32();
}
/// <summary>
/// Returns random value >= 0.0 and < 1.0
/// </summary>
protected override double Sample()
{
return c_realUnitInt * NextInt32();
}
/// <summary>
/// Returns random value >= 0.0f and < 1.0f
/// </summary>
public float NextSingle()
{
var retval = (float)(c_realUnitInt * NextInt32());
if (retval == 1.0f)
return NextSingle();
return retval;
}
/// <summary>
/// Returns a random value >= 0 and < maxValue
/// </summary>
public override int Next(int maxValue)
{
return (int)(NextDouble() * maxValue);
}
/// <summary>
/// Returns a random value >= minValue and < maxValue
/// </summary>
public override int Next(int minValue, int maxValue)
{
return minValue + (int)(NextDouble() * (double)(maxValue - minValue));
}
/// <summary>
/// Generates a random value between UInt64.MinValue to UInt64.MaxValue
/// </summary>
[CLSCompliant(false)]
public ulong NextUInt64()
{
ulong retval = NextUInt32();
retval |= NextUInt32() << 32;
return retval;
}
private uint m_boolValues;
private int m_nextBoolIndex;
/// <summary>
/// Returns true or false, randomly
/// </summary>
public bool NextBool()
{
if (m_nextBoolIndex >= 32)
{
m_boolValues = NextUInt32();
m_nextBoolIndex = 1;
}
var retval = ((m_boolValues >> m_nextBoolIndex) & 1) == 1;
m_nextBoolIndex++;
return retval;
}
/// <summary>
/// Fills all bytes from offset to offset + length in buffer with random values
/// </summary>
public virtual void NextBytes(byte[] buffer, int offset, int length)
{
int full = length / 4;
int ptr = offset;
for (int i = 0; i < full; i++)
{
uint r = NextUInt32();
buffer[ptr++] = (byte)r;
buffer[ptr++] = (byte)(r >> 8);
buffer[ptr++] = (byte)(r >> 16);
buffer[ptr++] = (byte)(r >> 24);
}
int rest = length - (full * 4);
for (int i = 0; i < rest; i++)
buffer[ptr++] = (byte)NextUInt32();
}
public override void NextBytes(byte[] buffer)
{
NextBytes(buffer, 0, buffer.Length);
}
}
}