BBC BASIC for Windows
Programming >> BBC BASIC language >> Keeping track of choices
http://bb4w.conforums.com/index.cgi?board=language&action=display&num=1426633203

Keeping track of choices
Post by IffySnuffy on Mar 17th, 2015, 11:00pm

Hi all

Could someome either help me with this problem, or recommend the best place to read up about it.

The following is a short prog that prints a random number from 1 to 5. For extra clarity, and to keep track, it prints it on its own line.

As you can see, it will repeat forever.

The gist of what I'm trying to do is stop it from choosing a number once that number has been chosen, and once all 5 numbers have been chosen, to print a message.

I would imagine this is the basis of all card games etc, whereby once a card has been chosen, it can't be chosen a second time.

Thanks for your help

repeat
i%=rnd(5)
g=get
printtab(1,i%)i%
until false

Re: Keeping track of choices
Post by rtr2 on Mar 17th, 2015, 11:40pm

on Mar 17th, 2015, 11:00pm, IffySnuffy wrote:
I would imagine this is the basis of all card games etc, whereby once a card has been chosen, it can't be chosen a second time.

Shuffling, you mean? Indeed this is a very common requirement and if you search this forum for 'shuffle' you will find at least two previous threads on the subject:

http://bb4w.conforums.com/index.cgi?board=language&action=display&num=1395089290&start=1

http://bb4w.conforums.com/index.cgi?board=general&action=display&num=1368642381&start=6

Richard.

Re: Keeping track of choices
Post by Stripey on Mar 18th, 2015, 3:51pm

I think the poster wants to select only from previously unselected numbers, and to end once all numbers have been selected.

How about:
Code:
      REM IffySnuffy wants to pick from 5 numbers.
      NUMBERS = 5

      REM Define some constants to represent the status of a number.
      AVAILABLE = 0
      UNAVAILABLE = 1

      REM Make an array to track their status (available/unavailable).
      DIM Status(NUMBERS)
      REM Ignoring the bottom (zeroth) member of the array.
      REM All members of this array start out zero,
      REM meaning: AVAILABLE for selection.
      REM Set them to 1 (UNAVAILABLE) once picked.

      REM The main loop. Count keeps track of the number of numbers that have been selected.
      FOR Count = 1 TO NUMBERS
  
        REM Using IffySnuffy's method,
        REM keep picking random numbers between 1 and NUMBERS inclusive...
        REPEAT
          Pick% = RND(NUMBERS)
    
          REM ...until you pick one that is available
        UNTIL Status(Pick%) = AVAILABLE
  
        REM Change that member of the array from 0 to 1,
        REM to indicate that it's now unavailable.
        Status(Pick%) = UNAVAILABLE
  
        REM Press a key to continue and
        REM print the selected number in IffySnuffy's format.
  
        g = GET
        PRINT TAB(1,Pick%) Pick%
  
        REM A number has been selected, so loop again until Count reaches NUMBERS.
      NEXT Count

      REM All five numbers now picked, so finish...
      PRINT TAB(1,NUMBERS + 2) "Finished."
      END
 


No doubt something more elegant will be along shortly...

Stripey
Re: Keeping track of choices
Post by rtr2 on Mar 18th, 2015, 5:32pm

on Mar 18th, 2015, 3:51pm, Stripey wrote:
No doubt something more elegant will be along shortly...

I already offered an 'elegant' solution: shuffling. The OP referred to what he wanted as being "the basis of all card games" and the relevant Wikipedia article states "Fisher–Yates shuffling is similar to randomly picking numbered tickets out of a hat without replacement until there are none left".

Here is how to do it for the numbers 1 to 5:

Code:
      DIM num%(5)
      FOR I% = 1 TO 5
        num%(I%) = I%
      NEXT I%
      FOR I% = 5 TO 2 STEP -1
        SWAP num%(I%),num%(RND(I%))
      NEXT I%
      FOR I% = 1 TO 5
        PRINT num%(I%)
      NEXT I% 

I think you'll agree that this is more elegant, more efficient and simpler than a 'brute force' method. In particular there's no need for any 'trial and error' looping until an 'available' number is picked, an approach which becomes increasingly inefficient as fewer and fewer numbers are left.

For more information on the Fisher-Yates shuffle see the Wikipedia page and for BBC BASIC implementations see the BB4W Wiki article 'Notes on the use of RND'.

Richard.
Re: Keeping track of choices
Post by Stripey on Mar 18th, 2015, 6:20pm

Hah!

Apologies to the OP for wasting his/her time, and to Richard for not appreciating that "shuffle" covered so much ground.

My friends will be amused to think of me using "brute force", but there you go...

Stripey
Re: Keeping track of choices
Post by IffySnuffy on Mar 18th, 2015, 7:21pm

Thanks very much both of you for taking the trouble to offer me solutions, much appreciated. Your explanation, Stripey, was very helpful.

Richard, I think you are giving me credit for more intelligence than I possess!

I was mainly looking for a solution to prevent me from choosing the same number twice. I haven't reached the great scale of shuffling a 52 pack of cards with 4 suits yet, whatever impression I may have given you, but, one day...........

Seriously though folks, thanks again to both of you. smiley
Re: Keeping track of choices
Post by rtr2 on Mar 18th, 2015, 8:30pm

on Mar 18th, 2015, 7:21pm, IffySnuffy wrote:
I was mainly looking for a solution to prevent me from choosing the same number twice.

I hope you haven't misunderstood. The solution to preventing you from choosing the same number twice is to use a shuffle. I listed the code to do it, linked to two other threads with more detail, and pointed to a Wiki article. What more can I do to persuade you to do this in the simple way?

Quote:
I haven't reached the great scale of shuffling a 52 pack of cards with 4 suits yet

Shuffling 52 items is no harder than shuffling 5 (just change every 5 to 52 in the code I listed) so I don't really understand what you are meaning with that comment.

Richard.