rj-action-library/Runtime/Random/RandomEngine.cs

220 lines
4.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
public abstract class RandomEngine
{
public abstract float Next();
public float Value( float scalar )
{
return Next() * scalar;
}
public float Range( float a, float b)
{
return this.Next()*( b - a ) + a;
}
public float Polar()
{
return this.Next() * 2f - 1f;
}
public float Polar( float value )
{
return Polar() * value;
}
public bool Bool()
{
return this.Next() > 0.5f;
}
public bool Chance( float value )
{
return value / 100f >= Next();
}
public bool FlipCoin()
{
return Chance( 50f );
}
public float PercentageVariation( float variation )
{
var value = ( 100f - variation ) / 100f;
return Range( value, 1f / value );
}
public bool WithChanceOf( float value )
{
return ( this.Next() * 100 ) <= value ;
}
public Vector3 Between( Vector3 a, Vector3 b )
{
return a.Lerp( b, this.Next() );
}
public Color RandomHue( float saturation = 1f, float luminance = 0.5f)
{
var hue = Range( 0, 360 );
var color = new HSLColor( hue, saturation, luminance );
return color;
}
public Vector2 InRectangle( Vector2 min, Vector2 max )
{
var x = Mathf.Lerp( min.X, max.X, Next() );
var y = Mathf.Lerp( min.Y, max.Y, Next() );
return new Vector2( x, y );
}
public Vector3 InCube()
{
return new Vector3( Polar(), Polar(), Polar() );
}
public Vector3 InsideCube( float size )
{
return InCube() * ( size * 0.5f );
}
public Vector3 InsideSphere()
{
var inCube = InCube();
if ( inCube.LengthSquared() > 1 )
{
inCube = inCube.Normalized() * Next();
}
return inCube;
}
public Vector3 OnSphere( float size )
{
return OnSphere() * size;
}
public Vector3 OnSphere()
{
var dir = InsideSphere();
while ( dir.LengthSquared() == 0 )
{
dir = InsideSphere();
}
return dir;
}
public Vector3 InSphere( float size )
{
return InsideSphere() * ( size * 0.5f );
}
public int IntegerInclusive( int min, int max )
{
return (int) ( Mathf.Floor( this.Next() * ( max - min + 1 ) ) + min ) ;
}
public int IntegerInclusive( int max )
{
return IntegerInclusive( 0, max );
}
public int IntegerExclusive( int min, int max )
{
var nextValue = this.Next();
var randomValue = nextValue * ( max - min ) + min;
var value = (int) ( Mathf.Floor( randomValue ) );
return Mathf.Min( max - 1, value );
}
public int IntegerExclusive( int max )
{
return IntegerExclusive( 0, max );
}
public char From( string source )
{
var index = IntegerExclusive( source.Length );
return source[ index ];
}
public T From<T>( T[] array )
{
if ( array.Length == 0 )
{
return default ( T );
}
var index = IntegerExclusive( array.Length );
return array[ index ];
}
public T From<T>( HashSet<T> set )
{
var selectedIndex = IntegerExclusive( set.Count );
var currentIndex = 0;
foreach ( var e in set )
{
if ( selectedIndex == currentIndex )
{
return e;
}
currentIndex++;
}
return default( T );
}
public T FromValues<T>( T first, params T[] values )
{
if ( values.Length == 0 )
{
return first;
}
var index = IntegerExclusive( values.Length + 1 );
return index == 0 ? first : values[ index - 1 ];
}
public T From<T>( List<T> list )
{
if ( list.Count == 0 )
{
return default ( T );
}
var index = this.IntegerExclusive( 0, list.Count );
return list[ index ];
}
}
public abstract class SeedableRandomEngine:RandomEngine
{
public abstract void SetSeed( int number );
public abstract object GetSeedState();
public abstract void SetSeedState( object seedState );
}
}