"random" numbers

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
nathanf534
Posts: 199
Joined: Tue Dec 09, 2008 2:55 am

"random" numbers

Post by nathanf534 »

ok.. so i have a Dice class that i am using for a risk game. 3 dice for attacker, 2 for defender...
when i call dice.roll() it "randomly" picks a number from 1-6 for the dice...etc
the first time i ran the game, it worked nicely...
the second time appears nice...
third time, i got suspicious, and looked at the rolls more closely

every battle, each round rolls the same as the last battle, every time, exactly
for example, this is what it keeps rolling (in order of attacking, then defending dice, each row is another "roll")

66556
55355
35455
41625
21116
64532
end of attack

this exact same rolls happen everytime i start a game
here is the Dice class



Code: Select all

class Dice{
 public:
    int number;
    int drawNumber;
    int x;
    int y;
    int relx;
    int rely;
    int rolling;
    IGUIElement* parent;
    void roll(bool keep=true){
        drawNumber=(rand()%6)+1;
        if(keep)number=drawNumber; 
    }
    void animateRolling(){
        rolling=60;    
    }
    void updateAnimation(){
        if(rolling==0)return;
        if(rolling%5==0)roll(false);
        rolling--;
        if(rolling==0)drawNumber=number;     
    }
    void setPos(int x1, int y1){
        relx=x1;
        rely=y1;     
    }
    void setParent(IGUIElement* p){
        parent=p;    
    }
    void updatePosition(){
        rect<s32> prev=parent->getRelativePosition();
        x=prev.UpperLeftCorner.X+relx;
        y=prev.UpperLeftCorner.Y+rely;  
    }
    void draw(){
        this->updatePosition();
        this->updateAnimation();
        Video->draw2DRectangle(White2,rect<s32>(x,y,x+30,y+30));
        if(drawNumber%2==1)Video->draw2DRectangle(Black2,rect<s32>(x+12,y+12,x+18,y+18));
        if(drawNumber!=1){
            Video->draw2DRectangle(Black2,rect<s32>(x+22,y+22,x+28,y+28));
            Video->draw2DRectangle(Black2,rect<s32>(x+2,y+2,x+8,y+8));    
        }
        if(drawNumber>3){
            Video->draw2DRectangle(Black2,rect<s32>(x+22,y+2,x+28,y+8));
            Video->draw2DRectangle(Black2,rect<s32>(x+2,y+22,x+8,y+28));                
        }
        if(drawNumber==6){
            Video->draw2DRectangle(Black2,rect<s32>(x+2,y+12,x+8,y+18));
            Video->draw2DRectangle(Black2,rect<s32>(x+22,y+12,x+28,y+18));                  
        }
                                                
    }
};
and i know that the method im using won't produce perfect random number... but what im getting is just crazy

rand() uses:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
while(signatureEmpty){cout<<wittyComment();}
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

this is totaly normal, because there are no real random numbers !!! :lol:
the rand function always starts with the same initial value when starting the program and so you'll get always the same numbers...
you'll have to seed the algorythm with a different value before using rand(), usually you'll use the actual time for this... ;)
look for srand(..) for this...
Last edited by Acki on Thu Mar 12, 2009 7:40 pm, edited 2 times in total.
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
nathanf534
Posts: 199
Joined: Tue Dec 09, 2008 2:55 am

Post by nathanf534 »

ahh, thanks very much, i totally forgot about seeding
while(signatureEmpty){cout<<wittyComment();}
Vandrick
Posts: 13
Joined: Sat Feb 21, 2009 5:37 am

Post by Vandrick »

I like my numbers to be very random so I wrote my own random functions not based off rand().

Code: Select all

#include <time.h>

bool RandomChance(s32 Chance);
bool RandomChance(float Chance);
s32 Random(s32 min, s32 max);
float Random(float min, float max);
s32 SystemTimeRet(SYSTEMTIME* Sys);


bool RandomChance(s32 Chance)
{
	if(Chance>=100)
		return 1;
	else if(Chance<=-1)
		return 0;

	if((Chance*100)>=Random(0,10000))
		return 1;
	else
		return 0;
}

bool RandomChance(float Chance)
{
	if(Chance>=100)
		return 1;
	else if(Chance<=-1)
		return 0;

	if((Chance*100)>=Random(0,10000))
		return 1;
	else
		return 0;
}

s32 Random(s32 min, s32 max)
{
	if(min == max)
		return min;
	u32 Clock = clock();
	SYSTEMTIME sysTime;
    GetLocalTime(&sysTime);
	u32 Time = SystemTimeRet(&sysTime);
	__asm{
		mov ebx,RandomTimer
		mov eax,Time
		xor ebx,eax
		mov RandomTimer,ebx
	};
	RandomTimer=abs((int)(RandomTimer+clock()));
	return (RandomTimer%((max+min)+1))-min;
}

float Random(float min, float max)
{
	if(min==max)
		return min;
	DWORD BeforeThePointMin = (s32)min;
	DWORD BeforeThePointMax = (s32)max;
	DWORD AfterThePointMin = 0;
	DWORD AfterThePointMax = 0;
	DWORD BeforeThePoint = 0;
	DWORD AfterThePoint = 0;

	float DecDeDuct = 0;
	if(BeforeThePointMax!=0)DecDeDuct=BeforeThePointMax-max;
	else DecDeDuct=max;
	AfterThePointMax = (s32)(DecDeDuct*1000000000);//(BeforeThePointMax-(max))*1000000000;
	if(BeforeThePointMin!=BeforeThePointMax)
		AfterThePointMax += 999999999;
	DecDeDuct = 0;
	if(BeforeThePointMin!=0)DecDeDuct=BeforeThePointMin-min;
	else DecDeDuct=min;
	AfterThePointMin = (s32)(DecDeDuct*1000000000);//(BeforeThePointMin-(min))*1000000000;
	
	AfterThePoint = Random((s32)AfterThePointMin, (s32)AfterThePointMax);

	BeforeThePoint = Random((s32)BeforeThePointMin, (s32)BeforeThePointMax);
	
	return ((float)BeforeThePoint+(AfterThePoint*0.000000001f));
}

s32 SystemTimeRet(SYSTEMTIME* Sys)
{
	s32 RetVal = 0;
	__asm{
		mov eax,Sys
		mov ecx,[eax]
		add ecx,[eax+0x04]
		add ecx,[eax+0x08]
		add ecx,[eax+0x0C]
		mov RetVal,ecx
	}
	
	return RetVal;

}
I know the Random Float code isnt perfect but it works for what I need it to do.
Post Reply