diff --git a/src/external/rprand.h b/src/external/rprand.h index b8dc4a279..acdeac671 100644 --- a/src/external/rprand.h +++ b/src/external/rprand.h @@ -117,10 +117,10 @@ extern "C" { // Prevents name mangling of functions // Module Functions Declaration //---------------------------------------------------------------------------------- RPRANDAPI void rprand_set_seed(unsigned long long seed); // Set rprand_state for Xoshiro128**, seed is 64bit -RPRANDAPI unsigned int rprand_get_value(int min, int max); // Get random value within a range, min and max included +RPRANDAPI int rprand_get_value(int min, int max); // Get random value within a range, min and max included -RPRANDAPI unsigned int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates -RPRANDAPI void rprand_unload_sequence(unsigned int *sequence); // Unload pseudo-random numbers sequence +RPRANDAPI int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates +RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo-random numbers sequence #ifdef __cplusplus } @@ -136,7 +136,7 @@ RPRANDAPI void rprand_unload_sequence(unsigned int *sequence); // Unload pseudo #if defined(RPRAND_IMPLEMENTATION) -#include // Required for: calloc(), free() +#include // Required for: calloc(), free(), abs() #include // Required for data types: uint32_t, uint64_t //---------------------------------------------------------------------------------- @@ -174,33 +174,33 @@ void rprand_set_seed(unsigned long long seed) } // Get random value within a range, min and max included -unsigned int rprand_get_value(int min, int max) +int rprand_get_value(int min, int max) { - unsigned int value = rprand_xoshiro()%(max - min) + min; + int value = rprand_xoshiro()%(abs(max - min) + 1) + min; return value; } -// Load pseudo-random numbers sequence with no duplicates -unsigned int *rprand_load_sequence(unsigned int count, int min, int max) +// Load pseudo-random numbers sequence with no duplicates, min and max included +int *rprand_load_sequence(unsigned int count, int min, int max) { - unsigned int *sequence = NULL; + int *sequence = NULL; - if (count > (max - min)) + if (count > (abs(max - min) + 1)) { RPRAND_LOG("WARNING: Sequence count required is greater than range provided\n"); //count = (max - min); return sequence; } - sequence = (unsigned int *)RPRAND_CALLOC(count, sizeof(unsigned int)); + sequence = (int *)RPRAND_CALLOC(count, sizeof(int)); - uint32_t value = 0; + int value = 0; bool value_is_dup = false; for (int i = 0; i < count;) { - value = rprand_xoshiro()%(max - min) + min; + value = (rprand_xoshiro()%(abs(max - min) + 1)) + min; value_is_dup = false; for (int j = 0; j < i; j++) @@ -223,7 +223,7 @@ unsigned int *rprand_load_sequence(unsigned int count, int min, int max) } // Unload pseudo-random numbers sequence -void rprand_unload_sequence(unsigned int *sequence) +void rprand_unload_sequence(int *sequence) { RPRAND_FREE(sequence); sequence = NULL; diff --git a/src/raylib.h b/src/raylib.h index c732d8ef1..4a353a70f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1067,10 +1067,13 @@ RLAPI void SwapScreenBuffer(void); // Swap back b RLAPI void PollInputEvents(void); // Register all input events RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) -// Misc. functions +// Random values generation functions RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) +RLAPI int *LoadRandomSequence(unsigned int count, int min, int max); // Load random values sequence, no values repeated +RLAPI void UnloadRandomSequence(int *sequence); // Unload random values sequence +// Misc. functions RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) diff --git a/src/rcore.c b/src/rcore.c index ac5dea842..b09dffe67 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -1677,7 +1677,7 @@ void SetRandomSeed(unsigned int seed) #endif } -// Get a random value between min and max (both included) +// Get a random value between min and max included int GetRandomValue(int min, int max) { int value = 0; @@ -1695,6 +1695,7 @@ int GetRandomValue(int min, int max) // WARNING: Ranges higher than RAND_MAX will return invalid results // More specifically, if (max - min) > INT_MAX there will be an overflow, // and otherwise if (max - min) > RAND_MAX the random value will incorrectly never exceed a certain threshold + // NOTE: Depending on the library it can be as low as 32767 if ((unsigned int)(max - min) > (unsigned int)RAND_MAX) { TRACELOG(LOG_WARNING, "Invalid GetRandomValue() arguments, range should not be higher than %i", RAND_MAX); @@ -1705,6 +1706,55 @@ int GetRandomValue(int min, int max) return value; } +// Load random values sequence, no values repeated, min and max included +int *LoadRandomSequence(unsigned int count, int min, int max) +{ + int *values = NULL; + +#if defined(SUPPORT_RPRAND_GENERATOR) + rprand_load_sequence(count, min, max); +#else + if (count > (abs(max - min) + 1)) return values; + + values = (int *)RL_CALLOC(count, sizeof(int)); + + int value = 0; + bool dupValue = false; + + for (int i = 0; i < count;) + { + value = (rand()%(abs(max - min) + 1) + min); + dupValue = false; + + for (int j = 0; j < i; j++) + { + if (values[j] == value) + { + dupValue = true; + break; + } + } + + if (!dupValue) + { + values[i] = value; + i++; + } + } +#endif + return values; +} + +// Unload random values sequence +void UnloadRandomSequence(int *sequence) +{ +#if defined(SUPPORT_RPRAND_GENERATOR) + rprand_unload_sequence(sequence); +#else + RL_FREE(sequence); +#endif +} + // Takes a screenshot of current screen (saved a .png) void TakeScreenshot(const char *fileName) {