Jump to content
TwentySixHundred

Random Number Generation

Recommended Posts

Hi guys, im playing around trying to generate random numbers from 0-154 or preferably 4-154. However im seeing glaring patterns no matter what i try. It seems whatever the math it tries to hug one area more then the other, for example.

 

Something like this tends to hug the middle range more then anything.

(rand/4) + (rand&31) + (rand&15) + (rand&15) + (rand&15) + (rand&3) + 12

 

Then something like this will tend to hug the higher range more.

(rand/4) + (rand&31) + (rand&15) + (rand&15) + (rand&3) + 27

 

And something else i was playing around with was hugging the lower range more often. Im finding random is not-so random and other places on the net have mentioned, it's quite tricky to generate random numbers without patterns emerging. The question i have is what are the best and fastest ways to overcome this issue, if possible?

 

I mean im having more luck with wrapping the the sprites out of bounds with higher values then the said desired range. The only issue with that is the odd sprite that the wrap around is visible on both side of the screen.

Share this post


Link to post
Share on other sites

When I was working on Seaweed Assault, I had to mix division with & in the right combination. I just kept playing with it until the glaring patterns were gone. You'll probably end up alternating them (division, &, division, & . . .).

  • Thanks 1

Share this post


Link to post
Share on other sites
20 minutes ago, Random Terrain said:

When I was working on Seaweed Assault, I had to mix division with & in the right combination. I just kept playing with it until the glaring patterns were gone. You'll probably end up alternating them (division, &, division, & . . .).

 

I was actually just thinking if that would work, i have a feeling this part could too uniform but not sure.

(rand&15) + (rand&15) + (rand&15)

 

This is the best setup i have got so far however like i was saying it's heavily generating numbers within the mid range

(rand/4) + (rand&31) + (rand&15) + (rand&15) + (rand&15) + (rand&3) + 12

 

I will try mixing it up with some extra division and shuffle them all around to see what happens.

Edited by TwentySixHundred

Share this post


Link to post
Share on other sites

Yeah, instead of this:

 

(rand/4) + (rand&31) + (rand&15) + (rand&15) + (rand&15) + (rand&3) + 12

 

You'd try this:

 

(rand/4) + (rand&31) + (rand/16) + (rand&15) + (rand/16) + (rand&3) + 12

 

If that doesn't work, alternate them the other way. If that doesn't work, try other combinations. You'll find something that works.

Share this post


Link to post
Share on other sites
17 minutes ago, Random Terrain said:

Yeah, instead of this:

 

(rand/4) + (rand&31) + (rand&15) + (rand&15) + (rand&15) + (rand&3) + 12

 

You'd try this:

 

(rand/4) + (rand&31) + (rand/16) + (rand&15) + (rand/16) + (rand&3) + 12

 

If that doesn't work, alternate them the other way. If that doesn't work, try other combinations. You'll find something that works.

Thanks i have managed to fan it out a bit more with this

(rand/16) + (rand&15) + (rand/4) + (rand&31) + (rand&15) + (rand/64) + 12

 

However it's the extreme highs and lows it struggles to generate like say a 4 or 150. Still hugs the middle range more then id like. I want the middle range more so although need the highs and lows to generate more often then they do. Might keep playing around with the combination, i was hoping the rand/64 at the end would shuffle the chances some more.

Share this post


Link to post
Share on other sites

If you find the perfect combination, be sure to post it. I wonder if there is a difference between DPC+ results and rand16 standard kernel results.

Share this post


Link to post
Share on other sites
8 minutes ago, Random Terrain said:

If you find the perfect combination, be sure to post it. I wonder if there is a difference between DPC+ results and rand16 standard kernel results.

Will do, i have a test program going however still haven't found anything im happy with yet. I will keep plugging away 👍The ability to change the rand seed would be great however with what im trying doesn't seem to have much effect

Edited by TwentySixHundred

Share this post


Link to post
Share on other sites

The more ranges you add together, the more of a bell curve effect you will get with probabilities toward the center of the range, as you observed. Maybe someone else can come up with a better suggestion, but this one would at least give a much less steep bell curve, and might be good enough for your purposes:

    Position = rand ; (0-255)
    If Position > 150 then Position = Position - 128 (23-127)
    Position = Position + 4 (4-154)

This will still have a slight bias away from the extreme ends of the range, but much less so, I think. I'm interested in hearing if others have cleaner solutions, though.

Share this post


Link to post
Share on other sites
7 minutes ago, Karl G said:

The more ranges you add together, the more of a bell curve effect you will get with probabilities toward the center of the range, as you observed. Maybe someone else can come up with a better suggestion, but this one would at least give a much less steep bell curve, and might be good enough for your purposes:

    Position = rand ; (0-255)
    If Position > 150 then Position = Position - 128 (23-127)
    Position = Position + 4 (4-154)

This will still have a slight bias away from the extreme ends of the range, but much less so, I think. I'm interested in hearing if others have cleaner solutions, though.

Thanks Karl, yeah i was just experimenting with something similar. Was trying to pre-seed the playerx position with a rand number then have the code below make the final randomization. Very buggy at the moment as i think it's causing the sprites to wrap around. However there is some really random placement happening. I like your method and will have a play around with it 👍

(rand/16) + (rand&15) + (rand/4) + (rand&31) + (rand&15) + (rand/64) + 12

Share this post


Link to post
Share on other sites

Well i managed to get nice randomization by randomizing a seed then adding the value of that seed to rand. It's not perfect however it seems to work quite nicely for a quick throw together. When i have a fresh set of eyes tomorrow i will see what tweaks can be done as im sure there is room for fine tuning. Anyway here is the bas and bin

 

Random Generation.bin

Random Generation.bas

  • Like 1

Share this post


Link to post
Share on other sites
2 hours ago, SpiceWare said:
  • (Random32() & 0xff) = 0-255
  • 151 * = 0 - 38505
  • >> 8 = 0 - 150
  • + 4 = 4 - 154

Since you are here anyway, how would you do it in bB or 6502 ASM?  🙂 

 

Edit: I mean as a best approximation, rather than trying to do 32-bit operations.

Share this post


Link to post
Share on other sites
13 minutes ago, Karl G said:

Since you are here anyway, how would you do it in bB or 6502 ASM?  🙂 

 

Edit: I mean as a best approximation, rather than trying to do 32-bit operations.

 

I would do what they're doing, but with as few rand as possible. So for bB:

(rand & 127) + (rand & 15) + (rand & 7) + 4

which would be 4-153.  Can add (rand & 1) if you absolutely must have 4-154.

 

The other thing I would do is use rand once every frame, but discard the value.  I cover this in step 10 - "Random Numbers" of my Collect Tutorial.

 

Quote

One thing that helps when using an LFSR is to keep reading values at a regular rate, even if you don't need the value. What this does is impose an element outside of the Atari's control - namely the time it takes the human to do things: hit the RESET switch to start a game, collect the next box, etc. I've added this to VerticalBlank
 

VerticalBlank:
        jsr Random
...

 

 

Likewise step 10 includes example asm code to get a random position.

Share this post


Link to post
Share on other sites

here's one. not perfect

 

temp1 = rand/2: temp1 = (((((temp1/2 + temp1)/2 + temp1)/2 +temp1)/2 + temp1)/4 + temp1)/8 + temp1 + 4

Edited by bogax
  • Like 2

Share this post


Link to post
Share on other sites
8 hours ago, SpiceWare said:

@TwentySixHundred - I see you're a member of the Harmony/Melody Club.  One of the things you have to look forward to is:

 

position = ((151 * (Random32() & 0xff)) >> 8) + 4;
  • (Random32() & 0xff) = 0-255
  • 151 * = 0 - 38505
  • >> 8 = 0 - 150
  • + 4 = 4 - 154

 

That will be a breath of fresh air to have 32bit operations, yeah i have a read over at the club every now and then. Always something new to learn and possibly can translate some of the methods used into bB. That does look very similar to the examples in C over at Stackoverflow 👍

5 hours ago, SpiceWare said:

 

I would do what they're doing, but with as few rand as possible. So for bB:

(rand & 127) + (rand & 15) + (rand & 7) + 4

which would be 4-153.  Can add (rand & 1) if you absolutely must have 4-154.

I am thinking that's the best possible way however incorporating the method i found works best with using a variable "seed" to randomize the overall rand value before this statement. So rather then the general pseudo random number generated that is seeded from a zero (i assume). It's got a rolling variable to mix up the final results. I have noticed the longer it runs the more random it becomes.

 

However with still having this

(rand & 127) + (rand & 15) + (rand & 7) + 4

I find will be the soother way to keep that random value within the boundaries, although the part i need to work out is how to incorporate that random fed variable along with rand into the statement. I feel replacing rand with seed alone won't be enough to yield the desired results.

Share this post


Link to post
Share on other sites

So with the method i was using previously by simply changing the seed variable to a float (8.8 fixed point) there seems to be more randomness. Obviously the actual positioning of the sprites will still be to the nearest integer, however having the remainder adds that further refinement. Probably nothing too major and i doubt worth the loss of an additional variable, never-the-less it seems to mix things up a bit more.

 

Random_Number_Generation.bas

Random_Number_Generation.bin

  • Like 1

Share this post


Link to post
Share on other sites
On 2/18/2020 at 9:46 PM, bogax said:

here's one. not perfect

 

temp1 = rand/2: temp1 = (((((temp1/2 + temp1)/2 + temp1)/2 +temp1)/2 + temp1)/4 + temp1)/8 + temp1 + 4

It's about as even a distribution as you can get, in 8 bits.  :thumbsup:

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...