Fandom

Wikihack

Source:Rnd.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Below is the full text to src/rnd.c from NetHack 3.4.3. To link to a particular line, write [[rnd.c#line123]], for example.

This file contains the functions that power NetHack's RNG.

LicenseEdit

1.    /*	SCCS Id: @(#)rnd.c	3.4	1996/02/07	*/
2.    /* NetHack may be freely redistributed.  See license for details. */
3.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.

Top of fileEdit

4.    #include "hack.h"
5.    
6.    /* "Rand()"s definition is determined by [OS]conf.h */

See, for example, unixconf.h#line303.

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.   


The rest of the file does not worry about which implementation of Rand() is used, instead using the macro RND(x).

rn2Edit

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


As line 22's comment suggests, rn2(x) returns an integer greater than or equal to zero and less than x.

This is used in the game in situations requiring a 50/50 chance of an event occurring: rn2(2) outputs 0 or 1 with equal probability.

rnlEdit

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

rnl(x) is the same as rn2, with a chance of a proportion of your Luck being subtracted from the result. This means very lucky characters tend to see lower values and very unlucky characters tend to see higher values.

In-game, this is used to make saving throws against your Luck. For example, blessed armor has a saving throw against being eroded by a trap: if rnl(4) is zero, the armor escapes unscathed[1][2][3]:

First, i is a random integer from 0 to 3. A very lucky character (with +13 Luck) has a rn2(37) chance (36 in 37 ~= 97%) of this being reduced by Luck/3, which in this case rounds to 4. i cannot be reduced below 0, so it is set to 0. So the other 1 time in 37 there will be a 25% chance of i being 0. In total, that's a 145/148 chance (~=98%) that the armor will not be eroded.

In the worst case scenario (a very unlucky character with -13 Luck) there is a 251/252 (~=99.6%) of the armor being eroded.

Moral: keep your Luck high.

rndEdit

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

rnd(x) returns an integer from 1 to x, inclusive. This simulates the roll of an x-sided die.

dEdit

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

File:3d6.svg

d is NetHack's implementation of D notation from D&D. d(n,x) is equivalent to ndx (e.g. d(3,6) is like 3d6). This simulates the roll of n x-sided dice.

"Alea iacta est" is Latin for "the die is cast". "J.C." refers to Julius Caesar, from whom this quote originates.

rneEdit

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.  

File:Rne3.svg

rne returns an exponentially weighted random integer from 1 to a number depending on your experience level. It is used in-game for deciding the enchantment of randomly generated items.

rnzEdit

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

File:Rnz100.svg

rnz produces a very strange distribution and is used for calculating prayer timeouts, among other things.

See Also Edit

hack.h#line291 - rn1(x,y) #define

Source code referencesEdit

  1. trap.c#line162
  2. trap.c#line2666
  3. trap.c#line2723

Also on Fandom

Random Wiki