Controlling the Random operator...
Kaos Kidd
Posts: 614
I have this nifty little program that, while waiting for a keypress, it constantly reseeds the random number generator:
Now this works great, but I can't seem to get "controll" of the random number.
Could someone please share with me either the 'insides' of Chips random code in the VGA HiRes Text Demo or Spell out what is needed to get a random number between X and Y.
Thanks!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
PRI RndNumber | InKey, Temp InKey := 0 REPEAT WHILE Inkey == 0 Temp := ?Temp RETURN Temp
Now this works great, but I can't seem to get "controll" of the random number.
Could someone please share with me either the 'insides' of Chips random code in the VGA HiRes Text Demo or Spell out what is needed to get a random number between X and Y.
Thanks!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
Comments
?variable runs one direction.
variable? runs the other direction.
The value returned·and written back to the variable is a 32-step iteration of a maximal-length LFSR. In other words, every bit gets replaced and it will only repeat after 4,294,967,295 iterations (2 exp 32 - 1).
The best way to 'randomize' the seed is to increment it, since sequential numbers are, on average, separated by huge runs of other numbers when doing ?variable or variable?.
So, when sitting idle, do variable++. When wanting random numbers, use variable? or ?variable. Remember that where the ? is determines which direction to sequence in.
You might want to experiment by printing out successive values onto a tv or vga monitor. They are best looked at in hex (term.hex(?variable, 8)).
In case the initial value is 0, it will be set to 1 before being iterated.
Have fun!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chip Gracey
Parallax, Inc.
To answer your last question, the following subroutine will return a random integer between x and y, inclusive:
seed is a long VAR, which you can initialize (randomize) if you like. x and y can be negative, positive, or mixed; but x should always be less than or equal to y.
I cant prove this yet, but I'll get some time on it tonight.
Thanks again !
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
Don't use Seed as an argument to the subroutine: it's a pass-by-value parameter that won't get updated. Just let the subroutine access it as a global variable.
As to the math:
1. ? returns a random number between 1 and 2^32-1. Since this could be negative, and ** is a signed operation, we shift it right by one to make sure it's positive.
2. The values we want to return range over a span of MaxValue - MinValue + 1, so we need to compute a random number covering that range.
3. ** in effect treats one of its multipliers as a fraction less than 1. But since we've already shifted the random number right by one, it'll be less than 0.5.
4. Because the random multiplier ranges to 0.5, we have to shift the multiplicand left by 1.
5. Once we do the multiply, we have a number that ranges between 0 and (MaxValue - MinValue).
6. Adding MinValue, that number will now range from MinValue to MaxValue.
-Phil
Seed := cnt
whether you ask for user input only depends on if you want the program to wait on the user. Ive found that using the counter produces sufficently random seeds for everyday needs.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Life is one giant teacup ride.
Thanks for the light...
Paul: By using cnt, you will always get the SAME random number set every time the chip is restarted. This would equate to a very unrandom outcome within the app. By having the app start, then wait for the user to press a key (and I use the clear the keyboard buffer), you force a different seed, be it cnt or a var. I like your idea to use cnt tho, it would save 3 longs in ram, better RAM usage...
I would still force the user to press something to start, therefore forcing a different value into cnt every time the app is started. And, as you metioned, it's part of the "start up" for the app...
I discovered that by using a DAT {Name} BYTE {value},{value},{value}... i basically have a pre init array accessed with a simple {Name}[noparse][[/noparse]Index] This is great! I have one quick question about indexing on the DAT lables:
Can a negitive Index be used?
Example:
DAT
TOP BYTE 1,2,4,8,16,32,64,128,256
MID BYTE 5,7,9,13,17,19,23,27,29
BOT BYTE 2,4,6,8,10,12,14,16,18,20
Index := -5
Value = MID[noparse][[/noparse]Index]
Would value = 16 ?
Thanks again every one...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Life is one giant teacup ride.
Paul:
When ever I use the CNT, I get the exact same sequence of numbers. This is because the Prop runs at the same speed, and executes the exact number of instructions each time leading up to the point where CNT is caputured for the random number seed. Clearing the keyboard, and forcing the user to press a key, forces a underterminable number of extra "cycles" before it's captured, thus usable. I ran the test 100 times, testing for identicle numbers, and it proved true 100 times.
The end result is this:
I clear the keyborad buffer, then wait for a key press, each time through the keypress loop I increment the seed value (which was pre-seeded before the loop with cnt).
Once I have my random number seed, it remains throughout this segment of the run.
I drop into a loop 52 times...
I get a random number between 1 & 13 (Value) and a second random number between 0 & 3 (suit)
I use a case statement like:
CASE Suit
0: Card := %0000_0000 + Value
1: Card := %0001_0000 + Value
2: Card := %0010_0000 + Value
3: Card := %0100_0000 + Value
Next, I run through the card array, checking for card, if found, I repeat the above "find" loop
I insert the card into the array, increment the card count.
Bits 0~3 are the card values, Bits 4~6 are the suites, Bit 7 is a flag for face up / down.
Is there a better way of randomizing and getting the bits 4~6 like the case statement?
(Sorry about the duplicated posts, my connection was timing out all night last night, anyway... I fixed that....)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Life is one giant teacup ride.
Ya, you could be right, but then I would have used "user" and not "operator"...
LOL..
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
comments and crits are always welcome
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
I wrote this code in my browser so I haven't tested to see if it works or even compiles.
Also, I apologize if I completely misinterpreted what you're trying to do.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
I hadn't thought of that approch, much better usage of ram and time...
Basically I'v packed the deck into a byte with the value of 0 reserved for no card, bit 7 is reserved for face up/down
01~13 = D %X000_0001 ~ %X000_1101
16~29 = C %X001_0001 ~ %X001_1101
32~45 = H %X010_0001 ~ %X010_1101
64~77 = S %X100_0001 ~ %X100_1101
It took about 2 or 3 seconds to make a deck, but from what I see in your code, it would take a fraction of a second or so.
I'll put that in place tonight and play with it...
I see how your moving suite into the right bit place with the << 4 and adding the value (nice...) , but what ia the | <idx >> 1 doing?
I think its taking the value of IDX and making it a bit. So if it's 3, then it would set idx = %00000000_00000000_00000000_00000100.
If it was 7 (for example), then it would set idx = %00000000_00000000_00000000_01000000, not %00000000_00000000_00000000_01111111, right?
Ok, that's fine, thats what the docs say, but what is the >> 1, right shifting it back 1?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
The |< operator is basically the same as "2 to the power of". So |< 0 is 1 (2 ^ 0) and |< 3 is 8 (2 ^ 3). Using |< idx gives the values 1, 2, 4, & 8 for the values 0-3. Since your suit value is 0, 1, 2, or 4, you have to shift the result right one bit.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
Your code works as it stands, and it does run in fractions of a second. Cool.
Next thing up is getting the array indexing right...
Thanks again everyone...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·