Jump to content
ChilePepper

Random Numbers....

Recommended Posts

Hello, I have a question regarding the rand function. I looked at bB Commands page, but I couldn't find anything. (Maybe I'm not looking hard enough) But if in the program I call the rand function-thing, it will generate a random number. But if I call it later, instead of generating a new number, it just does the same number. How would I make it reset, so to speak. Thanks,

-ChilePepper

Share this post


Link to post
Share on other sites

I was talking about this awhile back, that random generation is not so random. Basically your best bet is to set a variable that can be used for the random number and you can preset it's seed value. Check this topic as it may help

 

 

  • Like 1

Share this post


Link to post
Share on other sites

The method I use is to have a counter variable incrementing while the title screen is going.  When the user exits the title screen I use that counter to seed the random number generator (i.e. "rand = counter")

 

The player is the best source for randomness as you can't count on RAM being dirty on initialization (to use it for seeding) with every emulator.

  • Like 2

Share this post


Link to post
Share on other sites
Posted (edited)
1 hour ago, Gemintronic said:

The method I use is to have a counter variable incrementing while the title screen is going.  When the user exits the title screen I use that counter to seed the random number generator (i.e. "rand = counter")

 

The player is the best source for randomness as you can't count on RAM being dirty on initialization (to use it for seeding) with every emulator.

Yep very much what i have used, you can even have that counter variable increment every frame and call a rand value to that variable before needing to use it. That way the counter value is constantly changing 60 times a second avoiding any patterns to appear, provided that call function is on demand rather then timed. It's one the most cycle efficient methods i have found so far without the need of complicated math routines.

 

Something like this

_main

 counter = counter + 1

 if _blahvar_1 && _blahvar_2 then counter = counter + rand : goto _blah_label

 drawscreen
 goto _main

 

I use this method for the random placement of the power station in City Defence, also very similar for the random warhead spawning.

Edited by TwentySixHundred
  • Like 1

Share this post


Link to post
Share on other sites

Sorry, but either I'm not understand you or you guys aren't understanding me. Here's a code example. If you compile and run this program you'll notice that even though your pressing fire, the number on screen won't change, because instead of generating a new number, the 'random' function is just using the same number as before. So my question is how do I make it so it generates a new number each time? Thanks again.

default.bas

Share this post


Link to post
Share on other sites
3 minutes ago, ChilePepper said:

Sorry, but either I'm not understand you or you guys aren't understanding me. Here's a code example. If you compile and run this program you'll notice that even though your pressing fire, the number on screen won't change, because instead of generating a new number, the 'random' function is just using the same number as before. So my question is how do I make it so it generates a new number each time? Thanks again.

default.bas 2.15 kB · 1 download

Thats because you have no condition, when you press fire you need to call the rand function. Have a look and see if you can spot the change i had made *untested code*random_condition.bas

Share this post


Link to post
Share on other sites
Posted (edited)
6 minutes ago, TwentySixHundred said:

*untested code*

sorry for being blunt, but it doesn't work.

Edited by ChilePepper

Share this post


Link to post
Share on other sites

you're not calling rand in the if satement just testing the rand variable

assign rand to a temp variable and test it

 

try

temp1 = rand

if temp1 < 100 then goto one

etc

Share this post


Link to post
Share on other sites

Thanks Bogax, your suggestion was what I was looking for. However, like TwentySixHundred was saying, rand is not very random, I am seeing patterns, so I'll be sure to check out that thread TSH was talking about. Thanks guys.

  • Like 1

Share this post


Link to post
Share on other sites

Okay thanks. So here's what I did:

 

dim rand16 = a

temp1 = rand16

 

there is still a pattern but its less noticeable. In the thread that he posted earlier, TwentySixHundred talked about how the numbers seemed to be hugging a certain area more than others. I think that is happening here as well perhaps? So how would I fix that with the rand16? Thanks again.

-ChilePepper

Share this post


Link to post
Share on other sites

You should still use the rand function even when you define a variable for rand16. The extra variable improves the randomness of the routine, but you don't use the variable directly yourself.

Share this post


Link to post
Share on other sites
18 minutes ago, ChilePepper said:

May you explain that in code please.

 

Examples:

   b = rand

   if rand < 32 then r = r + 1

   c = (rand&15)

 

Share this post


Link to post
Share on other sites
Posted (edited)

  rand is a counter that counts in a funny sequence

 

  here rnd and rnd16 are (something like) rand, only in bB

  this is set up for rand16. for rand you'd have to comment out the dim of rand16
  and change the gosub rnd16 in the if statement to gosub rnd

 

  dim sc0 = score
  dim sc1 = score + 1
  dim sc2 = score + 2
  dim r16 = s
  dim rand16 = z

  r = 1 : rand = 1 : r16 = 0 : rand16 = 0

  scorecolor = $44


loop
  if f && joy0fire then gosub rnd16 : temp2 = rand : gosub update_scr
  if joy0fire then f = 0 else f = 1

  drawscreen

  goto loop


rnd

  if r{0} then r = r/2 ^ $B4 else r = r/2
  temp1 = r
  return


rnd16
  temp1 = r16
  r16 = r16 * 2
  if r{0} then r16{0} = 1
  if temp1{7} then r = r/2 ^ $B4 else r = r/2
  temp1 = r ^ r16
  return

update_scr
   sc0 = 0 : sc1 = sc1 & 15
   if temp1 >= 100 then sc0 = sc0 + 16 : temp1 = temp1 - 100
   if temp1 >= 100 then sc0 = sc0 + 16 : temp1 = temp1 - 100
   if temp1 >= 50 then sc0 = sc0 + 5 : temp1 = temp1 - 50
   if temp1 >= 30 then sc0 = sc0 + 3 : temp1 = temp1 - 30
   if temp1 >= 20 then sc0 = sc0 + 2 : temp1 = temp1 - 20
   if temp1 >= 10 then sc0 = sc0 + 1 : temp1 = temp1 - 10
   sc1 = (temp1 * 4 * 4) | sc1

   sc1 = sc1 & 240 : sc2 = 0
   if temp2 >= 100 then sc1 = sc1 + 1 : temp2 = temp2 - 100
   if temp2 >= 100 then sc1 = sc1 + 1 : temp2 = temp2 - 100
   if temp2 >= 50 then sc2 = sc2 + 80 : temp2 = temp2 - 50
   if temp2 >= 30 then sc2 = sc2 + 48 : temp2 = temp2 - 30
   if temp2 >= 20 then sc2 = sc2 + 32 : temp2 = temp2 - 20
   if temp2 >= 10 then sc2 = sc2 + 16 : temp2 = temp2 - 10
   sc2 = sc2 | temp2
   return

basic_rand.bas.bin

Edited by bogax
elucidation

Share this post


Link to post
Share on other sites
Posted (edited)
On 4/28/2020 at 10:56 PM, ChilePepper said:

Thanks Bogax, your suggestion was what I was looking for. However, like TwentySixHundred was saying, rand is not very random, I am seeing patterns, so I'll be sure to check out that thread TSH was talking about. Thanks guys.

No problem, There really isn't right or wrong ways about it and many of methods people use. You only gotta have a read over at stackoverflow.com to see how many methods and theories people have to battle the age old issue of not so randomness. Computers in general struggle to provide true randomness as they calculate perfectly without imperfections. Randomness is caused from imperfections so it's not easy to replicate.

 

As for what i was trying to achieve, the method i was using basically was within a range of vales. So i wanted a random number from 4 to 154 IIRC and because rand uses the full byte i had to implement some math. This was to make sure if the value is out of range it would divide that value. IMO this division itself causes alot more patterns to appear because the math is set in stone (that's debatable and my observations). It seems the more math involved the more patterns emerge also mentioned my Spicware.

 

Now as for randomness and if you're wanting to use the full byte (0-255) it's alot easier to remove the patterns. From my end of experimentation with random number generation i have found what works for me and it's actually fairly simple. Basically like mentioned in the beginning using a counter variable really helps mix things up, rather then relying on the pseudo random number generated by the rand function. As batari's rand function IIRC seeds from 0 and cannot be changed AFAIK, it's highly likely for rand to produce the same number especially on the first call (common with every language it's just with some you can change the seed).

 

So what i like to do is less complex then you probably think:

 dim counter = z
 
 rem -------------------------main-----------------------
_main

 counter = counter + 1

 blah
 othercode
 blah
 othercode

 if blahblahblah then counter = counter + rand : goto _desired_outcome

_drawscreenloop
 drawscreen
 goto _main

 rem ----------------------- end of main -----------------

_desired_outcome

 blah
 blah
 blah

 goto _drawscreenloop

 

So you can see the counter variable is incrementing every loop and continuously rolling like a slot machine. Then the if statement is checking for a condition i called blahblahblah if that condition is met then it grabs the counter value and adds rand's pseudo number. So everytime you call rand no matter if it has a pattern or not, it's mixed up with that rolling value you add from the counter.

 

Basically it's just calling rand and whatever that rolling value is from counter then adds the two together giving a completely random number everytime. Although there is still the chance of hitting the same number twice like the luck of slot machines. All you need to do is read 'counter' after the (counter = counter + rand) math is complete, to pluck you random number.

 

 -Anthony

Edited by TwentySixHundred

Share this post


Link to post
Share on other sites

My 2 cents... randomness doesn't mean that the numbers output are uniform for any particular sequence of numbers, which is what people often expect.

 

Here's the bB 8-bit rand sequence...

 

random-bb8.thumb.png.1a49072f506048c859a3f606ee24d7aa.png

 

...and here's a 255 byte sequence I generated from random.org, which uses atmospheric noise as a source of entropy...

 

random-random_org.thumb.png.809338fb425dba3f97a041aaffabfa08.png

 

The bB is a little more clumpy to be sure, but I also see runs of similar numbers in the random.org data too. No sequence of random numbers will be completely uniform, except at very large scales.

 

As others have pointed out, you can improve the overall patterns in the bB generator by using the 16-bit LFSR (which I didn't create a chart for, to avoid "randomly" choosing a seed that happened to be a good or bad example.) and by favouring division over masking.

 

IMO the small unexpected patterns can be a strength. I use the same LFSR that's in bB to govern much of the enemy movement in my 7800 game Salvo. At times a particular enemy will change direction more frequently than others, which lends him a sense of individuality and character.

 

 

  • Like 3

Share this post


Link to post
Share on other sites
6 hours ago, RevEng said:

My 2 cents... randomness doesn't mean that the numbers output are uniform for any particular sequence of numbers, which is what people often expect.

 

Here's the bB 8-bit rand sequence...

 

random-bb8.thumb.png.1a49072f506048c859a3f606ee24d7aa.png

 

...and here's a 255 byte sequence I generated from random.org, which uses atmospheric noise as a source of entropy...

 

random-random_org.thumb.png.809338fb425dba3f97a041aaffabfa08.png

 

 

 

What did you use to graph them?

Share this post


Link to post
Share on other sites

I imported the data into LibreOffice Calc (the free excel clone) and created the graphs there.

 

The bB LFSR data came from a C re-implementation I did a while back.

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, RevEng said:

My 2 cents... randomness doesn't mean that the numbers output are uniform for any particular sequence of numbers, which is what people often expect.

 

Here's the bB 8-bit rand sequence...

 

random-bb8.thumb.png.1a49072f506048c859a3f606ee24d7aa.png

 

...and here's a 255 byte sequence I generated from random.org, which uses atmospheric noise as a source of entropy...

 

random-random_org.thumb.png.809338fb425dba3f97a041aaffabfa08.png

 

The bB is a little more clumpy to be sure, but I also see runs of similar numbers in the random.org data too. No sequence of random numbers will be completely uniform, except at very large scales.

 

As others have pointed out, you can improve the overall patterns in the bB generator by using the 16-bit LFSR (which I didn't create a chart for, to avoid "randomly" choosing a seed that happened to be a good or bad example.) and by favouring division over masking.

 

IMO the small unexpected patterns can be a strength. I use the same LFSR that's in bB to govern much of the enemy movement in my 7800 game Salvo. At times a particular enemy will change direction more frequently than others, which lends him a sense of individuality and character.

 

 


wont the sequence of numbers be completely uniform over the period of the PRNG? 
 

So, 8bit PRNG repeat each number every 255 samples, 16-bit every 65535 samples, etc. (if they have maximal periods).

 

i suppose the trouble comes I when you want an equal distribution of numbers in a range other than 1-255, or 1-65535, ... and instead something like 1-20. To generate an equal distribution of numbers in those ranges would require throwing out results that aren’t in the range, or would require a more complicated algorithm for obtaining the results. 
 

It probably goes over board, but Mersenne Twister I believe does some complicated math to ensure that you can get equal (or close to equal) distributions of numbers in any range. I wouldn’t want to implement it on an 8-bit 1 MHz CPU though.

https://en.m.wikipedia.org/wiki/Mersenne_Twister

 

Share this post


Link to post
Share on other sites
51 minutes ago, CapitanClassic said:


wont the sequence of numbers be completely uniform over the period of the PRNG? 

 

Yes, that's what I meant by "large scales". The people who say the numbers aren't random enough because they see a pattern aren't viewing all 255 values in the 8-bit LFSR, or all 65535 in the 16-bit LFSR. They're seeing a run of similar values in a small sampling.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...