Sign in to follow this  

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Quote:
Original post by rakoon2
Why does my game crash if I do:
*** Source Snippet Removed ***

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


Sounds likely, yes.

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by rakoon2
Oh! 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 this post


Link to post
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)))
#endif






int 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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by rakoon2
Oh! 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 this post


Link to post
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.

If you intended to correct an error in the post then please contact us.

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

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this