score wrapping band-aid

This patch simply keeps the score from wrapping by capping it at LONG_MAX.
If someone wants to change the score to be unsigned, some changes will
need to be made to tweak this code (and use ULONG_MAX instead).
I'm assuming that our platforms all have limits.h.
This commit is contained in:
cohrs
2004-03-26 18:28:28 +00:00
parent e424ca4ba3
commit 607f63e5fd
4 changed files with 40 additions and 23 deletions

View File

@@ -60,6 +60,7 @@ thrown potions can sometimes hit a steed's saddle
sync default documentation of "null" option with the code sync default documentation of "null" option with the code
tripping over a cockatrice corpse didn't petrify, even when not wearing boots tripping over a cockatrice corpse didn't petrify, even when not wearing boots
do not call swamps on the Juiblex level "moat" when freezing do not call swamps on the Juiblex level "moat" when freezing
keep score from wrapping around and becoming negative by capping it
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes

View File

@@ -3,6 +3,7 @@
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
#include "hack.h" #include "hack.h"
#include <limits.h>
extern const char *hu_stat[]; /* defined in eat.c */ extern const char *hu_stat[]; /* defined in eat.c */
@@ -154,20 +155,20 @@ max_rank_sz()
long long
botl_score() botl_score()
{ {
int deepest = deepest_lev_reached(FALSE); long deepest = deepest_lev_reached(FALSE);
long utotal;
#ifndef GOLDOBJ #ifndef GOLDOBJ
long ugold = u.ugold + hidden_gold(); utotal = u.ugold + hidden_gold();
if ((utotal -= u.ugold0) < 0L) utotal = 0L;
if ((ugold -= u.ugold0) < 0L) ugold = 0L;
return ugold + u.urexp + (long)(50 * (deepest - 1))
#else #else
long umoney = money_cnt(invent) + hidden_gold(); utotal = money_cnt(invent) + hidden_gold();
if ((utotal -= u.umoney0) < 0L) utotal = 0L;
if ((umoney -= u.umoney0) < 0L) umoney = 0L;
return umoney + u.urexp + (long)(50 * (deepest - 1))
#endif #endif
+ (long)(deepest > 30 ? 10000 : utotal += u.urexp + (50 * (deepest - 1)) +
deepest > 20 ? 1000*(deepest - 20) : 0); (deepest > 30 ? 10000 : deepest > 20 ? 1000*(deepest - 20) : 0);
if (utotal < u.urexp) utotal = LONG_MAX; /* wrap around */
return utotal;
} }
#endif #endif

View File

@@ -10,8 +10,12 @@
#ifndef NO_SIGNAL #ifndef NO_SIGNAL
#include <signal.h> #include <signal.h>
#endif #endif
#include <limits.h>
#include "dlb.h" #include "dlb.h"
/* add b to long a, convert wraparound to max value */
#define nowrap_add(a, b) (a = ((a + b) < 0 ? LONG_MAX : (a + b)))
/* these probably ought to be generated by makedefs, like LAST_GEM */ /* these probably ought to be generated by makedefs, like LAST_GEM */
#define FIRST_GEM DILITHIUM_CRYSTAL #define FIRST_GEM DILITHIUM_CRYSTAL
#define FIRST_AMULET AMULET_OF_ESP #define FIRST_AMULET AMULET_OF_ESP
@@ -538,7 +542,7 @@ winid endwin;
value = arti_cost(otmp); /* zorkmid value */ value = arti_cost(otmp); /* zorkmid value */
points = value * 5 / 2; /* score value */ points = value * 5 / 2; /* score value */
if (counting) { if (counting) {
u.urexp += points; nowrap_add(u.urexp, points);
} else { } else {
makeknown(otmp->otyp); makeknown(otmp->otyp);
otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
@@ -567,6 +571,7 @@ int how;
boolean bones_ok, have_windows = iflags.window_inited; boolean bones_ok, have_windows = iflags.window_inited;
struct obj *corpse = (struct obj *)0; struct obj *corpse = (struct obj *)0;
long umoney; long umoney;
long tmp;
if (how == TRICKED) { if (how == TRICKED) {
if (killer.name[0]) { if (killer.name[0]) {
@@ -721,7 +726,6 @@ die:
/* calculate score, before creating bones [container gold] */ /* calculate score, before creating bones [container gold] */
{ {
long tmp;
int deepest = deepest_lev_reached(FALSE); int deepest = deepest_lev_reached(FALSE);
#ifndef GOLDOBJ #ifndef GOLDOBJ
@@ -738,11 +742,11 @@ die:
tmp = 0L; tmp = 0L;
if (how < PANICKED) if (how < PANICKED)
tmp -= tmp / 10L; tmp -= tmp / 10L;
u.urexp += tmp; tmp += 50L * (long)(deepest - 1);
u.urexp += 50L * (long)(deepest - 1);
if (deepest > 20) if (deepest > 20)
u.urexp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20); tmp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20);
if (how == ASCENDED) u.urexp *= 2L; nowrap_add(u.urexp, tmp);
if (how == ASCENDED) nowrap_add(u.urexp, u.urexp);
} }
if (bones_ok) { if (bones_ok) {
@@ -819,9 +823,11 @@ die:
/* add points for collected valuables */ /* add points for collected valuables */
for (val = valuables; val->list; val++) for (val = valuables; val->list; val++)
for (i = 0; i < val->size; i++) for (i = 0; i < val->size; i++)
if (val->list[i].count != 0L) if (val->list[i].count != 0L) {
u.urexp += val->list[i].count tmp = val->list[i].count
* (long)objects[val->list[i].typ].oc_cost; * (long)objects[val->list[i].typ].oc_cost;
nowrap_add(u.urexp, tmp);
}
/* count the points for artifacts */ /* count the points for artifacts */
artifact_score(invent, TRUE, endwin); artifact_score(invent, TRUE, endwin);
@@ -835,7 +841,7 @@ die:
if (Schroedingers_cat) { if (Schroedingers_cat) {
int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]); int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]);
mhp = d(m_lev, 8); mhp = d(m_lev, 8);
u.urexp += mhp; nowrap_add(u.urexp, mhp);
if (!done_stopprint) if (!done_stopprint)
Strcat(eos(pbuf), " and Schroedinger's cat"); Strcat(eos(pbuf), " and Schroedinger's cat");
} }
@@ -844,7 +850,7 @@ die:
if (!done_stopprint) if (!done_stopprint)
Sprintf(eos(pbuf), " and %s", mon_nam(mtmp)); Sprintf(eos(pbuf), " and %s", mon_nam(mtmp));
if (mtmp->mtame) if (mtmp->mtame)
u.urexp += mtmp->mhp; nowrap_add(u.urexp, mtmp->mhp);
mtmp = mtmp->nmon; mtmp = mtmp->nmon;
} }
if (!done_stopprint) putstr(endwin, 0, pbuf); if (!done_stopprint) putstr(endwin, 0, pbuf);

View File

@@ -3,6 +3,7 @@
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
#include "hack.h" #include "hack.h"
#include <limits.h>
STATIC_DCL long FDECL(newuexp, (int)); STATIC_DCL long FDECL(newuexp, (int));
STATIC_DCL int FDECL(enermod, (int)); STATIC_DCL int FDECL(enermod, (int));
@@ -99,8 +100,16 @@ void
more_experienced(exp, rexp) more_experienced(exp, rexp)
register int exp, rexp; register int exp, rexp;
{ {
u.uexp += exp; long newexp = u.uexp + exp;
u.urexp += 4*exp + rexp; long rexpincr = 4*exp + rexp;
long newrexp = u.urexp + rexpincr;
/* cap experience and score on wraparound */
if (newexp < 0 && exp > 0) newexp = LONG_MAX;
if (newrexp < 0 && rexpincr > 0) newrexp = LONG_MAX;
u.uexp = newexp;
u.urexp = newrexp;
if(exp if(exp
#ifdef SCORE_ON_BOTL #ifdef SCORE_ON_BOTL
|| flags.showscore || flags.showscore