#include "rng.h"

void rng_seed(rng_t *r, uint64_t seed) {
    r->state = 0u;
    r->inc = (seed << 1u) | 1u;
    rng_u32(r);
    r->state += seed;
    rng_u32(r);
}

uint32_t rng_u32(rng_t *r) {
    uint64_t old = r->state;
    r->state = old * 6364136223846793005ULL + r->inc;
    uint32_t xorshifted = (uint32_t)(((old >> 18u) ^ old) >> 27u);
    uint32_t rot = (uint32_t)(old >> 59u);
    return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}

int rng_range(rng_t *r, int lo, int hi) {
    if (hi <= lo) return lo;
    uint32_t span = (uint32_t)(hi - lo + 1);
    return lo + (int)(rng_u32(r) % span);
}

int rng_percent(rng_t *r, int pct) {
    return (int)(rng_u32(r) % 100) < pct;
}
