Random.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #include "core/Random.h"
  2. static const size_t M = 7;
  3. void initRandom(Random* r, u32 seed) {
  4. r->index = 0;
  5. for(size_t i = 0; i < ARRAY_LENGTH(r->data); i++) {
  6. r->data[i] = seed;
  7. seed = seed * 7 + 31;
  8. }
  9. }
  10. static void update(Random* r) {
  11. static const u32 map[2] = {0, 0x8EBFD028};
  12. static const size_t LENGTH = ARRAY_LENGTH(r->data);
  13. for(size_t i = 0; i < LENGTH - M; i++) {
  14. r->data[i] = r->data[i + M] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1];
  15. }
  16. for(size_t i = LENGTH - M; i < LENGTH; i++) {
  17. r->data[i] =
  18. r->data[i + (M - LENGTH)] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1];
  19. }
  20. r->index = 0;
  21. }
  22. #define LIMIT(value, min, max) (min + value % (max - min))
  23. static u32 next(Random* r) {
  24. if(r->index >= ARRAY_LENGTH(r->data)) {
  25. update(r);
  26. }
  27. u32 u = r->data[r->index++];
  28. u ^= (u << 7) & 0x2B5B2500;
  29. u ^= (u << 15) & 0xDB8B0000;
  30. u ^= (u >> 16);
  31. return u;
  32. }
  33. u32 randomU32(Random* r, u32 min, u32 exclusiveMax) {
  34. u32 u = next(r);
  35. return LIMIT(u, min, exclusiveMax);
  36. }
  37. i32 randomI32(Random* r, i32 min, i32 exclusiveMax) {
  38. i32 i = (i32)(next(r) >> 1);
  39. return LIMIT(i, min, exclusiveMax);
  40. }
  41. size_t randomSize(Random* r, size_t min, size_t exclusiveMax) {
  42. size_t s = next(r);
  43. return LIMIT(s, min, exclusiveMax);
  44. }
  45. bool randomBool(Random* r) {
  46. return next(r) & 1;
  47. }
  48. float randomFloat(Random* r) {
  49. u32 u = next(r);
  50. float f = (float)u / (float)0xFFFFFFF;
  51. return f >= 1.0f ? randomFloat(r) : f;
  52. }