'===========================================================================
' Subject: SHUFFLING DATA IN AN ARRAY         Date: 10-03-93 (10:42)       
'  Author: Rick Pedley                        Code: QB, QBasic, PDS        
'  Origin: FidoNet QUIK_BAS Echo            Packet: TEXT.ABC
'===========================================================================
' > I'm looking for a code to shuffle data so that I get a list of the

' Here's a way to shuffle each number exactly once, in _one_ array:
 
DEFINT A-Z 
RANDOMIZE TIMER 
 
MaxNum = 1000 
DIM Array (1 TO MaxNum) 
FOR x = 1 TO MaxNum 
   Array(x) = x 
NEXT x 
Top = 1 
Bottom = MaxNum 
WHILE Bottom > Top 
   RandNum = INT((Bottom - Top + 1) * RND + 1) 
   SWAP Array(RandNum), Array(Bottom) 
   Bottom = Bottom - 1 
WEND 
 
'With five numbers, here's a picture of how it works: 
 
'1            1            4            3            3 < Bottom 
'2            5            5            5 < Bottom   5   (exit) 
'3            3            3 < Bottom   4            4 
'4            4 < Bottom   1            1            1 
'5 < Bottom   2            2            2            2 
 
'Sometimes the Bottom value swaps with itself, as I did purposely 
'in the last column. And as you can see, although 4 moved twice, 
'the shuffle is always completed in MaxNum times through the loop. 
'It's very fast, no index array is needed, and it doesn't slow 
'down near the end the way some other methods do. Here's a semi- 
'practical application for a sort like this (shuffling a deck of 
'cards is another obvious use). If you compare this method with 
'filling an index array with flag values, you'll see the difference. 
 
'Turn text screen from white to black randomly, 
'one location at a time. 
 
DEFINT A-Z 
RANDOMIZE TIMER 
Rows = 25                 'or 43 or 50 
MaxNum = Rows * 80 
DIM ScrnEl(MaxNum) 
Block$ = CHR$(219) 
BlockLine$ = STRING$(80, Block$)
FOR X = 1 TO MaxNum       'initialize array 
   ScrnEl(X) = X 
NEXT X 
Top = 1: Bot = MaxNum 
DO                        'shuffle all screen pos'ns 
   RandNum = INT(Bot * RND + 1) 
   SWAP ScrnEl(RandNum), ScrnEl(Bot) 
   Bot = Bot - 1 
LOOP WHILE Bot > Top 
CLS 
COLOR 15 
FOR X = 1 TO Rows         'fill in screen 
   PRINT BlockLine$; 
NEXT X 
DO UNTIL LEN(INKEY$): LOOP 

COLOR 0 
FOR X = 1 TO 2000 
   C = ScrnEl(X) MOD 80: IF C = 0 THEN C = 80 'calc screen pos'n 
   R = ScrnEl(X) \ 80 - (C < 80) 
   LOCATE R, C: PRINT Block$; 
NEXT X 
END 
 
'You can use this method easily with file records. You would do the 
'shuffle first, so all the values held in Array() are out of order. 
'Then, step through the file records: 
 
FOR Y = 1 TO 3000                ' 3000 records, already DIM'd 
   GET #x, RecordNumber(Array(y))' the _value_ of Array(x) points to the
NEXT Y                           ' record you're going to read. 
