Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / Couple of questions regarding the RANDOMIZE command

Author
Message
oDCo
20
Years of Service
User Offline
Joined: 11th May 2005
Location:
Posted: 18th May 2005 20:25
Hello All,

I've searched the forum for info on the RANDOMIZE command and found this thread: http://forum.thegamecreators.com/?m=forum_view&t=19241&b=10

However it's so old that I couldn't bump it with my question, so I'll just have to start a new thread.

I'm using the RND command a lot and like the person in the above thread, I'm getting numbers repeat. I know that by using the RANDOMIZE command I can eliminate this problem but I don't understand what exactly the RANDOMIZE command does or how it works. (Incidentally I don't understand how the RND command works either.)

Do I need to call the RANDOMIZE command everytime I'm going to call the RND command? Or do I only need to run it once at the start of the program? (I'm using the RND command with lots of different ranges through the course of my program if that makes any difference.)

Also, is the RANDOMIZE TIMER() still the best way of randomizing?

Thanks in advance,

David
BatVink
Moderator
22
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 19th May 2005 00:14 Edited at: 19th May 2005 00:18
Random numbers aren't actually random. There are just over 32,000 of them, and always follow the same sequence.

RANDOMIZE allows you to start at a different seed in the sequence. So, RANDOMIZE 1 will always start at position 1. So far, you are no better off!

RANDOMIZE TIMER() relies on the fact that you are highly unlikely to ever know what value TIMER() will return, as it changes 1,000 times a second. In effect, you are picking a random starting point, based on the millisecond that you call the command.

So far, so good.

Now, every time you use RND, you are still following the same sequence. the result is not truly random, but at least you don't know where you are amongst the 32,000 values, and it's not very likely that somebody will be able to predict the sequence.

If you want to add more randomness, you can call RANDOMIZE TIMER() more often. Then, you are constantly changing the seed

RND(n) picks a number between 0 and n. Don't worry about the fact that 32,000 numbers, and picking any range doesn't seem to hang together. RND() adjusts the values to suit the range you specify. I believe the numbers are actually between 0 and 1 internally.

BatVink
oDCo
20
Years of Service
User Offline
Joined: 11th May 2005
Location:
Posted: 19th May 2005 00:56
Ahhh, thanks BatVink, that explains a lot

I'll just run have to run RANDOMIZE before every RND.

Thanks again

David
Sven B
20
Years of Service
User Offline
Joined: 5th Jan 2005
Location: Belgium
Posted: 19th May 2005 01:17
One small problem: the rnd() command will allways return an integer value. this means that rnd(5.2365) will return 1, 2, 3, 4 or 5.

Here's a small snippet how to solve this:
oDCo
20
Years of Service
User Offline
Joined: 11th May 2005
Location:
Posted: 19th May 2005 03:36
Thanks Guys

Both of those posts are a great help
Underworld 1020
21
Years of Service
User Offline
Joined: 2nd Mar 2004
Location: NY, USA
Posted: 19th May 2005 05:25
it could return a 0 also.

oDCo
20
Years of Service
User Offline
Joined: 11th May 2005
Location:
Posted: 21st May 2005 07:32
Hello again,

I'm still a bit confused by this subject. If you run the code below, you'll be presented with a list of 10 numbers which (more often than not) aren't random . . . they're in sequence.



However, if you remove the SYNC commands, you appear to get random numbers each time . . . or I can't work out the sequence at least.



So, can someone explain why this is happening?

I'm actually having to create a lot of random numbers for a text-based project I'm working on, so not having the SYNC command isn't a huge problem . . . just a little annnoying.

Thanks in advance,

David
P Schnell
20
Years of Service
User Offline
Joined: 13th Feb 2005
Location:
Posted: 21st May 2005 10:09
For really random numbers, use this function:



No idea about the sync problem.

oDCo
20
Years of Service
User Offline
Joined: 11th May 2005
Location:
Posted: 21st May 2005 22:24
Hi Schnell, thanks for that idea for a function, it's saved me a load of code . . . I'd not thought to use a function

Back to the SYNC issue, I've now noticed (with fresh eyes) that even without the SYNC command, the numbers are still predictable . . . on my machine the value returned from each RND command is 37 less than the previous value (looping back to 100 at 0).

Can anyone think of a way to avoid this? I know we're not dealing with truly random numbers so there is a sequence somewhere, but there must be something I can do to help minimize the problem.

I'm basically returning values based on two random numbers, with this sequence problem it means that while the first random number will be random, the second (and third and forth in my project) are predictable. i.e.

value1 = 1
value2 = 2

value1 = 57
value2 = 58

value1 = 9
value2 = 10

As you can see, it's very fustrating, especially when you programing a game based on random numbers.

Thanks again,

David
Mentor
22
Years of Service
User Offline
Joined: 27th Aug 2002
Location: United Kingdom
Posted: 22nd May 2005 22:10 Edited at: 22nd May 2005 23:02
noooo! you got it all wrong, call randomise timer once after some delay like

press a key to start

nobody can press a key in exactly the same millisecond (unless they lean on it all through the program start) so you get apparently random times, the problem with the way you did it is it will return the same results since the code randomises from the timer at the same intervals, for example...

RANDOMIZE TIMER()
rnd01 = RND(99) + 1
WAIT 1

took 1.5 msecs

RANDOMIZE TIMER()
rnd02 = RND(99) + 1
WAIT 1

took 1.5 msecs

RANDOMIZE TIMER()
rnd03 = RND(99) + 1
WAIT 1

took 1.5 msecs

RANDOMIZE TIMER()
rnd04 = RND(99) + 1
WAIT 1

ETC

so what your code actualy did was

RANDOMIZE 1
rnd01 = RND(99) + 1
WAIT 1
RANDOMIZE 2 <<<<<<<1 + 1.5 msecs = 2.5 = 2 in integer
rnd02 = RND(99) + 1
WAIT 1
RANDOMIZE 4 <<<<<<< 2.5 msecs last time + 1.5 =4
rnd03 = RND(99) + 1
WAIT 1
RANDOMIZE 5 <<<<<<< 4 + 1.5 = 5.5 = 5
rnd04 = RND(99) + 1
WAIT 1
etc

all you need to do is to randomise timer once at the start of the code, all those extra randomises are just counting up in milliseconds from when the program started so you get mostly the same results (apart from when something lags slightly and delays the timer a bit..eg windoze does a swap to the swapfile)

timer()

gives a number in milliseconds since the system started

doing

do
cls
print timer()
loop

will give you the current timer value, if you call it too often (say every 1/10th of a millisecond) then you get the same number, if you call it every millisecond then you get something like

123
124
125
126
127
128

etc

what you need to do is to make your program have it called after a unpredictable amount of time, so add a random delay (like the time it takes the user to press space to continue) and your code will not run to the exact same number of milliseconds every time, otherwise your code takes the same number of milliseconds to reach your instructions and you get the same result, the other way to do it would be to randomize by the time from the system clock, (add the hours, minutes and seconds together) that way you would always get a different result unless the user started the program at exactly the same time each day (and if you added in the day, month and year then that would stop even that happening)eg:

do
cls
print get date$()
print get time$()
loop

is how you get the system date and time, this will always be different every time the program is run unless the user owns a time machine , so all you have to do is to extract the numbers from those strings and use them in the randomise command rather than the number from the timer, eg:



I hope that explains things a bit better.

Mentor.

PC1:XP, P4 3ghz, 1gig mem, 3x160gig hd`s, Radeon 9800pro, 6 way sound.
PC2: Linux, AMD 2ghz, 512mb ram, Nvidia GeForce4mx, 16 bit SB.
PC3: XP, laptop, intel 2.6ghz celeron, ATI 9000igp, 256mb
oDCo
20
Years of Service
User Offline
Joined: 11th May 2005
Location:
Posted: 23rd May 2005 04:37 Edited at: 23rd May 2005 04:38
Wow, it works . . . your code that is

I'll try intergrating that into what I've got and see how I get on. Basically though, I only need to run the randomize command once per loop . . . yes?

Also, I assuming it won't matter what the max number is each time I run the RND command . . . yes?

Thanks for taking the time to me help with this, I really appreciate it

David
Mentor
22
Years of Service
User Offline
Joined: 27th Aug 2002
Location: United Kingdom
Posted: 24th May 2005 03:09 Edited at: 24th May 2005 03:18
you only realy need to run the randomise command once per program, if you look at my example you can see that the command is outside the loop that prints the random numbers, try putting it inside the loop and see what happens, what will happen is that you will get one or two numbers repeated, the reason is that a main loop executes very fast, if you keep calling the loop with the time in seconds inside the randomise command, then the loop may execute 100 times in that second, so the randomise will use the same number (say 57 seconds) 100 times, and you get the same number 100 times, if you set the randomise OUTSIDE the loop, then every time you call rnd you get the next random number in the sequence starting at the position pointed to by the randomise command.

think of it this way, you have a book with 12332767 random numbers in it, one for every page, normaly you would read the book from the start, so each time rnd is called you read the number off page one, then page 2... etc, what randomise does is make the system start from a different page (eg page 1234 = randomise 1234), so although you are still reading the same sequence of numbers, you just start in a different page (don`t take this description literaly..but it`s near enough).

all you need to know is that randomize X will always give the same sequence, eg....

randomize 123
for i=1 to 10
print rnd(5);":";
next i
print
randomize 123
for i=1 to 10
print rnd(5);":";
next i
wait key

as soon as you call randomize with the same value, you get the same sequence of numbers, so what you need to avoid is calling randomize in the main loop, just calling rnd will give you the next random number, randomize just sets where in the list of random numbers you start, so call it once in the begining, then after that just use rnd, if you wanted to restart a random level and use the same sequence of numbers to make it, then you can call randomize again with the same number, and it will reset the rnd function to start from the same number it did on the last run, hope that helps.

Mentor.

PS: oh yeah!, you can call rnd as often as you like and with whatever range the integer value can hold (2,147,483,648 to -2,147,483,647), after a VERY large number of calls (several million) the sequence of random numbers will repeat, but by then you will be several years on in your life and should not be able to recall the numbers the program spat out 23 years ago, so this shouldn`t worry you too much.

PC1:XP, P4 3ghz, 1gig mem, 3x160gig hd`s, Radeon 9800pro, 6 way sound.
PC2: Linux, AMD 2ghz, 512mb ram, Nvidia GeForce4mx, 16 bit SB.
PC3: XP, laptop, intel 2.6ghz celeron, ATI 9000igp, 256mb
oDCo
20
Years of Service
User Offline
Joined: 11th May 2005
Location:
Posted: 24th May 2005 05:27
Eureka, I finally understand it!

You guys certainly know your stuff.

Thanks for being so patient with me, you've been a great help and I do really appreciate it

All the best,

David

Login to post a reply

Server time is: 2025-05-22 23:36:39
Your offset time is: 2025-05-22 23:36:39