00001 #ifndef RANDOM_H
00002 #define RANDOM_H
00003
00004 #include "rng.h"
00005
00006 #include <map>
00007 #include <vector>
00008
00009 bool coinflip();
00010 int div_rand_round(int num, int den);
00011 int div_round_up(int num, int den);
00012 bool one_chance_in(int a_million);
00013 bool x_chance_in_y(int x, int y);
00014 int random2(int max);
00015 int maybe_random2(int x, bool random_factor);
00016 int maybe_roll_dice(int num, int size, bool random);
00017 int random_range(int low, int high);
00018 int random_range(int low, int high, int nrolls);
00019 const char* random_choose_string(const char* first, ...);
00020 int random_choose(int first, ...);
00021 int random_choose_weighted(int weight, int first, ...);
00022
00023 int random2avg(int max, int rolls);
00024 int bestroll(int max, int rolls);
00025 int random2limit(int max, int limit);
00026 int binomial_generator(unsigned n_trials, unsigned trial_prob);
00027 int fuzz_value(int val, int lowfuzz, int highfuzz, int naverage = 2);
00028 int roll_dice(int num, int size);
00029
00030 struct dice_def
00031 {
00032 int num;
00033 int size;
00034
00035 dice_def(int n = 0, int s = 0) : num(n), size(s) {}
00036 int roll() const;
00037 };
00038
00039 dice_def calc_dice(int num_dice, int max_damage);
00040 void scale_dice(dice_def &dice, int threshold = 24);
00041
00042 class rng_save_excursion
00043 {
00044 public:
00045 rng_save_excursion(long seed) { push_rng_state(); seed_rng(seed); }
00046 rng_save_excursion() { push_rng_state(); }
00047 ~rng_save_excursion() { pop_rng_state(); }
00048 };
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 class defer_rand
00073 {
00074 std::vector<unsigned long> bits;
00075 std::map<int, defer_rand> children;
00076
00077 bool x_chance_in_y_contd(int x, int y, int index);
00078 public:
00079
00080
00081
00082 bool x_chance_in_y(int x, int y) { return x_chance_in_y_contd(x,y,0); }
00083 bool one_chance_in(int a_million) { return x_chance_in_y(1,a_million); }
00084 int random2(int maxp1);
00085
00086 int random_range(int low, int high);
00087 int random2avg(int max, int rolls);
00088
00089 defer_rand& operator[] (int i);
00090 };
00091
00092 template<typename Iterator>
00093 int choose_random_weighted(Iterator beg, const Iterator end)
00094 {
00095 ASSERT(beg < end);
00096
00097 #ifdef DEBUG
00098 int times_set = 0;
00099 #endif
00100
00101 int totalweight = 0;
00102 int count = 0, result = 0;
00103 while (beg != end)
00104 {
00105 totalweight += *beg;
00106 if (random2(totalweight) < *beg)
00107 {
00108 result = count;
00109 #ifdef DEBUG
00110 times_set++;
00111 #endif
00112 }
00113 ++count;
00114 ++beg;
00115 }
00116 #ifdef DEBUG
00117 ASSERT(times_set > 0);
00118 #endif
00119 return result;
00120 }
00121
00122 #endif