rn2()/rnd() debugging

Finding bad calls to rn2(0) or rnd(0) should not be dependent upon
having DEBUGFILES=rnd.c, so switch from debugpline() to impossible().
This commit is contained in:
PatR
2015-11-07 00:12:09 -08:00
parent 464bb3a1f4
commit 7ddcf113f2

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 rnd.c $NHDT-Date: 1432512767 2015/05/25 00:12:47 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */ /* NetHack 3.6 rnd.c $NHDT-Date: 1446883921 2015/11/07 08:12:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.16 $ */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
#include "hack.h" #include "hack.h"
@@ -9,37 +9,42 @@ extern int NDECL(rand);
#define RND(x) (rand() % x) #define RND(x) (rand() % x)
#else /* LINT */ #else /* LINT */
#if defined(UNIX) || defined(RANDOM) #if defined(UNIX) || defined(RANDOM)
#define RND(x) (int)(Rand() % (long) (x)) #define RND(x) ((int) (Rand() % (long) (x)))
#else #else
/* Good luck: the bottom order bits are cyclic. */ /* Good luck: the bottom order bits are cyclic. */
#define RND(x) (int)((Rand() >> 3) % (x)) #define RND(x) ((int) ((Rand() >> 3) % (x)))
#endif #endif
#endif /* LINT */ #endif /* LINT */
int rn2(x) /* 0 <= rn2(x) < x */ /* 0 <= rn2(x) < x */
int
rn2(x)
register int x; register int x;
{ {
#ifdef BETA #ifdef BETA
if (x <= 0) { if (x <= 0) {
debugpline1("rn2(%d) attempted", x); impossible("rn2(%d) attempted", x);
return (0); return 0;
} }
x = RND(x); x = RND(x);
return (x); return x;
#else #else
return (RND(x)); return RND(x);
#endif #endif
} }
int rnl(x) /* 0 <= rnl(x) < x; sometimes subtracting Luck */ /* 0 <= rnl(x) < x; sometimes subtracting Luck;
register int x; /* good luck approaches 0, bad luck approaches (x-1) */ good luck approaches 0, bad luck approaches (x-1) */
int
rnl(x)
register int x;
{ {
register int i, adjustment; register int i, adjustment;
#ifdef BETA #ifdef BETA
if (x <= 0) { if (x <= 0) {
debugpline1("rnl(%d) attempted", x); impossible("rnl(%d) attempted", x);
return (0); return 0;
} }
#endif #endif
@@ -50,15 +55,15 @@ register int x; /* good luck approaches 0, bad luck approaches (x-1) */
of integer division involving negative values */ of integer division involving negative values */
adjustment = (abs(adjustment) + 1) / 3 * sgn(adjustment); adjustment = (abs(adjustment) + 1) / 3 * sgn(adjustment);
/* /*
* 11..13 -> 4 * 11..13 -> 4
* 8..10 -> 3 * 8..10 -> 3
* 5.. 7 -> 2 * 5.. 7 -> 2
* 2.. 4 -> 1 * 2.. 4 -> 1
* -1,0,1 -> 0 (no adjustment) * -1,0,1 -> 0 (no adjustment)
* -4..-2 -> -1 * -4..-2 -> -1
* -7..-5 -> -2 * -7..-5 -> -2
* -10..-8 -> -3 * -10..-8 -> -3
* -13..-11-> -4 * -13..-11-> -4
*/ */
} }
@@ -73,37 +78,39 @@ register int x; /* good luck approaches 0, bad luck approaches (x-1) */
return i; return i;
} }
int rnd(x) /* 1 <= rnd(x) <= x */ /* 1 <= rnd(x) <= x */
int
rnd(x)
register int x; register int x;
{ {
#ifdef BETA #ifdef BETA
if (x <= 0) { if (x <= 0) {
debugpline1("rnd(%d) attempted", x); impossible("rnd(%d) attempted", x);
return (1); return 1;
} }
x = RND(x) + 1;
return (x);
#else
return (RND(x) + 1);
#endif #endif
x = RND(x) + 1;
return x;
} }
int d(n, x) /* n <= d(n,x) <= (n*x) */ /* d(N,X) == NdX == dX+dX+...+dX N times; n <= d(n,x) <= (n*x) */
int d(n, x)
register int n, x; register int n, x;
{ {
register int tmp = n; register int tmp = n;
#ifdef BETA #ifdef BETA
if (x < 0 || n < 0 || (x == 0 && n != 0)) { if (x < 0 || n < 0 || (x == 0 && n != 0)) {
debugpline2("d(%d,%d) attempted", n, x); impossible("d(%d,%d) attempted", n, x);
return (1); return 1;
} }
#endif #endif
while (n--) while (n--)
tmp += RND(x); tmp += RND(x);
return (tmp); /* Alea iacta est. -- J.C. */ return tmp; /* Alea iacta est. -- J.C. */
} }
/* 1 <= rne(x) <= max(u.ulevel/3,5) */
int int
rne(x) rne(x)
register int x; register int x;
@@ -117,14 +124,16 @@ register int x;
return tmp; return tmp;
/* was: /* was:
* tmp = 1; * tmp = 1;
* while(!rn2(x)) tmp++; * while (!rn2(x))
* return(min(tmp,(u.ulevel < 15) ? 5 : u.ulevel/3)); * tmp++;
* return min(tmp, (u.ulevel < 15) ? 5 : u.ulevel / 3);
* which is clearer but less efficient and stands a vanishingly * which is clearer but less efficient and stands a vanishingly
* small chance of overflowing tmp * small chance of overflowing tmp
*/ */
} }
/* rnz: everyone's favorite! */
int int
rnz(i) rnz(i)
int i; int i;
@@ -133,9 +142,10 @@ int i;
int x = i; int x = i;
int tmp = 1000; int tmp = 1000;
#else #else
register long x = i; register long x = (long) i;
register long tmp = 1000; register long tmp = 1000L;
#endif #endif
tmp += rn2(1000); tmp += rn2(1000);
tmp *= rne(4); tmp *= rne(4);
if (rn2(2)) { if (rn2(2)) {
@@ -145,7 +155,7 @@ int i;
x *= 1000; x *= 1000;
x /= tmp; x /= tmp;
} }
return ((int) x); return (int) x;
} }
/*rnd.c*/ /*rnd.c*/