Public Group

#### Archived

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

# a better way to randomize an event?

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

## Recommended Posts

high. im new to programming, so please bare with my noobishness. ive been working on a text based RPG game in the past few days, and in a lot of the program i needed to randomize the chance of an event happening (Ex. when you kill an enemy, the chances of him dropping loot). well, i found that i was doing it so much for so many different things, (ex not only chances of enemy dropping loot, but also chances of many other things such as what spell the enemy casts or if the enemy casts a spell at all, etc.) anyway, i made my own function to do this now. basically it works like this bool random_bool() { bool chance; int random = rand() % 100; //make a random number 1-100 if (random >=50) //if its more then 50, return true chance = true; } else // if its less then 50, return false { chance = false; } return chance; } now, in my program when i want to randomize an event (say for the event of an enemy dropping loot when he dies), i do drop_loot = random_bool(); if (drop_loot == true) { drop loot code; } basically the fucntion just randomizes a boolean value the way rand() randomizes a number. it seems to be working pretty well so far, but im just wondering if what im doing is completely wrong, or if theres a different, or a built in way to do this. thanks for any input ps-(i realize that the function only works if you want a 50/50 chance of something happening, im going to change it so you can send it the chances through a parameter instead of it being hard coded) p s s - is it truly a 50/50 chance? or am i wrong about that? [edited by - graveyard filla on January 13, 2004 4:13:54 PM] [edited by - graveyard filla on January 13, 2004 4:14:38 PM]

##### Share on other sites
If you only need boolean true or false, you only need to check 1 bit.

For example

if( Rand() & 1 )
{
// do some stuff
}
else
{
// do some other stuff
}

Alternatively, you could fill a bitstream with random numbers (since Rand() would return numbers of n bits length it''s a waste to call it every time you need a new bit), and then extract from it.. or even just fill a 32bit int, and refill it everytime it''s "empty" (set up a simple random bool class )

##### Share on other sites
it is a 50/50 chance I dont see why you dont just use rand in the program, if its for a monster dying you may just want an entirely separate function for when monsters die, I have a simple battling program too but Im working to add more advanced things but maybe the code will help, and in that function if you want it to be truely random use srand(time(0)) making sure you have the time.H file included, but I dont understand your question.
its long so have fun
#include <iostream.h>#include <conio.h>#include <stdlib.h>#include #include <iomanip.h>#include <fstream.h>#include <ctype.h>#include <assert.h>const int Maxhp = 560;const int startingstamina = 100;// function prototypesvoid battleA(int,int,int,int,int);char battle_screen(int,int,int);void showmenu(int,int,int,int,int);int check_health_monster(int,int*,int*,int*,int*);int giveplayeritems(int*);int check_health_player(int,int*,int*,int*);char attack_screen();int coordinates_message(int,int);int ice1(int*,int,int,int);int fire1(int*,int,int,int);int potion(int,int*);int normal_attack(int*,int,int,int);struct character{int hp;int stamina;}monster,player;ofstream fout;ifstream fin;int main(){char command;int x,y,counter=1,grid_1=1;int num_potions=1;int *def_monster, *num_potionsP = &num_potions;int loopc,end,battle_check, battle_counter, turn, spell, item, attack;int *damage;int* grid_1P=&grid_1,*turnP=&turn,*counterP = &counter;player.hp = Maxhp;monster.hp = Maxhp;x=0;y=0;loopc = 1;while(counter != 0){while(grid_1 != 0){monster.hp = Maxhp;srand(time(0));if(loopc == 1){clrscr();}loopc++;cout< <<" 1.Fire1"< <<" 2.Ice1"< <<"------------------"< spell = getch();if( spell == ''1''){def_monster = &monster.hp;monster.hp = fire1(def_monster,turn,player.hp,monster.hp);check_health_monster(monster.hp,grid_1P,counterP,turnP,num_potionsP);}else if( spell == ''2''){def_monster = &monster.hp;monster.hp = ice1(def_monster,turn,player.hp,monster.hp);check_health_monster(monster.hp,grid_1P,counterP,turnP,num_potionsP);}}else if( command == ''3''){if(num_potions <= 0){num_potions = 0;}cout< <<" 1.potions "< <<"-------------------"< item = getch();if(item == ''1''){player.hp = potion(player.hp,num_potionsP);turn= 2;}}else if(command == ''4''){turn = 0;grid_1 = 1;counter = 1;clrscr();}} // while (turn == 1)// Monster''s turnwhile(turn == 2){battle_screen(player.hp,monster.hp,turn);attack = rand()%3;def_monster = &player.hp;if(attack == 1){player.hp = normal_attack(def_monster,turn,player.hp,monster.hp);end = check_health_player(player.hp,grid_1P,counterP,turnP);}else if(attack == 2){player.hp = ice1(def_monster,turn,player.hp,monster.hp);end = check_health_player(player.hp,grid_1P,counterP,turnP);}else if(attack == 3){player.hp = fire1(def_monster,turn,player.hp,monster.hp);end = check_health_player(player.hp,grid_1P,counterP,turnP);}turn = 1;if(end == 1){turn = 0;counter = 0;grid_1 = 0;} // while (turn == 2)}}return 0;}int coordinates_message(int x,int y){cout<<"Your coordinates are ("<return 0;}int ice1(int* def_monster,int turn,int player, int monster){srand(time(0));int damage,hit_check;damage = rand()%74+40;*def_monster -= damage;hit_check = 1;clrscr();battleA(damage,player,monster,hit_check,turn);return (*def_monster);}int fire1(int* def_monster,int turn, int player, int monster){srand(time(0));int damage,hit_check;damage = rand()%74+40;*def_monster -= damage;clrscr();hit_check = 1;battleA(damage,player,monster,hit_check,turn);return (*def_monster);}potion(int player, int* num_potionsP){int i;int Maxhp = 560;if(*num_potionsP <= 0){clrscr();cout<<"Sorry you have no potions to use";getch();clrscr();}else{for(i = 1; i<= 100 ; ++i){if(player == Maxhp){cout<<"you healed "< break;}player += 1;}clrscr();cout<<"Your HP: "< getch();clrscr();*num_potionsP = *num_potionsP - 1;}return (player);}int normal_attack(int *def_monster,int turn,int player,int monster){srand(time(0));int damage, rand_check, hit_check;rand_check = rand()%100;if(rand_check >= 20){damage = rand()%84+53;*def_monster -= damage;hit_check = 1;battleA(damage,player,monster,hit_check,turn);}else{hit_check = 0;battleA(damage,player,monster,hit_check,turn);}return (*def_monster);}char attack_screen(){char command;cout< <<" 1.Attack"< <<" 2.Spell"< <<" 3.Item"< <<" 4.Run"< <<"-------------------"<return(command);}int check_health_player(int HP,int* grid_1P,int* counterP,int* turnP){if(HP <= 0){clrscr();cout<<"You Lost";getch();*grid_1P = 0;*counterP = 0;*turnP = 3;return (1);}else{return (0);}}int check_health_monster(int HP,int* grid_1P,int* counterP,int* turnP,int* num_potionsP){if(HP <= 0){clrscr();cout<<"You Beat The Monster";getch();giveplayeritems(num_potionsP);*grid_1P = 1;*counterP = 1;*turnP = 0;return (1);}else{*turnP = 2;return (0);}}int giveplayeritems(int* num_potionsP){int i,num_items;srand(time(0));num_items = rand()%10;for(i = 0; i < num_items; ++i){*num_potionsP = *num_potionsP + 1;clrscr();cout<<"Potion "<}getch();return (0);}char battle_screen(int player,int monster,int turn){char command;if(turn == 2){clrscr();cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<getch();}if(turn == 1){clrscr();cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout<cout< <<" 1.Attack"< <<" 2.Spell"< <<" 3.Item"< <<" 4.Run"< <<"-------------------"<command = getch();}return (command);}void battleA(int damage,int player,int monster,int hit_check,int turn){if((hit_check == 1)&&(turn == 1)){clrscr();cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< getch();}if((hit_check == 1) && (turn == 2)){clrscr();cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< getch();}if((hit_check == 0)&&(turn == 1)){clrscr();cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< getch();}if((hit_check == 0) && (turn == 2)){clrscr();cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< cout< getch();}}void showmenu(int monster, int player, int x, int y,int num_potions){char choice;int menuloop = 1, i;char filename[30];while(menuloop == 1){cout<<"----------------------------------";cout<cout<cout<cout<choice = getch();if(choice == ''1''){clrscr();cout<<"Enter a file name to save in ";cin.getline(filename,sizeof(filename-1));fout.open(filename);fout<clrscr();cout<<"Saving............"< fout.close();clrscr();}if(choice == ''2''){menuloop = 0;}if(choice == ''3''){clrscr();cout<<"Enter a file name to load ";cin.getline(filename,sizeof(filename-1));fin.open(filename);assert(! fin.fail());fin>>monster>>player>>x>>y>>num_potions;clrscr();cout<<"loading............"< fin.close();clrscr();}}};

##### Share on other sites
hey bitwhise, thanks for your help and code, ill take a look at it later (gotta goto class now)

what dont you understand my question? im trying to randomize the chances of an event happening, (a block of code to be executed) such as a monster dropping loot.

in the code using my function it would be:

((monster dies)))

drop_loot = random_bool();

if (drop_loot == true)
{
run code to drop loot;
}
else
{
dont run code to drop loot, in fact this statement shouldnt even be here;
}

the random_bool function (described in my first post) is a 50/50 chance of returning true or false, there fore, theres a 50/50 chance the monster will drop loot. understand what im doing here? is there simply better way to do this? thanks for any help. ps the way im doing it is working fine, im just curiouse as to if theres a better/faster/way and also to see if anyone else uses this.

ps- fixed typos in my first post that might have confused people

[edited by - graveyard filla on January 13, 2004 4:15:11 PM]

##### Share on other sites
One of my favorites returns a random number between one and n, where you pass n as a value.

int MyRand(int n)
{
return rand() % n;
}

If you need a boolean, just call MyRand(2).

BiTwhise pointed out that you could use the rand() function in your code. I prefer MyRand(x) because I think it reads more smoothly. It''s just personal prefrence.

-----------
VenDrake

"My stupid jar is full. I can''t talk to you anymore."

##### Share on other sites
I think your idea works great, however you might want to just make another function that would allow you to enter in a percent of how often it can happen so you could just let it take in a int and if you enter 20 then you look for numbers under 20, or 20% chance that way you can play with how often things happen

##### Share on other sites
Technically, rand() % n will only provide an even distribution if RAND_MAX + 1 is exactly divisible by n. In your case with rand() % 100, although your result will be close to 50/50, it won''t be exact. rand() % 2 will result in either 0 or 1, and will provide a perfectly even distribution, and thus perfect 50/50 chance. If you want to change it later to support various percentage chances, then here are a couple of functions I wrote just recently to help someone else:

int Random(int Min, int Max){  return (int)((Max - Min + 1) * (double)rand() / ((double)RAND_MAX + 1.0) + Min);}double Random(double Min, double Max){  return (Max - Min) * (double)rand() / (double)RAND_MAX + Min;}

You could then just use

//Floating Point Percentage
if (Random(0.0, 100.0) <= PercentageToOccur)) {}

or

//Integer Percentage
if (Random(1, 100) <= PercentageToOccur)) {}

Just remember that if you use the integer version instead of the floating point version, Random(0, 100) is in the range of 0-100, obviously, and thus involves 101 numbers, 51 of which will be <= 50, and 50 of which will be > 50. So you''d more appropriately need to use Random(1, 100), as I have above. The floating point form almost completely eliminates this issue. Although I guess the integer version is just as good as long as you''re a bit careful with the range used.

If you''re worried for speed, though, and well-distributed, perfectly 50/50 random numbers aren''t an issue, just using rand() % n is probably just about the best bet. Short of actually implementing your own version of a random number generator. (Which isn''t actually too hard, I just found out yesterday.)

##### Share on other sites
Just as a piece of advice, NEVER write something like

if (blah) {  foo = true;} else {  foo = false;}

foo = blah;

This avoids getting you laughed at.
In C, there''s no boolean, so it''s generally accepted that anything non-zero is true and zero is false (since that''s what the if condition looks for). So the direct assignment will be fine.
In C++, the result will be cast in the way that it needs to be (unless I''ve been smoking crack along with my Java).
In Java, the ''blah'' here has to result in a boolean anyway, so the assignment will definitely be no problem.

##### Share on other sites
I''ve heard that you shouldn''t use rand() for yes / no, since the least significant digits aren''t very random.

##### Share on other sites
thamior,

i cant get your code pasted into c++. it says too many characters or something. id really like to run youor program and look at your code. could you post the file, or tell me how to paste it? my email is graveyardfilla@hotmail.com . thanks.

1. 1
2. 2
Rutin
20
3. 3
khawk
18
4. 4
A4L
14
5. 5

• 12
• 16
• 26
• 10
• 44
• ### Forum Statistics

• Total Topics
633763
• Total Posts
3013728
×