Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Drastick

I need help with Random

This topic is 5484 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

I know how to use rand() I thought.. but I have a little game AI that has some randomness to its logic I''m using rand() and it works fine I do a srand( time(NULL)) so I can get diffrent each time the game runs but here is the problem. the AI is in a class and I have three of these monsters loaded but all three are behaving exactly the same for this code.
 

void CRomer:atrol()
{
	static int state = 2;
	if( GetTickCount() - ThinkTime > 1000 + rand()%1000 )
	{
		state = rand() % 7;
		ThinkTime = GetTickCount();
	}

	switch(state)
		{
		case 0:	{ Thrust(100); } break;
		case 1: { Rotate(100 * fDeltaTime); } break;
		case 2: { Rotate(-100 * fDeltaTime); } break;
		case 3:	{ Rotate(50 * fDeltaTime); }
		case 4: { Thrust(100);}break;
		case 5:	{ Rotate(-50 * fDeltaTime); }
		case 6: { Thrust(100);}break;
		default: { }
		}

}

 
but for all the AIs they run that secion of code with the same random numbers for each pass. When I trace through the code with debug for each AI this secion gets diffrent random number like I want. The only thing I am think is that rand() depends on the time passed between the last time it was used and all three objects are running this code too close togeter?? HELP

Share this post


Link to post
Share on other sites
Advertisement
you know mt?

/*(c) makoto matsumoto & takuji nishimura */
/*http://www.math.keio.ac.jp/matumoto/emt.html*/

#include <stdio.h>

#define N 624
#define M 397
#define MATRIX_A 0x9908b0df
#define UPPER_MASK 0x80000000
#define LOWER_MASK 0x7fffffff

#define TEMPERING_MASK_B 0x9d2c5680
#define TEMPERING_MASK_C 0xefc60000
#define TEMPERING_SHIFT_U(y) (y >> 11)
#define TEMPERING_SHIFT_S(y) (y << 7)
#define TEMPERING_SHIFT_T(y) (y << 15)
#define TEMPERING_SHIFT_L(y) (y >> 18)

static unsigned long mt[N];
static int mti=N+1;

void sgenrand(unsigned int seed)
{
mt[0]= seed & 0xffffffff;

for (mti = 1; mti < N; mti++)
mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
}

double genrand(void)
{
unsigned long y;
static unsigned long mag01[2]={0x0, MATRIX_A};

if (mti >= N)
{
int kk;
if (mti == N+1)
sgenrand(4357);

for (kk=0; kk < N-M; kk++)
{
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
}
for (;kk < N-1; kk++)
{
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
}
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];

mti = 0;
}

y = mt[mti++];
y ^= TEMPERING_SHIFT_U(y);
y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
y ^= TEMPERING_SHIFT_L(y);

return ( (double)y / (unsigned long)0xffffffff );
}

it generates much more random output than rand() and is much faster. the rand() function is used to throw very platform dependand random numbers... e.g. on a pentium3 90% of the numbers generated by rand() are greater than 0x80000000 and a multiple of 2, what might be your problem,,,

quote:

if( GetTickCount() - ThinkTime > 1000 + rand()%1000 )



"ThinkTime > 1000" is 1 (true) or 0 (false). i guess you mean:
((GetTickCount() - ThinkTime) > 1000)? ... : ...
or
GetTickCount - (ThinkTime > 1000)? ... : ...

Share this post


Link to post
Share on other sites
Well, it seems as though your IF statment is never evaluated as true (so your state is never randomized), and therefore, all your bots are behaving in state 2, correct?

Basically, this means GetTickCount() - ThinkTime is never greater than 1000 + rand()%1000

It''s hard to tell you without knowing what the value for ThinkTime is, but my guess is that if you put in some watch variables for those two values, you may figure out where you''re going wrong.

Share this post


Link to post
Share on other sites
The initial value of ThinkTime is zero

and the function is called everyframe

the bots work like I want them too the change thier next state randmoly sometime every 1000 to 1999 milliseconds which is what this line is saying

//if the clock - the time the state was last change is more than
// a number from 1000 to 1999
if( (GetTickCount() - ThinkTime) > (1000 + rand()%1000) )
//change to a random state and reset thinktime

but for each bot they behave exactly the same as the other bot.

Share this post


Link to post
Share on other sites
quote:
Original post by Drastick
The initial value of ThinkTime is zero

and the function is called everyframe

the bots work like I want them too the change thier next state randmoly sometime every 1000 to 1999 milliseconds which is what this line is saying

//if the clock - the time the state was last change is more than
// a number from 1000 to 1999
if( (GetTickCount() - ThinkTime) > (1000 + rand()%1000) )
//change to a random state and reset thinktime

but for each bot they behave exactly the same as the other bot.



Gotcha. In that case, perhaps rand() keeps using the same baseline to generate each "random" number. Check into using srand to change the seed values for rand: srand

Share this post


Link to post
Share on other sites
quote:
Original post by Zul
Gotcha. In that case, perhaps rand() keeps using the same baseline to generate each "random" number. Check into using srand to change the seed values for rand: srand


That's not his problem.

I think I know what it is. You have three instances of CRomer, right? One for each monster. The problem is that static variable state. A static variable is going to be the same for all instances of the class. So walking through your program, when if (GetTickCount() - ThinkTime > ...) is true, state is assigned a new random number and ThinkTime is reset. However, when Patrol is called for the other monsters, they are going to use the value for the last time state = rand()% 7 was called, regardless of which monster's class it was called in. Here's a short program to demonstrate what I'm talking about:


#include <iostream>
#include <string>
#include <time.h>

class Class
{
public:
Class() { srand(time(NULL)); }
~Class(){ }

void Print() { std::cout << i_ << std::endl; }

void GetNewRandom(bool b)
{
static int i = 2;

if (b)
i = rand() % 7;

i_ = i;
}

private:
int i_;
};

int main(void)
{
Class A, B;

std::string s;

do
{
A.GetNewRandom(true);
B.GetNewRandom(false);

A.Print();
B.Print();

std::cin >> s;
} while (s != "q");

return 0;
}


You see how the same value is always printed out, even thoughclass B should be printing out 2 everytime?

Now to fix it. Just make 'state' a private member variable, init it to 2 in the constructor, and reset it like you already are. Hopefully that is what your problem is and what will fix it.


[edited by - BitBlt on June 18, 2003 2:54:20 PM]

Share this post


Link to post
Share on other sites
Sorry I figured it out duh!

static int state = 2;

it made this static for ever class I made so when I change the state of one it changed it for all...I donno why I even put this here. Anyway that is why they were acting the same

[edit]
oops ya thanks bitblt! I notice it before I read your post, but here is a Cookie for being correct *hands over a cookie*

[edited by - Drastick on June 18, 2003 3:06:10 PM]

[edited by - Drastick on June 18, 2003 3:06:43 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!