/src/z-rand.c

https://bitbucket.org/ekolis/jackband · C · 589 lines · 258 code · 113 blank · 218 comment · 35 complexity · b9584478f1b37cc65b0db5926a38f721 MD5 · raw file

  1. /*
  2. * File: z-rand.c
  3. * Purpose: A simple RNG for Angband
  4. *
  5. * Copyright (c) 1997 Ben Harrison, Randy Hutson
  6. *
  7. * This work is free software; you can redistribute it and/or modify it
  8. * under the terms of either:
  9. *
  10. * a) the GNU General Public License as published by the Free Software
  11. * Foundation, version 2, or
  12. *
  13. * b) the "Angband licence":
  14. * This software may be copied and distributed for educational, research,
  15. * and not for profit purposes provided that this copyright and statement
  16. * are included in all such copies. Other copyrights may also apply.
  17. */
  18. #include "z-rand.h"
  19. /*
  20. * This file provides an optimized random number generator.
  21. *
  22. *
  23. * This code provides both a "quick" random number generator (4 bytes of
  24. * state), and a "decent" random number generator (256 bytes of state),
  25. * both available in two flavors, first, the simple "mod" flavor, which
  26. * is fast, but slightly biased at high values, and second, the simple
  27. * "div" flavor, which is less fast (and potentially non-terminating)
  28. * but which is not biased and is much less subject to non-randomness
  29. * problems in the low bits. Note the "randint0()" macro in "z-rand.h",
  30. * which must specify a "default" flavor.
  31. *
  32. * Note the use of the "simple" RNG, first you activate it via
  33. * "Rand_quick = TRUE" and "Rand_value = seed" and then it is used
  34. * automatically used instead of the "complex" RNG, and when you are
  35. * done, you de-activate it via "Rand_quick = FALSE" or choose a new
  36. * seed via "Rand_value = seed".
  37. *
  38. *
  39. * This (optimized) random number generator is based loosely on the old
  40. * "random.c" file from Berkeley but with some major optimizations and
  41. * algorithm changes. See below for more details.
  42. */
  43. /*
  44. * Random Number Generator -- Linear Congruent RNG
  45. */
  46. #define LCRNG(X) ((X) * 1103515245 + 12345)
  47. /*
  48. * Use the "simple" LCRNG
  49. */
  50. bool Rand_quick = TRUE;
  51. /*
  52. * Current "value" of the "simple" RNG
  53. */
  54. u32b Rand_value;
  55. /*
  56. * Current "index" for the "complex" RNG
  57. */
  58. u16b Rand_place;
  59. /*
  60. * Current "state" table for the "complex" RNG
  61. */
  62. u32b Rand_state[RAND_DEG];
  63. /*
  64. * Initialize the "complex" RNG using a new seed
  65. */
  66. void Rand_state_init(u32b seed)
  67. {
  68. int i, j;
  69. /* Seed the table */
  70. Rand_state[0] = seed;
  71. /* Propagate the seed */
  72. for (i = 1; i < RAND_DEG; i++) Rand_state[i] = LCRNG(Rand_state[i-1]);
  73. /* Cycle the table ten times per degree */
  74. for (i = 0; i < RAND_DEG * 10; i++)
  75. {
  76. /* Acquire the next index */
  77. j = Rand_place + 1;
  78. if (j == RAND_DEG) j = 0;
  79. /* Update the table, extract an entry */
  80. Rand_state[j] += Rand_state[Rand_place];
  81. /* Advance the index */
  82. Rand_place = j;
  83. }
  84. }
  85. /*
  86. * Extract a "random" number from 0 to m-1, via "division"
  87. *
  88. * This method selects "random" 28-bit numbers, and then uses
  89. * division to drop those numbers into "m" different partitions,
  90. * plus a small non-partition to reduce bias, taking as the final
  91. * value the first "good" partition that a number falls into.
  92. *
  93. * This method has no bias, and is much less affected by patterns
  94. * in the "low" bits of the underlying RNG's.
  95. */
  96. u32b Rand_div(u32b m)
  97. {
  98. u32b r, n;
  99. /* Division by zero will result if m is larger than 0x10000000 */
  100. assert(m <= 0x10000000);
  101. /* Hack -- simple case */
  102. if (m <= 1) return (0);
  103. /* Partition size */
  104. n = (0x10000000 / m);
  105. /* Use a simple RNG */
  106. if (Rand_quick)
  107. {
  108. /* Wait for it */
  109. while (1)
  110. {
  111. /* Cycle the generator */
  112. r = (Rand_value = LCRNG(Rand_value));
  113. /* Mutate a 28-bit "random" number */
  114. r = ((r >> 4) & 0x0FFFFFFF) / n;
  115. /* Done */
  116. if (r < m) break;
  117. }
  118. }
  119. /* Use a complex RNG */
  120. else
  121. {
  122. /* Wait for it */
  123. while (1)
  124. {
  125. int j;
  126. /* Acquire the next index */
  127. j = Rand_place + 1;
  128. if (j == RAND_DEG) j = 0;
  129. /* Update the table, extract an entry */
  130. r = (Rand_state[j] += Rand_state[Rand_place]);
  131. /* Hack -- extract a 28-bit "random" number */
  132. r = ((r >> 4) & 0x0FFFFFFF) / n;
  133. /* Advance the index */
  134. Rand_place = j;
  135. /* Done */
  136. if (r < m) break;
  137. }
  138. }
  139. /* Use the value */
  140. return (r);
  141. }
  142. /*
  143. * The number of entries in the "Rand_normal_table"
  144. */
  145. #define RANDNOR_NUM 256
  146. /*
  147. * The standard deviation of the "Rand_normal_table"
  148. */
  149. #define RANDNOR_STD 64
  150. /*
  151. * The normal distribution table for the "Rand_normal()" function (below)
  152. */
  153. static s16b Rand_normal_table[RANDNOR_NUM] =
  154. {
  155. 206, 613, 1022, 1430, 1838, 2245, 2652, 3058,
  156. 3463, 3867, 4271, 4673, 5075, 5475, 5874, 6271,
  157. 6667, 7061, 7454, 7845, 8234, 8621, 9006, 9389,
  158. 9770, 10148, 10524, 10898, 11269, 11638, 12004, 12367,
  159. 12727, 13085, 13440, 13792, 14140, 14486, 14828, 15168,
  160. 15504, 15836, 16166, 16492, 16814, 17133, 17449, 17761,
  161. 18069, 18374, 18675, 18972, 19266, 19556, 19842, 20124,
  162. 20403, 20678, 20949, 21216, 21479, 21738, 21994, 22245,
  163. 22493, 22737, 22977, 23213, 23446, 23674, 23899, 24120,
  164. 24336, 24550, 24759, 24965, 25166, 25365, 25559, 25750,
  165. 25937, 26120, 26300, 26476, 26649, 26818, 26983, 27146,
  166. 27304, 27460, 27612, 27760, 27906, 28048, 28187, 28323,
  167. 28455, 28585, 28711, 28835, 28955, 29073, 29188, 29299,
  168. 29409, 29515, 29619, 29720, 29818, 29914, 30007, 30098,
  169. 30186, 30272, 30356, 30437, 30516, 30593, 30668, 30740,
  170. 30810, 30879, 30945, 31010, 31072, 31133, 31192, 31249,
  171. 31304, 31358, 31410, 31460, 31509, 31556, 31601, 31646,
  172. 31688, 31730, 31770, 31808, 31846, 31882, 31917, 31950,
  173. 31983, 32014, 32044, 32074, 32102, 32129, 32155, 32180,
  174. 32205, 32228, 32251, 32273, 32294, 32314, 32333, 32352,
  175. 32370, 32387, 32404, 32420, 32435, 32450, 32464, 32477,
  176. 32490, 32503, 32515, 32526, 32537, 32548, 32558, 32568,
  177. 32577, 32586, 32595, 32603, 32611, 32618, 32625, 32632,
  178. 32639, 32645, 32651, 32657, 32662, 32667, 32672, 32677,
  179. 32682, 32686, 32690, 32694, 32698, 32702, 32705, 32708,
  180. 32711, 32714, 32717, 32720, 32722, 32725, 32727, 32729,
  181. 32731, 32733, 32735, 32737, 32739, 32740, 32742, 32743,
  182. 32745, 32746, 32747, 32748, 32749, 32750, 32751, 32752,
  183. 32753, 32754, 32755, 32756, 32757, 32757, 32758, 32758,
  184. 32759, 32760, 32760, 32761, 32761, 32761, 32762, 32762,
  185. 32763, 32763, 32763, 32764, 32764, 32764, 32764, 32765,
  186. 32765, 32765, 32765, 32766, 32766, 32766, 32766, 32767,
  187. };
  188. /*
  189. * Generate a random integer number of NORMAL distribution
  190. *
  191. * The table above is used to generate a psuedo-normal distribution,
  192. * in a manner which is much faster than calling a transcendental
  193. * function to calculate a true normal distribution.
  194. *
  195. * Basically, entry 64*N in the table above represents the number of
  196. * times out of 32767 that a random variable with normal distribution
  197. * will fall within N standard deviations of the mean. That is, about
  198. * 68 percent of the time for N=1 and 95 percent of the time for N=2.
  199. *
  200. * The table above contains a "faked" final entry which allows us to
  201. * pretend that all values in a normal distribution are strictly less
  202. * than four standard deviations away from the mean. This results in
  203. * "conservative" distribution of approximately 1/32768 values.
  204. *
  205. * Note that the binary search takes up to 16 quick iterations.
  206. */
  207. s16b Rand_normal(int mean, int stand)
  208. {
  209. s16b tmp;
  210. s16b offset;
  211. s16b low = 0;
  212. s16b high = RANDNOR_NUM;
  213. /* Paranoia */
  214. if (stand < 1) return (mean);
  215. /* Roll for probability */
  216. tmp = (s16b)randint0(32768);
  217. /* Binary Search */
  218. while (low < high)
  219. {
  220. int mid = (low + high) >> 1;
  221. /* Move right if forced */
  222. if (Rand_normal_table[mid] < tmp)
  223. {
  224. low = mid + 1;
  225. }
  226. /* Move left otherwise */
  227. else
  228. {
  229. high = mid;
  230. }
  231. }
  232. /* Convert the index into an offset */
  233. offset = (long)stand * (long)low / RANDNOR_STD;
  234. /* One half should be negative */
  235. if (randint0(100) < 50) return (mean - offset);
  236. /* One half should be positive */
  237. return (mean + offset);
  238. }
  239. /*
  240. * Extract a "random" number from 0 to m-1, using the "simple" RNG.
  241. *
  242. * This function should be used when generating random numbers in
  243. * "external" program parts like the main-*.c files. It preserves
  244. * the current RNG state to prevent influences on game-play.
  245. */
  246. u32b Rand_simple(u32b m)
  247. {
  248. static bool initialized = FALSE;
  249. static u32b simple_rand_value;
  250. bool old_rand_quick;
  251. u32b old_rand_value;
  252. u32b result;
  253. /* Save RNG state */
  254. old_rand_quick = Rand_quick;
  255. old_rand_value = Rand_value;
  256. /* Use "simple" RNG */
  257. Rand_quick = TRUE;
  258. if (initialized)
  259. {
  260. /* Use stored seed */
  261. Rand_value = simple_rand_value;
  262. }
  263. else
  264. {
  265. /* Initialize with new seed */
  266. Rand_value = time(NULL);
  267. initialized = TRUE;
  268. }
  269. /* Get a random number */
  270. result = randint0(m);
  271. /* Store the new seed */
  272. simple_rand_value = Rand_value;
  273. /* Restore RNG state */
  274. Rand_quick = old_rand_quick;
  275. Rand_value = old_rand_value;
  276. /* Use the value */
  277. return (result);
  278. }
  279. /*
  280. * Generates damage for "2d6" style dice rolls
  281. */
  282. int damroll(int num, int sides)
  283. {
  284. int i;
  285. int sum = 0;
  286. /* assert(sides > 0); */
  287. if (sides <= 0) return (0);
  288. for (i = 0; i < num; i++)
  289. sum += randint1(sides);
  290. return (sum);
  291. }
  292. /*
  293. * Calculation helper function for damroll
  294. */
  295. int damcalc(int num, int sides, aspect dam_aspect)
  296. {
  297. int val = 0;
  298. switch (dam_aspect)
  299. {
  300. case MAXIMISE:
  301. case EXTREMIFY:
  302. {
  303. val = num * sides;
  304. break;
  305. }
  306. case RANDOMISE:
  307. {
  308. val = damroll(num, sides);
  309. break;
  310. }
  311. case MINIMISE:
  312. {
  313. val = num;
  314. break;
  315. }
  316. case AVERAGE:
  317. {
  318. val = num * (sides + 1) / 2;
  319. break;
  320. }
  321. }
  322. return (val);
  323. }
  324. /**
  325. * Generates a random signed long integer X where `A` <= X <= `B`.
  326. * The integer X falls along a uniform distribution.
  327. *
  328. * Note that "rand_range(0, N-1)" == "randint0(N)".
  329. */
  330. int rand_range(int A, int B)
  331. {
  332. if (A == B) return A;
  333. assert(A < B);
  334. return A + (s32b)Rand_div(1 + B - A);
  335. }
  336. /*
  337. * Help determine an "enchantment bonus" for an object.
  338. *
  339. * To avoid floating point but still provide a smooth distribution of bonuses,
  340. * we simply round the results of division in such a way as to "average" the
  341. * correct floating point value.
  342. *
  343. * This function has been changed. It uses "Rand_normal()" to choose values
  344. * from a normal distribution, whose mean moves from zero towards the max as
  345. * the level increases, and whose standard deviation is equal to 1/4 of the
  346. * max, and whose values are forced to lie between zero and the max, inclusive.
  347. *
  348. * Since the "level" rarely passes 100 before Morgoth is dead, it is very
  349. * rare to get the "full" enchantment on an object, even a deep levels.
  350. *
  351. * It is always possible (albeit unlikely) to get the "full" enchantment.
  352. *
  353. * A sample distribution of values from "m_bonus(10, N)" is shown below:
  354. *
  355. * N 0 1 2 3 4 5 6 7 8 9 10
  356. * --- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
  357. * 0 66.37 13.01 9.73 5.47 2.89 1.31 0.72 0.26 0.12 0.09 0.03
  358. * 8 46.85 24.66 12.13 8.13 4.20 2.30 1.05 0.36 0.19 0.08 0.05
  359. * 16 30.12 27.62 18.52 10.52 6.34 3.52 1.95 0.90 0.31 0.15 0.05
  360. * 24 22.44 15.62 30.14 12.92 8.55 5.30 2.39 1.63 0.62 0.28 0.11
  361. * 32 16.23 11.43 23.01 22.31 11.19 7.18 4.46 2.13 1.20 0.45 0.41
  362. * 40 10.76 8.91 12.80 29.51 16.00 9.69 5.90 3.43 1.47 0.88 0.65
  363. * 48 7.28 6.81 10.51 18.27 27.57 11.76 7.85 4.99 2.80 1.22 0.94
  364. * 56 4.41 4.73 8.52 11.96 24.94 19.78 11.06 7.18 3.68 1.96 1.78
  365. * 64 2.81 3.07 5.65 9.17 13.01 31.57 13.70 9.30 6.04 3.04 2.64
  366. * 72 1.87 1.99 3.68 7.15 10.56 20.24 25.78 12.17 7.52 4.42 4.62
  367. * 80 1.02 1.23 2.78 4.75 8.37 12.04 27.61 18.07 10.28 6.52 7.33
  368. * 88 0.70 0.57 1.56 3.12 6.34 10.06 15.76 30.46 12.58 8.47 10.38
  369. * 96 0.27 0.60 1.25 2.28 4.30 7.60 10.77 22.52 22.51 11.37 16.53
  370. * 104 0.22 0.42 0.77 1.36 2.62 5.33 8.93 13.05 29.54 15.23 22.53
  371. * 112 0.15 0.20 0.56 0.87 2.00 3.83 6.86 10.06 17.89 27.31 30.27
  372. * 120 0.03 0.11 0.31 0.46 1.31 2.48 4.60 7.78 11.67 25.53 45.72
  373. * 128 0.02 0.01 0.13 0.33 0.83 1.41 3.24 6.17 9.57 14.22 64.07
  374. */
  375. s16b m_bonus(int max, int level)
  376. {
  377. int bonus, stand, extra, value;
  378. /* Paranoia -- enforce maximal "level" */
  379. if (level > MAX_DEPTH - 1) level = MAX_DEPTH - 1;
  380. /* The "bonus" moves towards the max */
  381. bonus = ((max * level) / MAX_DEPTH);
  382. /* Hack -- determine fraction of error */
  383. extra = ((max * level) % MAX_DEPTH);
  384. /* Hack -- simulate floating point computations */
  385. if (randint0(MAX_DEPTH) < extra) bonus++;
  386. /* The "stand" is equal to one quarter of the max */
  387. stand = (max / 4);
  388. /* Hack -- determine fraction of error */
  389. extra = (max % 4);
  390. /* Hack -- simulate floating point computations */
  391. if (randint0(4) < extra) stand++;
  392. /* Choose an "interesting" value */
  393. value = Rand_normal(bonus, stand);
  394. /* Enforce the minimum value */
  395. if (value < 0) return (0);
  396. /* Enforce the maximum value */
  397. if (value > max) return (max);
  398. /* Result */
  399. return (value);
  400. }
  401. /*
  402. * Calculation helper function for m_bonus
  403. */
  404. s16b m_bonus_calc(int max, int level, aspect bonus_aspect)
  405. {
  406. int val = 0;
  407. switch (bonus_aspect)
  408. {
  409. case EXTREMIFY:
  410. case MAXIMISE:
  411. {
  412. val = max;
  413. break;
  414. }
  415. case RANDOMISE:
  416. {
  417. val = m_bonus(max, level);
  418. break;
  419. }
  420. case MINIMISE:
  421. {
  422. val = 0;
  423. break;
  424. }
  425. case AVERAGE:
  426. {
  427. val = max * level / MAX_DEPTH;
  428. break;
  429. }
  430. }
  431. return (val);
  432. }
  433. /*
  434. * Calculation helper function for random_value structs
  435. */
  436. int randcalc(random_value v, int level, aspect rand_aspect)
  437. {
  438. int total;
  439. if (rand_aspect == EXTREMIFY)
  440. {
  441. int min, max;
  442. min = randcalc(v, level, MINIMISE);
  443. max = randcalc(v, level, MAXIMISE);
  444. if (abs(min) > abs(max))
  445. total = min;
  446. else
  447. total = max;
  448. }
  449. else
  450. {
  451. total = v.base +
  452. damcalc(v.dice, v.sides, rand_aspect) +
  453. m_bonus_calc(v.m_bonus, level, rand_aspect);
  454. }
  455. return total;
  456. }
  457. /*
  458. * Test to see if a value is within a random_value's range
  459. */
  460. bool randcalc_valid(random_value v, int test)
  461. {
  462. if (test < randcalc(v, 0, MINIMISE))
  463. return FALSE;
  464. if (test > randcalc(v, 0, MAXIMISE))
  465. return FALSE;
  466. return TRUE;
  467. }
  468. /*
  469. * Test to see if a random_value actually varies
  470. */
  471. bool randcalc_varies(random_value v)
  472. {
  473. if (randcalc(v, 0, MINIMISE) == randcalc(v, 0, MAXIMISE))
  474. return FALSE;
  475. return TRUE;
  476. }