Hi Homer,
I've given you some tips and changed a few things around.
remstart
*********************
**RANDOM maxcards ONCE**
*********************
I've used REM for program annotations I think you need and ` when I speak to you about the code.
---
I removed the line "read CARD(r)"
READ is not used in this way, it is used to read data from data statements and store in the given variable.
Since you have no data statements I'm not sure what happens but it's not good.
---
remend
maxcards = 10 :`This is a more descriptive name.
dim CARD(maxcards)
rem = Main ==================
repeat
cls
rem Pick an unique card for each choice.
`It helps to describe the overall aim of a piece of code if it's not immediately obvious.
for t = 1 to maxcards
`We don't actually need a new variable for the card choice, we can just use the array.
Card(t) = rnd(maxcards - 1) + 1
for r = 1 to t
if r ! t :`"!" means "not equal to". If you are using DBP it would be "!!".
`Instead of jumping to a label we can simply trick the for loop into repeating the same t cycle again.
if CARD(t) = CARD(r) then t = t-1 : exit :`exit simply jumps out of the current loop and can be used on loops of all types.
rem Card(t) is unique to Card(1 to r).
`This style of comment is especially for conditional loops.
`It tells you what is true at this point in the loop.
`It can be difficult to learn how to comment like this but it's a simple way of conveying the function of loops.
`This comment helped me realise that we needed an "if r ! t" condition otherwise the loop doesn't work,
`because the comment is not true when r=1 and t=1. That's why this style is so helpful for loops.
endif
next r
next t
rem Display cards
for d=1 to maxcards
print CARD(d)
next d
`It helps to give prompts when the user is required to give input.
print "Press SPACEBAR to draw again or Press ESC to quit"
wait key
until escapekey()=1
undim CARD(maxcards)
end
Since arrays are global in DBC you could simply wrap the whole thing up in function tags to turn it into a function, but I think we could optimise the code before doing that.
There's an issue with the code in that choosing a card is "in theory" a potential infinite loop! That's because we're choosing a random number and then checking if we've already had that number, so in theory we could pick 4 first and then on the next card we might continue picking 4 for eternity! Of course that's not really going to happen but the problem remains that picking cards is slowed down by the possibility of duplicates.
Just for a demonstration I'm going to increase the deck to 2000 cards!
remstart
*********************
**RANDOM maxcards ONCE**
*********************
I've used REM for program annotations I think you need and ` when I speak to you about the code.
---
I removed the line "read CARD(r)"
READ is not used in this way, it is used to read data from data statements and store in the given variable.
Since you have no data statements I'm not sure what happens but it's not good.
---
remend
maxcards = 2000 :`This is a more descriptive name.
dim CARD(maxcards)
rem = Main ==================
repeat
cls
rem Pick an unique card for each choice.
`It helps to describe the overall aim of a piece of code if it's not immediately obvious.
for t = 1 to maxcards
`We don't actually need a new variable for the card choice, we can just use the array.
Card(t) = rnd(maxcards - 1) + 1
for r = 1 to t
if r ! t :`"!" means "not equal to". If you are using DBP it would be "!!".
`Instead of jumping to a label we can simply trick the for loop into repeating the same t cycle again.
if CARD(t) = CARD(r) then t = t-1 : exit :`exit simply jumps out of the current loop and can be used on loops of all types.
rem Card(t) is unique to Card(1 to r).
`This style of comment is especially for finite loops.
`It tells you what is true at this point in the loop.
`It can be difficult to learn how to comment like this but it's a simple way of conveying the function of loops.
`This comment helped me realise that we needed an "if r ! t" condition otherwise the loop doesn't work,
`because the comment is not true when r=1 and t=1. That's why this style is so helpful for loops.
endif
next r
next t
`We know the routine works now so we don't need to figure out a way to display 1000 cards on screen
print "DONE"
`It helps to give prompts when the user is required to give input.
print "Press SPACEBAR to draw again or Press ESC to quit"
wait key
until escapekey()=1
undim CARD(maxcards)
end
There's now a few seconds delay before the routine finishes.
So how can we remove the chance of duplicates and speed this up? Well we need a way to remove a card from the possible choices once it has been chosen; we're essentially giving the cards an identity. A simple way to do this is to make an array for the cards (like a deck) and check off the ones that have been selected (removed from the deck), then when we pick a new card we cycle through the deck to find one that hasn't been taken already.
remstart
**********************
** Random Card Draw **
**********************
remend
maxcards = 1999 :`remember that field 0 can hold a value so 1999 gives us 2000 fields.
dim card(maxcards) : rem this array stores the cards picked.
dim deck(maxcards) : rem this array keeps track of the pick status of each card in the deck.
rem = Main ============================
while escapekey() = 0
deal(maxcards)
remstart
Delete the rem tags and change "maxcards" to a smaller value if you want to test that it works.
for i = 0 to maxcards
print card(i)
next i
remend
print "DONE! Press any key to deal again or press ESC to quit."
wait key
cls
endwhile
rem = Functions =======================
function deal(max)
rem reset the deck and card arrays
for i = 0 to max
card(i) = 0
deck(i) = 0
next i
for i = 0 to max
pick = rnd(max-i)
rem find the "pick"-th available card
check = 0 :`this variable will count through available cards until we reach the pick-th card. It
for x = 0 to max
if deck(x)=0 :`if the card at deck position x is unpicked...
if check = pick :`If we've checked enough cards for the pick...
deck(x)=1 :`mark card x as picked.
card(i)=x :`put card x in the chosen cards list.
exit
else
inc check :`tell the check that we've gone over another available card.
endif
endif
next x
next i
endfunction
Now it's much faster! But hang on a second, we can see from the output that all we're really doing is shuffling the numbers so isn't there a better way of achieving that without randomly picking cards? Yes let's shuffle the deck then the cards will already be in a random order when we deal them!
So what happens when we shuffle cards? We swap the position of two randomly chosen cards in the deck, and we repeat the process until we're happy the deck is randomized. First we need to figure out how to pick two cards. We could do this as we've done before but there's a simpler and cleverer way to do it.
If we take one card out of 20 (1 to 20 for simplicity but we'll actually use 0 to 19 in the program) that leaves 19 cards remaining; so our next selection will be out of 19 cards. But if the first card picked isn't 20 we might accidentally choose the same card again

, but here's the clever part: if we remember which card we picked first we can simply count on from it to find the second card and if we go over the maximum amount of cards we simply wrap back around to the start, so it's impossible to pick the same card again! (This counting doesn't waste time like in the previous code example because we're not actually testing anything we're just adding two values together.) Then we just swap the values at those two positions in the array and hey presto, our first swap is complete!
remstart
**********************
** Random Card Draw **
**********************
remend
maxcards = 19
dim deck(maxcards) :`this array stores each card as a value in a unique position.
for i = 0 to maxcards
deck(i) = i :`we start with card i at position i in the deck.
next i
rem = Main ============================
while escapekey() = 0
rem repeat the swap action a few dozen times to shuffle the deck
for r = 1 to 24
swap(maxcards)
next r
rem deal the cards
for i = 0 to maxcards
print deck(i)
next i
print "DONE! Press any key to deal again or press ESC to quit."
wait key
cls
endwhile
rem = Functions =======================
function swap(max)
c1 = rnd(max)
c2 = c1 + 1 + rnd(max-1)
if c2 > max then c2 = c2 + 1 - max :`this is where we wrap the value if it's too big.
`this is a little trick to swap two variables without using a temporary variable.
deck(c1) = deck(c1) + deck(c2)
deck(c2) = deck(c1) - deck(c2)
deck(c1) = deck(c1) - deck(c2)
endfunction
So there you go. Now you've learned some neat tricks with arrays and how to manipulate them. Hope that helps.
Shh... you're pretty.