[comp.sources.d] Bug Fix for Hack

gil@svax.cs.cornell.edu (Gil Neiger) (04/22/87)

A few weeks ago a posted a problem I was having in hack here at Cornell.
Many players were finding that when they reached level 27 or thereabouts
they often lost a game due to "panic".  They would get the message
"Suddenly, the dungeon collapses" followed by "makemon?".  I posted
the appropriate section of makemon() that I had, but no one was able
to help me.  I noticed that some people have been having problems with
another version (Amiga) of hack crashing - maybe my fix can help them
also.

I had installed a fix to makemon() to better balance monsters when
using KOPS and ROCKMOLE.  Here's what the code looked like:

	} else {
		ct = CMNUM - strlen(fut_geno);
		if(index(fut_geno, 'm')) ct++;  /* make only 1 minotaur */
		if(index(fut_geno, '@')) ct++;
		if(ct <= 0) return(0); 		  /* no more monsters! */
		tmp = 7;
#ifdef KOPS
		tmp--;
#endif KOPS
#ifdef ROCKMOLE
		if(dlevel<4)tmp--;
#endif ROCKMOLE
		tmp = rn2(ct*dlevel/24 + tmp);
		if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
		if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
		ct = 0;
#ifdef KOPS
		ct++;          /****************************/
#endif KOPS
		for(; ct < CMNUM; ct++){
			ptr = &mons[ct];
			if(index(fut_geno, ptr->mlet))
				continue;
			if(!tmp--) goto gotmon;
		}
		panic("makemon?");
	}
gotmon:

The problem is when ct is decremented when KOPS is on (see ***);
tmp needs to be correspondingly (if it is greater than 0).
Specifically, that portion of the code should look like this

		tmp = rn2(ct*dlevel/24 + tmp);
		if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
		if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
		ct = 0;
#ifdef KOPS
		ct++;  tmp = (tmp) ? tmp-- : tmp;
#endif KOPS
		for(; ct < CMNUM; ct++){
			ptr = &mons[ct];

Now you can be assured that the loop will terminate correctly and
that there will be no panic.

					- Gil

levy@ttrdc.UUCP (04/26/87)

In article <1264@svax.cs.cornell.edu>, gil@svax.cs.cornell.edu (Gil Neiger) writes:
< The problem is when ct is decremented when KOPS is on (see ***);
                            ^^^^^^^^^^^
< tmp needs to be correspondingly (if it is greater than 0).
< Specifically, that portion of the code should look like this
< 
< 		tmp = rn2(ct*dlevel/24 + tmp);
< 		if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
< 		if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
< 		ct = 0;
< #ifdef KOPS
< 		ct++;  tmp = (tmp) ? tmp-- : tmp;
                ^^^^
< #endif KOPS
< 		for(; ct < CMNUM; ct++){
< 			ptr = &mons[ct];
< 
< Now you can be assured that the loop will terminate correctly and
< that there will be no panic.
< 
< 					- Gil

Huh?  Do you mean INCREMENTED?  Or should that be a ct--?

Also,

	tmp = (tmp) ? tmp-- : tmp;

is unportable code, and may blow up in environments other than the one you
tested it in.  If the compiler arranges for tmp-- to be executed before
the value of the expression is stuffed back into tmp, the effect of the
decrement will be undone.

Why not, instead,

	if (tmp) tmp--;
-- 
|------------dan levy------------|  Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
|         an engihacker @        |		vax135}!ttrdc!ttrda!levy
| at&t computer systems division |  Disclaimer:  try datclaimer.
|--------skokie, illinois--------|