]> granicus.if.org Git - nethack/commitdiff
rnl() tweaks
authornethack.rankin <nethack.rankin>
Sat, 28 Aug 2004 01:54:20 +0000 (01:54 +0000)
committernethack.rankin <nethack.rankin>
Sat, 28 Aug 2004 01:54:20 +0000 (01:54 +0000)
     Eliminate two minor anomalies in the behavior of the rnl() function
which returns a random number that is modified by the hero's Luck attribute.
Integer division by 3 on requests for small ranges and the fact that the
chance of making a modification was lower for good luck than for bad luck
meant that highest luck did not produce best chance to avoid worst result.

     The actual effect on game play is sure to have been negligible.  More
troubling is that the program has several rnl(3) and rnl(4) calls.  These
practically guarantee a result of 0 when the hero has maximum luck.  The
rnl() function really shouldn't be used for such tiny ranges (unless the
actual intent is that high level characters are expected to almost always
have the 0 outcome...).

doc/fixes34.4
src/rnd.c

index dcc3db8a9140daba9866c947d2db13dae48da789..76480e46885024fcf03c9639b8f96d1931503368 100644 (file)
@@ -51,6 +51,7 @@ monster throwing greased weapon has same chance for slip/misfire as player
 killing a pet by displacing it into a trap now yields experience
 prevent a rolling boulder that is in motion from vanishing in bones files
 ensure that a sleeping steed doesn't answer a #chat
+eliminate two very minor anomalies when using Luck to adjust random numbers
 
 
 Platform- and/or Interface-Specific Fixes
index 7b4ab0fec823d9bdaaafaf0b37c98c3905c0cc35..980fbf5f03dd1e7f869c65c6a5c10c4c0784fde8 100644 (file)
--- a/src/rnd.c
+++ b/src/rnd.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)rnd.c      3.4     2003/12/13      */
+/*     SCCS Id: @(#)rnd.c      3.4     2004/08/27      */
 /* NetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -40,7 +40,7 @@ int
 rnl(x)         /* 0 <= rnl(x) < x; sometimes subtracting Luck */
 register int x;        /* good luck approaches 0, bad luck approaches (x-1) */
 {
-       register int i;
+       register int i, adjustment;
 
 #ifdef DEBUG
        if (x <= 0) {
@@ -48,14 +48,32 @@ register int x;     /* good luck approaches 0, bad luck approaches (x-1) */
                return(0);
        }
 #endif
-       i = RND(x);
 
-       if (Luck && rn2(50 - Luck)) {
-           i -= (x <= 15 && Luck >= -5 ? Luck/3 : Luck);
+       adjustment = Luck;
+       if (x <= 15) {
+           /* for small ranges, use Luck/3 (rounded away from 0);
+              also guard against architecture-specific differences
+              of integer division involving negative values */
+           adjustment = (abs(adjustment) + 1) / 3 * sgn(adjustment);
+           /*
+            *   11..13 ->  4
+            *    8..10 ->  3
+            *    5.. 7 ->  2
+            *    2.. 4 ->  1
+            *   -1,0,1 ->  0 (no adjustment)
+            *   -4..-2 -> -1
+            *   -7..-5 -> -2
+            *  -10..-8 -> -3
+            *  -13..-11-> -4
+            */
+       }
+
+       i = RND(x);
+       if (adjustment && rn2(37 + abs(adjustment))) {
+           i -= adjustment;
            if (i < 0) i = 0;
            else if (i >= x) i = x-1;
        }
-
        return i;
 }