dumplog message history groundwork
[aNetHack.git] / src / rnd.c
blob8c15f22d457b4d88fc8785d4e00f6f04b946afe7
1 /* NetHack 3.6 rnd.c $NHDT-Date: 1446883921 2015/11/07 08:12:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.16 $ */
2 /* NetHack may be freely redistributed. See license for details. */
4 #include "hack.h"
6 /* "Rand()"s definition is determined by [OS]conf.h */
7 #if defined(LINT) && defined(UNIX) /* rand() is long... */
8 extern int NDECL(rand);
9 #define RND(x) (rand() % x)
10 #else /* LINT */
11 #if defined(UNIX) || defined(RANDOM)
12 #define RND(x) ((int) (Rand() % (long) (x)))
13 #else
14 /* Good luck: the bottom order bits are cyclic. */
15 #define RND(x) ((int) ((Rand() >> 3) % (x)))
16 #endif
17 #endif /* LINT */
19 /* 0 <= rn2(x) < x */
20 int
21 rn2(x)
22 register int x;
24 #ifdef BETA
25 if (x <= 0) {
26 impossible("rn2(%d) attempted", x);
27 return 0;
29 x = RND(x);
30 return x;
31 #else
32 return RND(x);
33 #endif
36 /* 0 <= rnl(x) < x; sometimes subtracting Luck;
37 good luck approaches 0, bad luck approaches (x-1) */
38 int
39 rnl(x)
40 register int x;
42 register int i, adjustment;
44 #ifdef BETA
45 if (x <= 0) {
46 impossible("rnl(%d) attempted", x);
47 return 0;
49 #endif
51 adjustment = Luck;
52 if (x <= 15) {
53 /* for small ranges, use Luck/3 (rounded away from 0);
54 also guard against architecture-specific differences
55 of integer division involving negative values */
56 adjustment = (abs(adjustment) + 1) / 3 * sgn(adjustment);
58 * 11..13 -> 4
59 * 8..10 -> 3
60 * 5.. 7 -> 2
61 * 2.. 4 -> 1
62 * -1,0,1 -> 0 (no adjustment)
63 * -4..-2 -> -1
64 * -7..-5 -> -2
65 * -10..-8 -> -3
66 * -13..-11-> -4
70 i = RND(x);
71 if (adjustment && rn2(37 + abs(adjustment))) {
72 i -= adjustment;
73 if (i < 0)
74 i = 0;
75 else if (i >= x)
76 i = x - 1;
78 return i;
81 /* 1 <= rnd(x) <= x */
82 int
83 rnd(x)
84 register int x;
86 #ifdef BETA
87 if (x <= 0) {
88 impossible("rnd(%d) attempted", x);
89 return 1;
91 #endif
92 x = RND(x) + 1;
93 return x;
96 /* d(N,X) == NdX == dX+dX+...+dX N times; n <= d(n,x) <= (n*x) */
97 int
98 d(n, x)
99 register int n, x;
101 register int tmp = n;
103 #ifdef BETA
104 if (x < 0 || n < 0 || (x == 0 && n != 0)) {
105 impossible("d(%d,%d) attempted", n, x);
106 return 1;
108 #endif
109 while (n--)
110 tmp += RND(x);
111 return tmp; /* Alea iacta est. -- J.C. */
114 /* 1 <= rne(x) <= max(u.ulevel/3,5) */
116 rne(x)
117 register int x;
119 register int tmp, utmp;
121 utmp = (u.ulevel < 15) ? 5 : u.ulevel / 3;
122 tmp = 1;
123 while (tmp < utmp && !rn2(x))
124 tmp++;
125 return tmp;
127 /* was:
128 * tmp = 1;
129 * while (!rn2(x))
130 * tmp++;
131 * return min(tmp, (u.ulevel < 15) ? 5 : u.ulevel / 3);
132 * which is clearer but less efficient and stands a vanishingly
133 * small chance of overflowing tmp
137 /* rnz: everyone's favorite! */
139 rnz(i)
140 int i;
142 #ifdef LINT
143 int x = i;
144 int tmp = 1000;
145 #else
146 register long x = (long) i;
147 register long tmp = 1000L;
148 #endif
150 tmp += rn2(1000);
151 tmp *= rne(4);
152 if (rn2(2)) {
153 x *= tmp;
154 x /= 1000;
155 } else {
156 x *= 1000;
157 x /= tmp;
159 return (int) x;
162 /*rnd.c*/