BBC BASIC for Windows
« Lottery number generator (duplication protection) »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 9:51pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Lottery number generator (duplication protection)  (Read 1409 times)
michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
cheesy Lottery number generator (duplication protection)
« Thread started on: Mar 28th, 2016, 11:25am »

**SPECIAL NOTE: This is not the original post.. I have removed the old program and replaced it with a much more advanced version with special tools.

This is the Canadian LOTTO MAX.. there are 7 numbers out of 49 that you must pick.

This program should be up to everyones standards.
1) no use of GOTO or GOSUB
2) no ancient coding ways.
3) it was built from the ground up
4) it has key detection so you can roll for more numbers
5) The most impressive part (Procedure array value duplication protection)
(sounds impressive eh?)

Please let me know if it isn't perfect.. I have been testing this and perfecting it for hours..

Code:
    
  DIM x%(7)
      CLS:PROC_newnumbers
      REPEAT
        key$=""
        key$ =INKEY$(1)
        IF LEN(key$) = 1 THEN
          IF key$="r" OR key$="R" THEN PROC_newnumbers
        ENDIF
      UNTIL key$="q" OR key$="Q"
      PRINT "done"
      END
      DEF PROC_newnumbers
      CLS
      PRINT "Here is 7 numbers for Lotto Max"
      REPEAT
        FOR t=1 TO 7
          x%(t)=RND(49)
        NEXT t
        PROC_comparray(7)
      UNTIL cond$="cleared"
      FOR t=1 TO 7
        PRINT x%(t)
      NEXT t
      PRINT "Press R or r for more numbers or Press Q or q to quit"
      ENDPROC
      DEF PROC_comparray(n)
      cond$="cleared"
      nex=1
      FOR cou=1 TO n
        FOR co=nex TO n
          IF cou<>co THEN IF x%(cou)=x%(co) THEN cond$="duplicate"
        NEXT co
        nex=nex+1
      NEXT cou
      ENDPROC
 
« Last Edit: Mar 29th, 2016, 05:50am by michael » User IP Logged

I like making program generators and like reinventing the wheel
Zaphod
Guest
cheesy Re: Lottery number generator (LOTTO MAX Canada)
« Reply #1 on: Mar 28th, 2016, 1:24pm »

Reinventing the wheel, yes indeed.

The BB4W wiki has a much more elegant solution by Richard in this
http://bb4w.wikispaces.com/Notes+on+the+use+of+RND

Opinion!
A beginner would be much better off adopting the kind of style used in the Wiki and supplied code examples rather than using the archaic Gosub an Goto of the very early basics. These constructs were dropped from common use 30 years or more ago. It is not that they are wrong just that better and faster constructs are now available in all modern dialects of BASIC.
User IP Logged

michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
cheesy Re: Lottery number generator (LOTTO MAX Canada)
« Reply #2 on: Mar 28th, 2016, 2:22pm »

Thanks.. I will try to make better structured programs.

I do program much the same as I did on the Trs-80 (1982).. (but I sometimes program like this because I am not putting any effort into making it slim)
I just do what ever works.

My use of RND comes from the help section.
It more accurately represents the old basics in the way I have presented.

My programming habits haven't changed much since I programmed from 1982- 1990 (approximately) and then for a very short bit in 2009 and then from March 2015- now..

Old habits die hard. When BBC Basic was being released, I
would have been only 8 years old. (if it is 35 years old)

I see this is the simpler method of making a similar program (Lotto Max uses 7 numbers not 6.. ( I got this from your link)

I actually use for/next loops in my programs a lot.
But for some reason I just did it the way I did...
(AND actually this is a translation from a program I made in APRIL 11, 2015.. ) So its just that.. I am more advanced than this..

And when I try to remake the board game I made back in 1988, we will see how that goes.. Because I am going to try to make it have artificial intelligence (to a degree) instead of a player against themselves style.


« Last Edit: Mar 28th, 2016, 3:41pm by michael » User IP Logged

I like making program generators and like reinventing the wheel
TheFamousCash
New Member
Image


member is offline

Avatar




PM


Posts: 16
cheesy Re: Lottery number generator (LOTTO MAX Canada)
« Reply #3 on: Mar 28th, 2016, 11:17pm »

On the other hand, why use random numbers? Surely you understand chances are worthless?
Why not use semi-random?
The best National lottery program shows TWO jackpot hits since lottery began.
See list of other hits.
http://www.ebay.co.uk/itm/111940737683?ssPageName=STRK:MESELX:IT&_trksid=p3984.m1555.l2649
User IP Logged

Zaphod
Guest
cheesy Re: Lottery number generator (duplication protecti
« Reply #4 on: Mar 29th, 2016, 1:24pm »

We all seek perfection but in software that is very difficult to define.
Your code revision is much better though. You can change. Remember, I'm pulling for you. We're all in this together.

I would suggest some modifications in terms of style and making the program and modules not so specific. The you can then reuse the code elsewhere, which might stop you reinventing the wheel but does save time. I make no claims of it being even close to perfect.

Here are the specifics.
First the logic is unchanged!
Procedure names starting with an underscore are reserved for library functions by BB4W convention so those are changed.
Where a Procedure is just determining a value, especially a Boolean then a function is probably a better choice.
Where variables are only used within a Procedure or Function then they are made Local.
To make the Procedures and Functions modular the data are passed to them as parameters.
The limits of arrays passed are tested so there are no errors.
The variable naming conventions are in line with the recommendations for BB4W and will show no warnings in the Cross Reference Utility.
Non functioning lines were removed.

Code:
      Numbers%=7
      Limit%=49
      DIM X%(Numbers%)
      CLS
      PROCnewnumbers(X%(),Limit%)

      REPEAT
        Key$ =INKEY$(1)
        IF Key$="r" OR Key$="R" THEN CLS:PROCnewnumbers(X%(),Limit%)
      UNTIL Key$="q" OR Key$="Q"
      PRINT "done"
      END

      DEF PROCnewnumbers(n%(), max%)
      LOCAL t
      PRINT "Here are "+STR$Numbers%+" non-repeating numbers for a Lottery in the range 1 to "+STR$max%
      REPEAT
        FOR t=1 TO DIM(n%(),1)
          n%(t)=RND(max%)
        NEXT
      UNTIL NOT FNcomparray(n%())
      FOR t=1 TO DIM(n%(),1)
        PRINT n%(t)
      NEXT
      PRINT "Press R or r for more numbers or Press Q or q to quit"
      ENDPROC

      DEF FNcomparray(a%())
      LOCAL dupe%, nex, cou, co
      nex=1
      FOR cou=1 TO DIM(a%(),1)
        FOR co=nex TO DIM(a%(),1)
          IF cou<>co THEN IF a%(cou)=a%(co) THEN dupe%=TRUE
        NEXT
        nex+=1
      NEXT
      =dupe%
 


The comments made by others about why you would want random numbers is of course valid, and certainly Richard's routine referenced earlier in this conversation is far more efficient.

In terms of lotteries you can improve your chances of being amongst a smaller number of winners by choosing less popular numbers. The popularity of numbers is pretty easy to find.
Good Luck.
User IP Logged

hellomike
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 46
cheesy Re: Lottery number generator (duplication protecti
« Reply #5 on: Apr 3rd, 2016, 4:25pm »

Hi Michael,

For your PROC_comparray() code, Zaphod already made some good modifications. I.e. making it a function and array-name/size independent.

However I like to make some other comments and I made a little program around it to make you see the differences.

Here is the code. It has line numbers just so I/we can refer to specific lines when discussing.

Code:
   10 SIZE%=5000
   20 DIM A%(SIZE%-1)
   30 FOR I%=0 TO SIZE%-1:A%(I%)=I%:NEXT
   40 
   50 T%=TIME:PRINT FNcomparray(A%()) TIME-T%
   60 T%=TIME:PRINT FNcomparrayNEW(A%()) TIME-T%
   70 
   80 PRINT
   90 
  100 A%(SIZE%/2)=1
  110 T%=TIME:PRINT FNcomparray(A%()) TIME-T%
  120 T%=TIME:PRINT FNcomparrayNEW(A%()) TIME-T%
  130 END
  140 
  150 DEF FNcomparray(a%())
  160 LOCAL dupe%, nex, cou, co
  170 nex=1
  180 FOR cou=1 TO DIM(a%(),1)
  190   FOR co=nex TO DIM(a%(),1)
  200     IF cou<>co THEN IF a%(cou)=a%(co) THEN dupe%=TRUE
  210   NEXT
  220   nex+=1
  230 NEXT
  240 =dupe%
  250 
  260 DEF FNcomparrayNEW(a%())
  270 LOCAL cou, co
  280 FOR cou=0 TO DIM(a%(),1)-1
  290   FOR co=cou+1 TO DIM(a%(),1)
  300     IF a%(cou)=a%(co) THEN =TRUE
  310   NEXT
  320 NEXT
  330 =FALSE 


First your approach has a bug in it, because the loops start with 1 and not zero. The (0) element of the array is not checked. You can see it failing when you alter line 100 into:

Code:
  100 A%(SIZE%/2)=0 


making A%(2500) equal to A%(0).
FNcomparray() will not signal a duplicate.

Then about the use of variable 'nex'. Note that it always has the same value as the variable 'cou'. I recommend you to remove 'nex' and simply use 'cou' instead.

Furthermore if you start the inner loop with 'cou+1' then you never have to check later if cou<>co because it always is, so you can remove that condition too.
Of course when doing this, make sure that the outer loop end value is 'DIM(a%(),1)-1' otherwise 'co' will eventually become 1 bigger than the last array index and you face a "Bad subscript at line 300".

Finally it is recommended that you leave the function (or PROCedure) as soon as a duplicate value is found. This gives huge performance boost.
For example if array element 0 and 1 are equal, then 'a%(cou)=a%(co)' is true in the very first iteration of both loops, where cou=0 and co=cou+1. There is no need to continue anymore.
This is especially important for code like comparing which uses loops within loops.

Running the program will execute both functions when the A%() array has no duplicate values so '0' is returned both times.
It will then execute both functions again with element a%(1) and A%(2500) being equal so '-1' is returned both times.

The return values are followed by the time in centi second that the execution of that specific call took.
On my system, this was the output:

Code:
         0      1115
         0       713

        -1      1112
        -1         0 


Note the time difference when both loops are executed fully (11.15 sec vs 7.13 sec) because there are no equals in the array but especially note, the difference when element 1 and 2500 are equal (11.12 sec vs 0.00 sec).

I hope you find the tips welcome Michael. Feel free to comment on it further.

Regards,

Mike
User IP Logged

Wildmooer
New Member
Image


member is offline

Avatar




PM


Posts: 7
cheesy Re: Lottery number generator (duplication protecti
« Reply #6 on: Apr 24th, 2016, 3:37pm »

I'm new to this, but I like it!
Please comment on this alternate method:
Code:
      n=0:key$="":spot=0

      REPEAT
  
        all$=""
        FOR n=1 TO 49
          all$=all$+CHR$(n)
        NEXT n
  
        CLS
        PRINT "Here are 7 numbers for Canadian Lotto Max:"
  
        FOR n=1 TO 7
          spot=RND(LEN(all$))
          PRINT ASC(MID$(all$,spot,1))
          all$=LEFT$(all$,spot-1)+MID$(all$,spot+1)
        NEXT n
  
        PRINT "Press [ANY KEY] for More Numbers or"
        PRINT "Press [Q] or [q] to Quit"
  
        REPEAT
          key$=INKEY$(0)
        UNTIL key$<>""
  
      UNTIL key$="q" OR key$="Q"

      PRINT "done"
      END

 
User IP Logged

Zaphod
Guest
cheesy Re: Lottery number generator (duplication protecti
« Reply #7 on: Apr 24th, 2016, 3:55pm »

I like that a lot as a technique!
Simple and effective.

But please don't do this:
Code:
 
        REPEAT
          key$=INKEY$(0)
        UNTIL key$<>"" 

You need a time delay so the cpu is not in a tight loop. INKEY$(1) will do that just fine.

For someone who is 'new to this' it's a great start and I can't wait to see what you do when you get more time in on BB4W.

User IP Logged

Wildmooer
New Member
Image


member is offline

Avatar




PM


Posts: 7
cheesy Re: Lottery number generator (duplication protecti
« Reply #8 on: Apr 25th, 2016, 03:56am »

Thank you for the tip!!!
« Last Edit: Apr 25th, 2016, 03:59am by Wildmooer » User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls