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*/