# rand() crashes.

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Why does my game crash if I do:
   const double nr_1 =  floor( vit*0.3 );
const double nr_2 = ( floor( ( vit*vit ) / 150) - 1 );
const double rnd_nr = getGreater( nr_1, nr_2 );

int rnd_vit = ( rand() % static_cast<int>( rnd_nr ) );
// crash


Is it because rnd_nr can be zero ( 0 ) ? ? :/

##### Share on other sites
Quote:
 Original post by rakoon2Why does my game crash if I do:*** Source Snippet Removed ***Is it because rnd_nr can be zero ( 0 ) ? ? :/

Sounds likely, yes.

##### Share on other sites
I want to calculate my vitality def with this formula:
// [VIT*0.5] + rnd([VIT*0.3], max([VIT*0.3],[(VIT^2)/150]-1))

Here is the code:
int CPlayer::getVitDef( void ){   const double nr_1 =  floor( vit*0.3 );    const double nr_2 = ( floor( ( vit*vit ) / 150) - 1 );   const double rnd_nr = getGreater( nr_1, nr_2 );        if( rnd_nr > 0 )   {       int rnd_vit = ( rand() % static_cast<int>( rnd_nr ) );       if( rnd_vit < nr_1 )       {           rnd_vit = static_cast<int>( nr_1 ) ;         }       else if( rnd_vit > rnd_nr )       {           rnd_vit = static_cast<int>( rnd_nr );       }                                     return ( static_cast<int>( vit*0.5 ) + rnd_vit );   }   else   {       return ( static_cast<int>( vit*0.5 ));   }   }

Do I do it right? How could I speed it up? Thank you.

##### Share on other sites
Using modulo (%) when trying to get a random number is generally a bad idea.

Personally, I did up a templated random number generator and then a few defines for convienience.
namespace random {	template<class T>	class TRandom	{	public:		static T MinMax(T minimum, T maximum) {			// do a bit of sanity on the min/max values			if( minimum == maximum ) 				return minimum;			else if( minimum < maximum )				return static_cast<T>( ((static_cast<float>(rand()) / static_cast<float>(RAND_MAX+1)) * (maximum-minimum)) + minimum);			else				return static_cast<T>( ((static_cast<float>(rand()) / static_cast<float>(RAND_MAX+1)) * (minimum-maximum)) + maximum);		}	};}#ifndef RANDOM_FLOAT#define RANDOM_FLOAT(min, max) (random::TRandom<float>::MinMax((min),(max)))#endif#ifndef RANDOM_INT#define RANDOM_INT(min, max) (random::TRandom<int>::MinMax((min),(max)))#endif#ifndef RANDOM_DIE#define RANDOM_DIE(min, max) (random::TRandom<int>::MinMax((min),(max)+1))#endif#ifndef RANDOM_DOUBLE#define RANDOM_DOUBLE(min, max) (random::TRandom<double>::MinMax((min),(max)))#endif

This template will return a random number of the appropriate type between min and max, including min, but excluding max (standard random number generation operation). If you need a random integer including both min and max (for instance, simulating a six sided die) you would use RANDOM_DIE(min,max). Also, for your "getGreater" function, you could probably just use the standard library's "max" if its just a simple numerical comparison, no need to roll your own.

##### Share on other sites
oha! Thank you! :-)

max: max' undeclared (first use this function) uh?

max( nr_1, nr_2 ); ?

##### Share on other sites
I believe you need to #include <stdlib> before you can use min() and max().

##### Share on other sites
still max' undeclared (first use this function) ? :/

if I try on of these stdlib: No such file or directory.

#include <stdio.h>#include <stdlib.h>#include <algorithm>

Oh and how do you guys find this range weapon to monster dmg-formula: ?
The damage is a little bit too constant if I have high dex! hm :/?

 // find the size modification out double size_mod = 0; if( size_type == 's' || size_type == 'm' )   size_mod = 1.00; else if( size_type == 'l' )   size_mod = 0.70;    // calc min dmg   const double minD = getSmaller( ATK, p_dex*(0.8+(0.2*weaponLevel)) ); // calc max dmg   const double maxD = getGreater(                       ( ATK/100)*getSmaller( ATK, p_dex*(0.8+(0.2*weaponLevel)))                        + RANDOM_DOUBLE(0, ((arrow->getArrowDmg()*(0.8+(0.2*arrowLevel)))- 1))                        , ATK ) * size_mod;  double rndD = RANDOM_DOUBLE(minD, maxD); //calc final dmg    int dmg =static_cast<int>( p_dex + (floor( p_dex/10 )*floor( p_dex/10 ))         + floor( p_str/5 ) + ( rndD * (1 - m_def/100)) - calcVitDef()  );

[Edited by - rakoon2 on August 19, 2004 1:26:13 PM]

##### Share on other sites
The generic templated versions of min(), max(), and swap() should all be available through <algorithm>.

##### Share on other sites
I suppose that in the event that your STL is crippled for some reason, you could implement them yourself as such:
template <class T>inline const T& min( const T& a, const T& b ) {    return b < a ? b : a;}template <class T>inline const T& max( const T& a, const T& b ) {    return a < b ? b : a;}

##### Share on other sites
Hehe.. yes I already did that :-).. but thank you!

##### Share on other sites
The "modern C++" version of <stdlib.h> is, of course, <cstdlib>.

##### Share on other sites
Oh! OK ;-)

Scrime, your version is wrong! This is right:
template <class T>inline const T& getGreater( const T& a, const T& b ) {    return a < b ? b : a;}template <class T>inline const T& getSmaller( const T& a, const T& b ) {    return b < a ? b : a;}

What should I use? my own or max/min? Is it the same?

##### Share on other sites
Quote:
 Original post by rakoon2Oh! OK ;-)Scrime, your version is wrong! This is right:*** Source Snippet Removed ***What should I use? my own or max/min? Is it the same?

I would use the C++ standard library version of min/max which are not in cstdlib those versions are macros if i remember correctly, you wont the ones that are in the algorithm header e.g.

#include <algorithm> //<- min/max in there#include <iostream>int main() {   std::cout << std::max(3, 5) << '\n';   std::cout << std::min(3, 5) << std::endl;   return 0;}

EDIT: there are overloaded versions that take predicates aswell if a type doesn't support the required relational operators that the normal min/max need.

##### Share on other sites
Ah! std::max !! Thank you!

##### Share on other sites
Scrime, I have a problem with your nr generator! It always returns the same number..! ( not really random ehh:P ).

Thank you!

Here is the code:
#include <iostream>#include <time.h>      // init the random number generator with the current time#include <math.h>      // random number generator namespace random {	template<class T>	class TRandom	{	public:		static T MinMax(T minimum, T maximum) {			// do a bit of sanity on the min/max values			if( minimum == maximum ) 				return minimum;			else if( minimum < maximum )				return static_cast<T>( ((static_cast<float>(rand()) / static_cast<float>(RAND_MAX+1)) * (maximum-minimum)) + minimum);			else				return static_cast<T>( ((static_cast<float>(rand()) / static_cast<float>(RAND_MAX+1)) * (minimum-maximum)) + maximum);		}	};}#ifndef RANDOM_FLOAT#define RANDOM_FLOAT(min, max) (random::TRandom<float>::MinMax((min),(max)))#endif#ifndef RANDOM_INT#define RANDOM_INT(min, max) (random::TRandom<int>::MinMax((min),(max)))#endif#ifndef RANDOM_DIE#define RANDOM_DIE(min, max) (random::TRandom<int>::MinMax((min),(max)+1))#endif#ifndef RANDOM_DOUBLE#define RANDOM_DOUBLE(min, max) (random::TRandom<double>::MinMax((min),(max)))#endifint main() {          srand( static_cast<unsigned> (time(NULL)) );      const int AttackerHit = 20;   const int DefenderFlee = 46;   const int dodge = 80 + AttackerHit - DefenderFlee;   int d = RANDOM_INT(1, 100);   std::cout << d << '\n';            if( d <= dodge)   {       std::cout << "dodge!!  "  << dodge << '\n';   }                system("Pause");   return 0;}

##### Share on other sites
I'm not quite sure how you are testing the code that I sent you, or even if you are typing it in correctly. The min/max templates that I provided are correct, it seems that all you did was swap their order and give them different names.

When seeding with time(NULL), I did notice that the first number generated was often the same over the course of a span of time, but the second and subsequent numbers were random. This isn't caused from my template, but rather from the way that rand() operates. My template just calls rand() in a way that it returns a value in the spcified range, it doesnt actually produce the random numbers. If you are concerned with it you can do one of the following:

1) Strip off the first non-random random number, by just calling rand() and throwing the value away.
2) Find another way to seed srand(), for instance GetTickCount() on Windows.
3) Implement a version of one of the better random number generators out there, like the Mersenne Twister

##### Share on other sites
Quote:
 Original post by rakoon2Oh! OK ;-)Scrime, your version is wrong! This is right:*** Source Snippet Removed ***

or, even quicker, create a couple of macros:
#define MIN(A,B) ( A < B ? A : B)#define MAX(A,B) ( A > B ? A : B)//usage:int x=30;int y=50;int z=MIN(x,y); // sets z = 30

##### Share on other sites
I refer you to here as to why macros that act like functions are bad ju ju.

##### Share on other sites

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

• ### Forum Statistics

• Total Topics
628730
• Total Posts
2984431

• 25
• 11
• 10
• 16
• 14