OSDN Git Service

add translation
[jnethack/source.git] / src / rnd.c
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. */
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 /* 0 <= rn2(x) < x */
20 int
21 rn2(x)
22 register int x;
23 {
24 #ifdef BETA
25     if (x <= 0) {
26         impossible("rn2(%d) attempted", x);
27         return 0;
28     }
29     x = RND(x);
30     return x;
31 #else
32     return RND(x);
33 #endif
34 }
35
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;
41 {
42     register int i, adjustment;
43
44 #ifdef BETA
45     if (x <= 0) {
46         impossible("rnl(%d) attempted", x);
47         return 0;
48     }
49 #endif
50
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);
57         /*
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
67          */
68     }
69
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;
77     }
78     return i;
79 }
80
81 /* 1 <= rnd(x) <= x */
82 int
83 rnd(x)
84 register int x;
85 {
86 #ifdef BETA
87     if (x <= 0) {
88         impossible("rnd(%d) attempted", x);
89         return 1;
90     }
91 #endif
92     x = RND(x) + 1;
93     return x;
94 }
95
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;
100 {
101     register int tmp = n;
102
103 #ifdef BETA
104     if (x < 0 || n < 0 || (x == 0 && n != 0)) {
105         impossible("d(%d,%d) attempted", n, x);
106         return 1;
107     }
108 #endif
109     while (n--)
110         tmp += RND(x);
111     return tmp; /* Alea iacta est. -- J.C. */
112 }
113
114 /* 1 <= rne(x) <= max(u.ulevel/3,5) */
115 int
116 rne(x)
117 register int x;
118 {
119     register int tmp, utmp;
120
121     utmp = (u.ulevel < 15) ? 5 : u.ulevel / 3;
122     tmp = 1;
123     while (tmp < utmp && !rn2(x))
124         tmp++;
125     return tmp;
126
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
134      */
135 }
136
137 /* rnz: everyone's favorite! */
138 int
139 rnz(i)
140 int i;
141 {
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
149
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;
158     }
159     return (int) x;
160 }
161
162 /*rnd.c*/