Random is a tiny library that provides a convenient API to generate any number of random outcomes based on a provided seed.
First, it uses the seed bytes directly, so the results are as random as the provided seed. This gives to your disposal up to 8 u32 integers (or equivalent in other types) that are strongly random.
Once all bytes are used the first time - it shuffles them by a simple algorithm that guarantees to produce a unique new pseudo-random sequence of bytes for at least 420 reuse cycles. This should be enough for any practical application inside a Scrypto component.
All methods return results that are uniformly distributed within limits decided either by the data type or by the provided arguments.
API reference
/// Instantiate a new Random. Seed length must be a multiple of 4.pubfnnew(seed:&Vec<u8>)->Random
/// Returns `true` or `false`.pubfnnext_bool(&mutself)->bool
/// Returns a random number of size T (u8, u16, u32, u64, usize).pubfnnext_int<T>(&mutself)->TwhereT:Num
/// Returns a random number in the range [min, max).pubfnin_range<T>(&mutself,min:T,max:T)->TwhereT:Num
/// Returns a random number in the range [0, max). For example, `roll(3)` will return one of [0, 1, 2].pubfnroll<T>(&mutself,max:T)->TwhereT:Num
Usage
First, you add a dependency to your `Cargo.toml` (see the latest revision in the examples repo):
Then you can instantiate and use it inside your callback:
use random::Random;
// ....
let mut random: Random = Random::new(&random_seed);
let random_bool = random.next_bool();
let random_byte = random.next_int::<u8>();
let random_int = random.next_int::<u32>();
// ....
let random_digit = random.roll::<u32>(10);
let random_damage = random.in_range::<u16>(200, );
// Hit with a 0.15% chance:
if random.roll(10000) < 15 {
// hit
}
// 3 different outcomes with chances of 0.1%, 9.9%, and 90% respectively:
let dice = random.roll(1000);
if dice < 1 {
// A [0.1% chance]
} else if dice < 100 {
// B [A + B has 10% chance]
} else {
// C
}
// Hatching period of 1000-2000 minutes, with the average being `(1000+2000)/2=1500`:
let period = random.in_range(1000, 2001);
// Coin flip (50/50 chance):
if random.next_bool() {
// A
} else {
// B
}