1    | /*	SCCS Id: @(#)rnd.c	3.3	96/02/07	*/
2    | /* NetHack may be freely redistributed.  See license for details. */
3    | 
4    | #include "hack.h"
5    | 
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 */
18   | 
19   | #ifdef OVL0
20   | 
21   | int
22   | rn2(x)		/* 0 <= rn2(x) < x */
23   | register int x;
24   | {
25   | #ifdef DEBUG
26   | 	if (x <= 0) {
27   | 		impossible("rn2(%d) attempted", x);
28   | 		return(0);
29   | 	}
30   | 	x = RND(x);
31   | 	return(x);
32   | #else
33   | 	return(RND(x));
34   | #endif
35   | }
36   | 
37   | #endif /* OVL0 */
38   | #ifdef OVLB
39   | 
40   | int
41   | rnl(x)		/* 0 <= rnl(x) < x; sometimes subtracting Luck */
42   | register int x;	/* good luck approaches 0, bad luck approaches (x-1) */
43   | {
44   | 	register int i;
45   | 
46   | #ifdef DEBUG
47   | 	if (x <= 0) {
48   | 		impossible("rnl(%d) attempted", x);
49   | 		return(0);
50   | 	}
51   | #endif
52   | 	i = RND(x);
53   | 
54   | 	if (Luck && rn2(50 - Luck)) {
55   | 	    i -= (x <= 15 && Luck >= -5 ? Luck/3 : Luck);
56   | 	    if (i < 0) i = 0;
57   | 	    else if (i >= x) i = x-1;
58   | 	}
59   | 
60   | 	return i;
61   | }
62   | 
63   | #endif /* OVLB */
64   | #ifdef OVL0
65   | 
66   | int
67   | rnd(x)		/* 1 <= rnd(x) <= x */
68   | register int x;
69   | {
70   | #ifdef DEBUG
71   | 	if (x <= 0) {
72   | 		impossible("rnd(%d) attempted", x);
73   | 		return(1);
74   | 	}
75   | 	x = RND(x)+1;
76   | 	return(x);
77   | #else
78   | 	return(RND(x)+1);
79   | #endif
80   | }
81   | 
82   | #endif /* OVL0 */
83   | #ifdef OVL1
84   | 
85   | int
86   | d(n,x)		/* n <= d(n,x) <= (n*x) */
87   | register int n, x;
88   | {
89   | 	register int tmp = n;
90   | 
91   | #ifdef DEBUG
92   | 	if (x < 0 || n < 0 || (x == 0 && n != 0)) {
93   | 		impossible("d(%d,%d) attempted", n, x);
94   | 		return(1);
95   | 	}
96   | #endif
97   | 	while(n--) tmp += RND(x);
98   | 	return(tmp); /* Alea iacta est. -- J.C. */
99   | }
100  | 
101  | #endif /* OVL1 */
102  | #ifdef OVLB
103  | 
104  | int
105  | rne(x)
106  | register int x;
107  | {
108  | 	register int tmp, utmp;
109  | 
110  | 	utmp = (u.ulevel < 15) ? 5 : u.ulevel/3;
111  | 	tmp = 1;
112  | 	while (tmp < utmp && !rn2(x))
113  | 		tmp++;
114  | 	return tmp;
115  | 
116  | 	/* was:
117  | 	 *	tmp = 1;
118  | 	 *	while(!rn2(x)) tmp++;
119  | 	 *	return(min(tmp,(u.ulevel < 15) ? 5 : u.ulevel/3));
120  | 	 * which is clearer but less efficient and stands a vanishingly
121  | 	 * small chance of overflowing tmp
122  | 	 */
123  | }
124  | 
125  | int
126  | rnz(i)
127  | int i;
128  | {
129  | #ifdef LINT
130  | 	int x = i;
131  | 	int tmp = 1000;
132  | #else
133  | 	register long x = i;
134  | 	register long tmp = 1000;
135  | #endif
136  | 	tmp += rn2(1000);
137  | 	tmp *= rne(4);
138  | 	if (rn2(2)) { x *= tmp; x /= 1000; }
139  | 	else { x *= 1000; x /= tmp; }
140  | 	return((int)x);
141  | }
142  | 
143  | #endif /* OVLB */
144  | 
145  | /*rnd.c*/