Shop OBEX P1 Docs P2 Docs Learn Events
Random Seed — Parallax Forums

Random Seed

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)

Comments

  • 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

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

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) 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

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

  • 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

  • JonnyMacJonnyMac Posts: 8,912
    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.

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

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

  • JonnyMacJonnyMac Posts: 8,912
    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.

  • 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

  • @"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. 👍

  • 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

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

  • @"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 :smile:

  • 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

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

  • bluejaybluejay Posts: 131
    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
    '              MIT License Applies
    '   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 ]-------------------------------------------------------
    
  • evanhevanh Posts: 15,126

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

  • 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

  • evanhevanh Posts: 15,126

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

  • JonnyMacJonnyMac Posts: 8,912
    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.

  • 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?

  • 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 ?

  • 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

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

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

  • ... winning numbers for Mega Millions or Powerball

    Currently, winnning the lottery is my retirement plan. :/

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

Sign In or Register to comment.