Jump to content
  • Advertisement

Archived

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

graveyard filla

how to generate 2 unique random numbers at the same time?

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

high, i have a question. if i want to generate a random number, i know to use the rand () function. well this as we all know will generate the same random number over and over, which makes it not exactly random. so we add in the srand (time (NULL)); function. now, this is all fine and dandy, as long as the random numbers arent generating within the same second. but what if i wanted to generate 2 random numbers at the same time? for example, in the program im working on, my first simple little game program. it is a simple RPG combat game. theres a player, and an enemy. you run the program and it says you have entered combat, press enter to attack. you press enter, and a random generated number is generated(attack), then a nother one is generated,(defence). if attack > defence, you hit, it then rolls dice to see how much damage is dealt. after this, the enemy swings, it does the same, 2 randoms (one attack one defence, same type of comparision, same type of damage system. but what happends is they will miss or hit each other the same way, every time, and for the same amount of damage. i changed it around a bit, making it so the first attack and defence are:
attack = (rand () % 400) + 1;   //generates random number within 1-400

	attack = attack % 11 + 1 //mods that number to make it between 1-12

	defence = (rand () % 500) + 1; // generates random number within 1-500

	defence = defence % 11 + 1; // mods that number within 1-12

and the second attack and defences are :
attack = (rand () % 11) + 1; //generates a random number and mods it to be between 1-12


defence = (rand () % 11) + 1; //generates a random number and mods it to be between 1-12

this seems to keep them both unique. but not fair! the second set of attacks seems to work a lot more then the first set. does anyone know an easier way to do this? i also have problems calculating damage, since that also uses random numbers for both players, within the same second. making the damage be the same, but i also changed the numbers around to be different, but that too seems to be off. any help is appreciated. thanks

Share this post


Link to post
Share on other sites
Advertisement
I am having the exact same problems. Currently every gameloop my game randomly chooses block color and position. Since it is updated quite a bit, my block positions repeat contantly.

I will be watching this thread to see if you find an answer.

[edited by - FaR on January 11, 2004 5:07:24 PM]

Share this post


Link to post
Share on other sites
I''m using the RDTSC instruction to get a seed. Doing something like this would probably give you a pretty good one:


// Gives you a 64-bit (8 byte) seed value.

inline unsigned __int64 GetSeed64()
{
__asm rdtsc
}

// Since srand wants a 32-bit number and not a 64-bit one, we''ll have to do something about the 64-bit seed.

inline unsigned int GetSeed32()
{
unsigned __int64 i = GetSeed64();
return (unsigned int)(i >> 32) ^ (unsigned int)(0xFFFFFFFF & i);
}


Then you call srand with the value from GetSeed32.


[My Image Gallery (WIP)][Greatest Tetris clone evar!][Return your stolen MP3s]

Share this post


Link to post
Share on other sites
i am very new to programming. i dont understand your code! for starters, ive never seen __ before a data type or anything. whats that about? care to explain the rest of the code to a newbie? thans\ks

Share this post


Link to post
Share on other sites
quote:
well this as we all know will generate the same random number over and over, which makes it not exactly random

? no !? Its generating a random series of numbers that is well defined by the mathematical expression behind rand(), but calling rand multiple times will not generate multiple times the same number. use srand only once when you use a fixed parameter (dont put srand in a gameloop etc) or use some alternative random number generators (google, sry forgot the name of a good one)


oh and
quote:

rand () % 400) + 1; //generates random number within 1-400
rand () % 11) + 1; //generates a random number and mods it to be between 1-12



do you see the problem? 12 will never appear (%11 returns values from 0 to 10)


T2k

Share this post


Link to post
Share on other sites
I don''t understand you problem.

Do you want two randomly generated numbers that are different?

That''s very easy to do.

Generate a random number. Save it. Keep generating another
random number until it''s different. Save that.


int r1, r2;

r1 = rand();
do { r2 = rand(); } while (r2 == r1);

// Now r1 and r2 are different






Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
quote:
Original post by graveyard filla
i am very new to programming. i dont understand your code! for starters, ive never seen __ before a data type or anything. whats that about? care to explain the rest of the code to a newbie? thans\ks
Sorry, I guess I''ll explain a little bit more.

__int 64 is a 64-bit datatype. __asm RDTSC calls the RDTSC instruction, which returns the number of cycles executed since the CPU started up. It returns a 64 bit (8 byte) number, which is twice the size srand wants. We could just use the lower DWORD (the first four bytes) of the result, but since we have a 64 bit number, we might as well use all of it. That''s why we have to manipulate it a bit.

The line "return (unsigned int)(i >> 32) ^ (unsigned int)(0xFFFFFFFF & i);" performs a logical XOR operation with the first four bytes and last four bytes of the value we got from RDTSC. XOR goes through all the individual bits, checking if they''re 1 or 0, and sets the corresponding bit of the result to 0 if the bits in the operands are the same, or 1 if they are different.
Don''t worry if you didn''t understand the bit about XOR - it isn''t really important for now.


[My Image Gallery (WIP)][Greatest Tetris clone evar!][Return your stolen MP3s]

Share this post


Link to post
Share on other sites
thanks for all your help guys. but i seem to be even more confused now then ever. so using the srand (time (NULL));
then assigning a variable to rand likeattack = (rand () % 11) + 2;

will generate a random number based on the internal clock. it was my presumption that if you did
srand (time (NULL));

attack = (rand () % 11) + 2;
defence = (rand () % 11) + 2;

this would generate 2 random numbers, but wouldnt the numbers be exactly the same? or am i wrong about this? since they executed one after another, wouldnt that mean thye execute at the same point in time, therefore they would be the same number?

one more question, so i only put
srand (time (NULL)) once in the entire program? or do i put it in each function, or what?

could someone help me? maybe take a look at my program, run it and tell me what you think? i could really use some advise from someone whos looked at the code/program itself.
here it is. thanks guys


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

using namespace std;

void intro_screen (); //a simple print screen function that prints the welcome screen


string calc_attack (int &enemyhealth); //the function that calculates the players attacks

//and returns the attack result (hit or miss)

// and "grabs" enemys health


string enemy_attack (int &health); //the function that calculates the enemeis attacks

//and returns the attack result and "grabs" player health


int main()
{
string hit_result;
string enemy_hit_result;
int go_attack;
int health = 100;
int enemy_health = 100; //initalizes the holding places for hit results, and health for both

//players




intro_screen(); //simply prints the intro screen to the screen


do
{

cout<<"You have "<<health<<" health"<<endl;
cout<<"They have "<<enemy_health<<" health"<<endl;
cout<<"Press enter to attack!"<<endl;
cin>>go_attack;

hit_result = calc_attack(enemy_health); // this finds out if the player hits or misses

// if hit, it updates the new enemies health


cout<<hit_result<<endl<<endl; //prints if player hit or missed


enemy_hit_result = enemy_attack(health); //this finds if the CPU hit or missed the player

//if hit, it updates the health variable


cout<<enemy_hit_result<<endl<<endl; //prints if CPU hit or missed


}
while ((health >= 0) && (enemy_health >= 0)); //plays the game untill one of the players dies


if (health < 0) //if player dies, say game over.

{

cout<<"You are dead"<<endl;

cout<<"Game Over"<<endl;
}
else if (enemy_health < 0) //if enemy dies, say victory

{
cout<<"You have achieved victory!"<<endl;

}

return 0;
}

void intro_screen () //simply prints the welcome screen to the player.

{
cout<<"*********************************************"<<endl;
cout<<"Welcome to FTA"<<endl;
cout<<"*********************************************"<<endl;
cout<<"Donkey Punch Productions. A company of Foo Derraro."<<endl;
cout<<"You are walking down the streets and an enemy approaches."<<endl<<endl;
cout<<"You have entered combat!!!"<<endl<<endl;

}

string calc_attack (int &enemy_health) //calculates players attack and returns "hit or miss"

// and sends back new enemy health

{
int attack;
int defence;
int damage;
string hit_result;

srand (time (NULL));
attack = (rand () % 1000) + 1; //generates random number for attack

//between 1-1000 and mods it to

// a a dice number (1-12)

attack = attack % 11 + 2;
defence = (rand () % 800) + 1; //generats random number for defence

//between 1-800 and mods it to a dice number

defence = defence % 11 + 2;
if (attack > defence) //compares attack to defence, if bigger, it is a hit and then calculates

// damage and update health

{
hit_result = "You hit!";

damage = ((rand () % 11) + 2);

enemy_health = enemy_health - damage;
}
else if (defence >= attack) //if defence is bigger, you miss

{
hit_result ="You missed!";
}

return hit_result; //returns string "hit" or "miss"

}

string enemy_attack (int &health) // calculates enemy attack "hit" or "miss" and calculates damage

//and updates health.

{
int attack;
int defence;
int enemydmg;
string enemy_hit_result;

srand (time (NULL));

attack = (rand () % 11) + 2; //makes attack a random between 1-12


defence = (rand () % 400) + 1;
defence = defence % 11 + 2;

//makes attack a random between 1-12


if (attack > defence) //if attack > defence, you hit is sent back, and calculates damage

//and updates health

{
enemy_hit_result = "You were hit!";

enemydmg = (rand () % 11) + 1;

health = health - enemydmg;
}

else if (defence >= attack) //if defence > attack, "miss" is returned, health stays unchanged


{
enemy_hit_result ="They missed you!";
}

return enemy_hit_result;
}

Share this post


Link to post
Share on other sites
first of all DO NOT CALL SRAND() before every random number .. this is just WRONG WRONG WRONG .. because then you are NOT getting random nubmers, you are getting a number based on the time, completely and totally ...

RAND generates a SEQUENCE of DIFFERENT pseudo-random nubmers, from a seed ... EACH time you reset the seed to a certain number, you get the SAME sequence, but the relationship between each number in the sequence is HIGHLY unpredictable before hand in the sense that they do not follow any easily recognizable patterns, and therefore are well suited for generated many different sub-sequences out of ...

SRAND is meant to be used ONCE, to initial the sequence at the start of your number generation ...

NOT ONLY can it be used to set to a thing like the clock time, so that you are highly likely to get different behavior every time you play the game. But it is also possible to CHOOSE a number and save it, so you can RERUN the same numbers again ... this is how PICKING a game in MAJONG or FREECELL works .. you are PICKING the seed to the random number generator - which then yeilds a certain deck during the shuffling algorithm (which calls RAND many times).

IF you can SRAND many times, you get LESS random seeming behavior in general, because the clock advances in a PREDICTABLE way ... the algortihm rand uses is based on trying to generated numbers based on a source, and yet not in any easily predicatable or identifiable way (they do this by combining many operations, at least one of which overflows out of the used registers) ...

Share this post


Link to post
Share on other sites
what about inside different functions? should i just call srand(time) in the main, and go about doing my rands() everywher else in the program (including outside of main)? what i mean to say is, is srand(time) a global thing? or do i have to do it in each one of the functions?

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!