1 /*
2  * PROPRIETARY INFORMATION.  This software is proprietary to POWDER
3  * Development, and is not to be reproduced, transmitted, or disclosed
4  * in any way without written permission.
5  *
6  * Produced by:	Jeff Lait
7  *
8  *      	POWDER Development
9  *
10  * NAME:        rand.h ( POWDER Library, C++ )
11  *
12  * COMMENTS:
13  * 	All the good old random number routines that form the
14  * 	backbone of any Roguelike.
15  */
16 
17 #ifndef __rand_h__
18 #define __rand_h__
19 
20 struct DICE
21 {
22     u16		myNumdie, mySides;
23     s16		myBonus;
24 };
25 
26 // Used to generate our percentile table.
27 #if 0
28 void rand_print();
29 #endif
30 
31 void rand_pushstate();
32 void rand_popstate();
33 
34 // A safe way to push/pop the state inside a function.
35 class RAND_STATEPUSH
36 {
37 public:
RAND_STATEPUSH()38     RAND_STATEPUSH() { rand_pushstate(); }
~RAND_STATEPUSH()39     ~RAND_STATEPUSH() { rand_popstate(); }
40 };
41 
42 // Needs to be called once.
43 void rand_init();
44 
45 // Random in inclusive range.
46 int rand_range(int min, int max);
47 
48 // Random from 0..num-1
49 int rand_choice(int num);
50 
51 // Giving a null terminated list of strings, pick one of the strings
52 // at random
53 const char *rand_string(const char **stringlist);
54 
55 // Rolls the specific number sided die.  The reroll count
56 // is how many rerolls you get.  Largest is returned.
57 // Result is between 1..num, unless num is 0, in which case it is 0,
58 // or negative, in which case -1..-num.
59 // Negative reroll means you get rerolls but the LEAST is returned.
60 int rand_roll(int sides, int reroll = 0);
61 
62 // Returns the expected value of the rand_roll function, multiplied
63 // by the given scale, rounded to nearest.
64 int rand_rollMean(int sides, int reroll, int scale);
65 
66 // Roll numdieDsides + bonus
67 int rand_dice(int numdie, int sides, int bonus);
68 int rand_dice(const DICE &dice, int multiplier = 1);
69 // Returns the expected result from rolling the dice.
70 int rand_diceMean(const DICE &dice, int multiplier = 1);
71 
72 // Returns the current seed.
73 long rand_getseed();
74 // Sets the seed...
75 void rand_setseed(long seed);
76 
77 // Returns true percentage % of the time.
78 bool rand_chance(int percentage);
79 
80 // Returns -1 or 1.
81 int  rand_sign();
82 
83 // Initializes dx & dy, only one of which is non-zero.
84 void	rand_direction(int &dx, int &dy);
85 
86 // Initializes dx & dy, both of which are not zero.
87 void	rand_eightwaydirection(int &dx, int &dy);
88 
89 // Given a direction from 0..3, returns the dx,dy pair for that direction.
90 void	getDirection(int dir, int &dx, int &dy);
91 
92 // Given an angle 0..7, returns dx, dy pair.
93 void	rand_angletodir(int angle, int &dx, int &dy);
94 // Given a dx & dy, returns the angle.
95 int	rand_dirtoangle(int dx, int dy);
96 
97 // Shuffles the given set of numbers...
98 void	rand_shuffle(u8 *set, int n);
99 void	rand_shuffle(int *set, int n);
100 
101 unsigned int	rand_wanginthash(unsigned int key);
102 unsigned int	rand_hashstring(const char *s);
103 
104 // Never use this as floats are attrociously slow on GBA
105 double rand_double();
106 
107 // Builds a random player name
108 void		rand_name(char *text, int len);
109 
110 // Some standard methods...
111 #ifndef MIN
112 #define MIN(a, b) ((a) < (b) ? (a) : (b))
113 #endif
114 #ifndef MAX
115 #define MAX(a, b) ((a) > (b) ? (a) : (b))
116 #endif
117 #ifndef BOUND
118 #define BOUND(val, low, high) MAX(MIN(val, high), low)
119 #endif
120 #ifndef SIGN
121 #define SIGN(a) ((a) < 0 ? -1 : (a) > 0 ? 1 : 0)
122 #endif
123 #ifndef ABS
124 #define ABS(a) ((a) < 0 ? -(a) : (a))
125 #endif
126 
127 // Useful to iterate over all directions.
128 #define FORALL_4DIR(dx, dy) \
129     for (int lcl_angle = 0; getDirection(lcl_angle, dx, dy), lcl_angle < 4; lcl_angle++)
130 
131 #define FORALL_8DIR(dx, dy) \
132     for (int lcl_angle = 0; rand_angletodir(lcl_angle, dx, dy), lcl_angle < 8; lcl_angle++)
133 
134 #endif
135