 CHAPTER X

The last subject that will be covered in this series is random 
numbers.  In dealing with this subject, once again, arrays will 
be utilized to cast a die or so and shuffle and deal some cards.

RND is the BASIC command for random number generation. 
Unfortunately, they are not really as random as they might seem. 
The numbers that are generated follow a pattern, but can not be 
detected.  The trick in programming is to start the series to be 
used at a different point everytime.

The command RND results in a number being generated between 0 
(which it can be) and 1.0 (which it can not be).  The starting 
point is controlled by the number inside the parenthesis of the 
command.  To demonstrate, type the following program.

 10 for i = 1 to 5
 20 ? rnd(0)
 30 next

Run it!  How did it work? Did the same number appear? RUN it 
again -- same results.  Why? The 0 inside the parenthesis tells 
the computer to always return the same number.  This is useful 
when debugging a program, but not when playing a game!

List 20 and replace the 0 with any positive number.  Try 5, now 
run.  This time different numbers appear.  RUN again.  The same 
series of numbers appear.  Try changing the 5 to some other 
positive number.  Same results again.  That wouldn't be much fun 
if a game was being played, at least the second time that it was 
played.

Change the program and put in a "seed" number which is a number 
that can be input when requested.  The number will then be 
"seeded" in as a negative number.  Add the following steps to the 
above program:

 3 INPUT "ENTER any number 1 to 5000 "; s
 5 x = rnd(-s)

Make sure that there is a positive number other than 0 in the RND 
command of statement 20.  Now RUN several times using a different 
seed each time.

There are some other programs that give a random seed.  There is 
one that is based on PEEKing an address in RAM which is steadily 
changing.  There is another in ADAM's COMPANION that makes use of 
one of the game controllers.

So far, numbers between 0 and 1 can be gotten, but those really 
aren't much good either.  More practice is needed.  To simulate 
casting a die, expect to get whole numbers from one to six.  Do 
that with the random number generator by using a statement that 
reads:

 x = INT(RND(1)*6) + 1

RND(1) generates a number between 0 and .99999999.  If that 
number is multiplied by 6 then there is a number from 0 to 
5.9999999.  The command INT yields the whole number that is 
inside the parenthesis.  In this program it would be something 
from 0 to 5.  But if 1 to 6 -- was desired add one to the result.

Make more changes to the program and see what results: 

 ADD 7 speed = 50
 CHANGE 10 to 10 FOR i = 1 to 100
 CHANGE 20 to 20 ? int(rnd(5)*6) + 1
 ADD 40 Speed = 255

Now RUN.  There is a range of numbers between 1 and 6.  Are they 
distributed satisfactorally for purposes of playing games, or 
should the bet be on a six or some other number? Probabilites and 
statistics will tell that seldom can a die be cast 12 times and 
get 2 of each number.  In fact, there is an acceptable range of 
deviation from the ideal.  Let's get a feel for what the computer 
does by making it cast the die over 2000 times in lots of 600 
each time and accumulate how the numbers come up.  This is the 
type of thing at which a computer shines.

What we are going to do is to cast the die 600 times, keeping 
track how many times each number comes up.  We will then store 
those numbers in column 1 of an array.  We will go another 600 
times adding to the accumulated totals for each number and store 
those totals in column 2 etc., until we have four columns.  We 
will then print out to numbers so we can see if there is a 
pattern.

Start a new program:

 10 dim n(6), r(6,4)
 20 INPUT$"seed 1 to 5000? "; s
 30 x = rnd(-s)
 40 for i = 1 to 4
 50 for j = 1 to 600
 70 x = int(rnd(5)*6)+1
 80 n(x) = n(x) +1
 90 ? i; " "; j; " "; x
 100 next j
 105 ? chr$(7): ? chr$(7)
 110 for k = 1 to 6: r(k,i) = n(k): next
 120 next i
 130 home: tb = 0
 140 for i = 1 to 6
 150 ? tab(tb); i; : tb = tb + 5
 160 for j = 1 to 4
 170 ? tab (tb); r (i,j);: tb = tb +5: next: tb = 0 : ?
 180 next i

RUN this program.  You should expect to see the numbers in each 
column roughly 100 * column number.  While they are not exact, 
they are close and you can see them shift during the run.  There 
are streaks, but no particular favoritism.  Try it several times.

You now have the stage set to cast dice for number games.  How 
about dealing cards.  It would be easy enough to change the six 
in the program for dice to a thirteen and use it for cards where 
the one is an ace and the 13 a king, or any other way you wanted 
to do it.  There is a problem with that -- there are only four 
aces in a deck, etc.  When four of them have come up, there can 
be no more until you shuffle again.  We can even control the 
suits if we wish.

The principle we will use in this program is to generate two 
numbers.  The first will be between 1 and 13 and the other 
between 1 and 4.  The first will represent the denomination and 
the second the suit.  We will have two dictionary arrays for our 
definitions, a deck array to deal the cards into, and an array to 
check if the card has been dealt.  Sound complicated? Not really.

Try it.  Type the following program:

 10 REM deal the cards -- 1 deck 
 15 INPUT "seed no 1 to 5000 ? ";s
 17 x = rnd(-s)
 20 dim deck(52,2), suit$(4), card$(13), check (13,4)
 30 DATA S, H, D, C 
 40 DATA " A", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", 
  "10", " J", " Q", " K"
 50 for i = 1 to 4: READ suit$(i): next
 60 for i = 1 to 13: READ card$(i): NEXT
 70 for i = 1 to 13: for j = 1 to 4: check(i,j) = 0: NEXT:
  NEXT :REM make all elements of check 0
 75 HOME: ? "Pardon me, I'm shuffling!"
 80 for i = 1 to 52
 90 a = int(rnd(5)*13)+ 1: b = int(rnd(5)*4) + 1
 100 if check (a,b) = 1 then goto 90
 110 check(a,b) = 1: deck (i, 1) = a: deck (i,2) = b
 120 next i
 130 home
 140 REM deal out four hands
 150 for i = 0 to 12: for j = 1 to 4
 160 ? card$(deck (i*4+j,1)); suit$(deck(i*4+j,2)); " ";
 170 next j
 180 ?: next i
 190 ?:? "Do you want another - y/n?": get q$
 200 if q$ = "y" then goto 70
 210 END

Study the program.  Save it before RUNning it.  It would be a 
shame to lose it and have to type it again.

How does it work? First it loads some definitions of the card and 
suit names into arrays.  Then it sets all of the elements of 
check array to 0.  Then a random number 1 to 13 representing the 
denomination of the card is generated and is followed by the 
generation of a suit number.  It then looks at check array to see 
if the element represented by the denomination row and the suit 
column is 1.  If it is, that means that the card has already been 
put in the deck array so it returns and gets another set of 
numbers.

If the card is not yet in the deck array, it changes the check 
element from zero to one and then stores the numbers in the deck 
array.  After all 52 positions in the deck array are filled, it 
deals out the cards in four hands.  The expression of i*4+j where 
i ranges from zero to 12 and j ranges from 1 to 4 will generate 
all the numbers from one to 52.  Think about it and you will 
decide it is true.

Have fun casting dice and dealing cards.  You now can write a 
program to play 21 or shoot craps, or about anything else. 

e