random.hpp 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. // Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #ifndef RANDOM_HPP
  4. #define RANDOM_HPP
  5. #include <type_traits>
  6. #include <random>
  7. #include "cbasetypes.hpp"
  8. inline std::random_device device;
  9. inline std::mt19937 generator = std::mt19937(device());
  10. int32 rnd(void);// [0, SINT32_MAX]
  11. /*
  12. * Generates a random number in the interval [min, max]
  13. * @return random number
  14. */
  15. template <typename T>
  16. typename std::enable_if<std::is_integral<T>::value, T>::type rnd_value(T min, T max) {
  17. if (min > max) {
  18. std::swap(min, max);
  19. }
  20. std::uniform_int_distribution<T> dist(min, max);
  21. return dist(generator);
  22. }
  23. /*
  24. * Simulates a chance based on a given probability
  25. * @return true if succeeded / false if it didn't
  26. */
  27. template <typename T>
  28. typename std::enable_if<std::is_integral<T>::value, bool>::type rnd_chance(T chance, T base) {
  29. return rnd_value<T>(1, base) <= chance;
  30. }
  31. /*
  32. * Simulates a chance based on a given probability
  33. * This considers the official inaccuracy where a random value between 0 and 20000 is generated first
  34. * and the taken modulo to the base. That means there's always an increased chance that the result is 0.
  35. * For example if base is 10000, there is a 3/20001 chance that the value is 0 (0, 10000 and 20000).
  36. * @return true if succeeded / false if it didn't
  37. */
  38. template <typename T>
  39. typename std::enable_if<std::is_integral<T>::value, bool>::type rnd_chance_official(T chance, T base) {
  40. return rnd_value<T>(0, 20000)%base < chance;
  41. }
  42. #endif /* RANDOM_HPP */