Random Seed — Parallax Forums

# Random Seed

Posts: 130

Can someone please correct this program so that all 6 numbers are randomized?
currently all numbers are the same all the time. Thanks

' {\$STAMP BS2}
' {\$PBASIC 2.5}
' lotto ex 3

seed VAR Byte
total VAR Nib

DO
seed = seed + 1
RANDOM seed
DEBUG DEC2 seed ," " //70,CR
PAUSE 500
total = total + 1
LOOP UNTIL (total = 6)

• Posts: 23,514

What's the " " for? You're printing " " // 70, which equals 32 every time, assuming BASIC is interpreting " " as a number in this context. Try eliminating the ," " so you're printing DEC2 seed // 70, which I think is what you want.

-Phil

• Posts: 130

eliminating " " will cause error. Replaced DEBUG DEC2 seed ," " //70,CR with DEBUG DEC 2 seed, CR.
The results are 6 constants numbers 24,56,62,90,50,25. They are not random and the number 99 appears. All numbers should be less than 71.

• Posts: 23,514
edited 2022-09-23 21:20

You have to eliminate the comma that precedes the " ", too. This does not produce an error:

```' {\$STAMP BS2}
' {\$PBASIC 2.5}
' lotto ex 3

seed VAR Byte
total VAR Nib

DO
seed = seed + 1
RANDOM seed
DEBUG DEC2 seed // 70,CR
PAUSE 500
total = total + 1
LOOP UNTIL (total = 6)
```

although it's probably still not what you want. BTW,

1. Eliminate the seed = seed + 1. It's not necessary.
2. To include 70 as a possible result (and exclude 0), write DEC2 seed // 70 + 1. The expression seed // 70 produces numbers 0 to 69.
3. seed should be declared a word, not a byte, for best results.
4. Your program will always produce the same sequence of numbers. That's because RANDOMIZE does not really produce a random number. It only produces the next number in a pseudorandom sequence. One way to start with a truly random number is to wait for an input from the keyboard while incrementing seed.

-Phil

• Posts: 130

I would like to randomize 6 numbers without using external keyboard input. Is it possible ? It's possible using MS Excel.

If I resolve this this problem I will share with Ken Gracey.

• Posts: 23,514

You'll need some kind of random external input to start, since the BASIC Stamp doesn't have a random element built-in.

Google "digital noise generator circuit" for some ideas. Stay away from circuits that use just gates and shift registers, since they produce the same pseudorandom sequences as RANDOMIZE. You need something with an analog element to produce a true random signal.

-Phil

• Posts: 8,393
edited 2022-09-24 20:01

Can someone please correct this program so that all 6 numbers are randomized?

As Phil pointed out, the BS2 does not have true random behavior, it has a PRNG (pseudo-random number generator) function which is a fancy way to say that RANDOM produces a series of values that seem random, but are not. If you give RANDOM the same seed, it will give you the same result. In your program, seed always starts at 0.

It's been a while since I've coded in BASIC, but a few years back the end of summer meant I would write countless control programs for haunted houses, and many of them require random behavior. What I typically do is employ an external trigger mechanism. Note that when the trigger is not active, the RANDOM function is being called. Think of this as stirring the cage of lotto balls before making a draw. Given the stimulus is external, you can get better random values. Note, too, that RANDOM wants to work with a word variable (as Phil also pointed out); you should do this to give the full range to the function.

```Reset:
DEBUG CLS, "Lottery Demo", CR, CR

FOR ballCnt = 0 TO 5                          ' set ball slots to empty
ball(ballCnt) = EMPTY
NEXT

ballCnt = 0

' -----[ Program Code ]----------------------------------------------------

Main:
timer = 0                                     ' reset timer
DO
RANDOM lottery                              ' stir random value
PAUSE 5
timer = (timer + 5) * Trigger               ' re-scan trigger input
LOOP WHILE (timer < 25)                       ' wait for valid trigger

Draw:
RANDOM lottery
ball(ballCnt) = lottery // R_SPAN + R_MIN     ' create ball
FOR check = 0 TO 5                            ' validate
IF check < ballCnt THEN
IF ball(ballCnt) = ball(check) THEN       ' if repeat
GOTO Draw                               '  try again
ENDIF
ENDIF
NEXT

DEBUG DEC2 ball(ballCnt), " "                 ' display new ball
ballCnt = ballCnt + 1                         ' update count
IF ballCnt < 6 THEN                           ' if not done
PAUSE 250                                   ' wait a bit
DO WHILE (Trigger = IS_ON)                  ' force button release
' hold
LOOP
GOTO Main
ENDIF

DEBUG CR, CR, "Done!"

STOP
```

This is the output from the program (see attached for full listing).

PS: If this is a homework assignment and you didn't identify it as such, shame on you.

PPS: Quick and dirty is never quick, but it's always dirty. Take the time to write a program that works well, then optimize it after. Looking at the program now there is no need to set the array to empty. I'll let you remove that code.

• Posts: 130

If I copy the above instructions the program will not run. Variables are missing.
The statement "ball(ballCnt) = EMPTY". Is EMPTY a subroutine?

• Posts: 1,173

Its been a LONG time since I played with the BS2, but I walked this road once and had good success getting fairly random seeds to plug into RANDOMIZE. The idea is to use an external RC circuit with the cheapest, sloppiest components you can find.

Repeatedly charge and discharge that RC circuit using RCTIME. Each time you do, you will get a slightly different value. If the value is even, call it a “1”. If odd, call it a “0”. String as many of these “bits” together as you need to get your seed. Feed that into RANDOMIZE (or just use them directly). This is far from perfect, but you’d be surprised how well it works. Just use really awful tolerance components for best effect. (Heck, you could use a thermistor for the R component if you wanted).

• Posts: 8,393
edited 2022-09-24 20:08

You:

If I copy the above instructions the program will not run. Variables are missing.
The statement "ball(ballCnt) = EMPTY". Is EMPTY a subroutine?

Me:

This is the output from the program (see attached for full listing).

For some reason, the attachment didn't stick. It is there now. Sorry about that.

To do a "draw" I press a button that is connected to P15. There is a 10K pull-down on P15, with a N.O. button connected between P15 and 5v.

• Posts: 23,514

Repeatedly charge and discharge that RC circuit using RCTIME. Each time you do, you will get a slightly different value. If the value is even, call it a “1”. If odd, call it a “0”. String as many of these “bits” together as you need to get your seed. Feed that into RANDOMIZE (or just use them directly). This is far from perfect, but you’d be surprised how well it works. Just use really awful tolerance components for best effect. (Heck, you could use a thermistor for the R component if you wanted).

I'll second that approach. Even better would be to take two RCTIME readings. If the first is larger than the second, shift a 0 into seed. If the second is larger than the first, shift in a 1. Otherwise, do it over. This produces a completely unbiased, independent, random choice for each bit.

-Phil

• Posts: 1,173

@"Phil Pilgrim (PhiPi)" said:

Repeatedly charge and discharge that RC circuit using RCTIME. Each time you do, you will get a slightly different value. If the value is even, call it a “1”. If odd, call it a “0”. String as many of these “bits” together as you need to get your seed. Feed that into RANDOMIZE (or just use them directly). This is far from perfect, but you’d be surprised how well it works. Just use really awful tolerance components for best effect. (Heck, you could use a thermistor for the R component if you wanted).

I'll second that approach. Even better would be to take two RCTIME readings. If the first is larger than the second, shift a 0 into seed. If the second is larger than the first, shift in a 1. Otherwise, do it over. This produces a completely unbiased, independent, random choice for each bit.

-Phil

I LIKE this approach!.I never really thought it thru like that until now. 👍

• Posts: 23,514

I LIKE this approach!.I never really thought it thru like that until now. 👍

I can't really take credit for it. It's used in Chip's RealRandom Propeller object, and he credit's John Von Neumann for the original idea on how to obtain unbiased coin flips from a biased coin.

-Phil

• Posts: 130

"To do a "draw" I press a button that is connected to P15. There is a 10K pull-down on P15, with a N.O. button connected between P15 and 5v."

When I press button the results are random for 5 numbers. However the number 60 appears first and every time.

• Posts: 1,524

@"Phil Pilgrim (PhiPi)" said:

I can't really take credit for it. It's used in Chip's RealRandom Propeller object, and he credit's John Von Neumann for the original idea on how to obtain unbiased coin flips from a biased coin.

-Phil

In case of curiosity about the contents of that John Von Newmann's 1951' paper is available at the following link (mere three pages of text):

https://mcnp.lanl.gov/pdf_files/nbs_vonneumann.pdf

A little excerpt from its first page tells all the truth...

"Any one who considers arithmetical methods of producing random digits is, of course, in a state of sin."

Henrique

• Posts: 23,514

When I press button the results are random for 5 numbers. However the number 60 appears first and every time.

Please post your entire program so we can look to see what's happening.

-Phil

• Posts: 8,393

When I press button the results are random for 5 numbers. However the number 60 appears first and every time.

You must have modified the code.

Please post your entire program so we can look to see what's happening.

I'm with Phil: If you change something and have problems, you have to share the changes.

FTR, I just re-ran the program I posted yesterday and it the first number of every draw is different. If you look at the loop under Main you'll see that the RANDOM function is continuously called until the button is pressed for 25 milliseconds. Again, this is like stirring the lotto balls in a cage.

I made a small change to the program so that you can do multiple draws without resetting. This is what the output looks like.

Please run this WITHOUT MODIFICATIONS. When you get it to work on your end, make a new copy and modify that.

• Posts: 130
edited 2022-09-26 12:00

The number 60 still appears.

```' =========================================================================
'
'   File...... jm_lotto_demo.bs2
'   Purpose...
'   Author.... Jon McPhalen
'              Copyright (c) 2022 Jon McPhalen
'   E-mail....
'   Started...
'   Updated... 25 SEP 2022
'
'   {\$STAMP BS2}
'   {\$PBASIC 2.5}
'
' =========================================================================

' -----[ Program Description ]---------------------------------------------

' -----[ Revision History ]------------------------------------------------

' -----[ I/O Definitions ]-------------------------------------------------

Trigger         PIN     15                      ' for trigger input

' -----[ Constants ]-------------------------------------------------------

IS_ON           CON      1                      ' for active-high in/out
IS_OFF          CON      0

R_MIN           CON      1                      ' for random #s
R_MAX           CON     70
R_SPAN          CON     R_MAX - R_MIN + 1

' -----[ Variables ]-------------------------------------------------------

ballCnt         VAR     Nib                     ' current state of draws
check           VAR     Nib                     ' loop index

timer           VAR     Byte                    ' for trigger
ball            VAR     Byte(6)                 ' balls drawn

lottery         VAR     Word                    ' random value

' -----[ Initialization ]--------------------------------------------------

Reset:
DEBUG CLS, "Lottery Demo", CR

New_Game:
ballCnt = 0
DEBUG CR, "Draw: "

' -----[ Program Code ]----------------------------------------------------

Main:
timer = 0                                     ' reset timer
DO
RANDOM lottery                              ' stir random value
PAUSE 5
timer = (timer + 5) * Trigger               ' re-scan trigger input
LOOP WHILE (timer < 25)                       ' wait for valid trigger

Draw:
RANDOM lottery
ball(ballCnt) = lottery // R_SPAN + R_MIN     ' create ball
FOR check = 0 TO 5                            ' validate
IF check < ballCnt THEN
IF ball(ballCnt) = ball(check) THEN       ' if repeat
GOTO Draw                               '  try again
ENDIF
ENDIF
NEXT

DEBUG DEC2 ball(ballCnt), " "                 ' display new ball
ballCnt = ballCnt + 1                         ' update count
IF ballCnt < 6 THEN                           ' if not done
PAUSE 250                                   ' wait a bit
DO WHILE (Trigger = IS_ON)                  ' force button release
' hold
LOOP
GOTO Main
ENDIF

PAUSE 2000

GOTO New_Game

' -----[ Subroutines ]-----------------------------------------------------

' -------------------------------------------------------------------------

' -------------------------------------------------------------------------

' -------------------------------------------------------------------------

' -------------------------------------------------------------------------

' -------------------------------------------------------------------------

' -----[ User Data ]-------------------------------------------------------
```
• Posts: 14,025

"Pseudo Random Number Generators" are just like a pre-shuffled pack of cards. But the deck size is in the billions at the low end, usually many orders larger. The shuffled order is defined by the algorithm and it's parameters. Usually those parameters are not adjustable as they are carefully chosen to give even distribution of recurring (same value) output results.

So the only user input parameter is the seed. Which is exactly like cutting a pack of cards.

• Posts: 23,514

Which is exactly like cutting a pack of cards.

Nice description! And accessing the next random number is like dealing off the top of the pack and replacing the card to the bottom.

-Phil

• Posts: 14,025

@"Phil Pilgrim (PhiPi)" said:
... dealing off the top of the pack and replacing the card to the bottom.

Right, yes. That retains the shuffle order. I should have said deck instead of pack too.

• Posts: 8,393
edited 2022-09-26 03:59

The number 60 still appears.

Not on my computer.

Maybe you have a button problem. On my system I have a 10K resistor between P15 and ground. I also have a normally-open button between P15 and 5V. When I pressed and held the button before running the program, the first number was always 68.

I added a bit of code to the reset section that will tell you if you're button is active when you start the program. This waits until the input is clear before allowing draws.

```Reset:
DEBUG CLS, "Lottery Demo", CR
IF (Trigger = IS_ON) THEN
DEBUG "-- Draw button is pressed."
PAUSE 1000
DO WHILE (Trigger = IS_ON)
' wait for button to clear
LOOP
GOTO Reset
ENDIF
```

Tip: When posting code, use three back-ticks on the line before and the line after to include the formatting.

Tip: Learn to using the Snipping Tool (if on Windows) so that you can do screen grabs so that we can see what you see.

And there's no need to post code that you didn't modify -- we just need to see your changes, and it would be helpful to see what you see.

• Posts: 130

Thanks Jon for the posting tip. The reset code works fine. I have a 10k pulldown resistor between the switch and ground which generates 2 set of numbers. For Lotto numbers I have to press the button 6 times. Is it possible to generate Random 6 set of numbers at once?

• Posts: 130

A note to my recent post. "Is it possible to generate Random 6 set of numbers at once?"
I bypassed the switch and connected P15 to the output of an 555 timer configured for the square-wave to run in an Astable mode. The speed of the numbers displayed is controlled by a 10k pot. The result is that when the program is running Debug displays a set of 6 numbers at a time indefinite.

Is it still possible to modify the program to run a set of 6 double numbers ?

• Posts: 130

After adding the parts below and eliminating the 3 statements the program works fine.
The program generates 6 set of "Random Numbers" each time the "normally close" switch is pressed.

'Connect a N.C. switch and 10k pullup resistor with a 10UF cap

'IS_OFF CON 0
'DEBUG "-- Draw button is pressed--"
' wait for button to clear

• Posts: 8,393

For Lotto numbers I have to press the button 6 times.

That's by design so that your human timing contributes to the randomness of the numbers.

Is it possible to generate Random 6 set of numbers at once?

Yes, but you will only get 65535 possible sets of numbers. If you use the human input to get a random seed, but base the next five selections on that seed, you have less randomness in the draws.

• Posts: 130

Ok. Now if somebody can give me 6 winning numbers for Mega Millions or Powerball I will gladly contribute half of winnings to that person.

• Posts: 2,231

... winning numbers for Mega Millions or Powerball

Currently, winnning the lottery is my retirement plan.

• Posts: 2,961

Can't help with Mega Millions, but these should work for PowerBall : 31,54,29,52,30;11