Author: Martin Strand
This is very simple, you say: Use a set to store drawn fields!
Yes, you can do if you don't have to many fields to draw. If you pull out more than
255 fields - then the set will say: No more room here! What will you do now?
(And for you who know-how to use arrays to such tasks, don’t read further. I doubt
I can tell you any new)
Answer:
I’m not going to make a whole program for you – that’s quite easy, so you manage
that yourself.
(Note that the routine is translated from Norwegian – some “funny” names can
occur!)
The datatype required:
|
TDrawList = array of ShortString;
We make a dynamic array to make the procedure just that – dynamic. This makes the
procedure work just as well with ten records as with ten thousand records. (Not
tried – only a theory!) I’m using ShortString, but of course, you can use other
datatypes, just remember to change down at the TempDrawList too.
The function-head – the variables: (The name “Draw” was occupied.)
1
2 function Drawing(ARecordCount: Integer; ARecords: TDrawList; ADrawCount: Integer):
3 TDrawList;
4
5 var
6 I, Nr: Integer;
7 TempDrawList: array of record
8 Value: ShortString;
9 CanBeDrawn: Boolean;
10 end;
ARecordCount: This is the number of records in…
ARecords: This is, as you may understand, all those who CAN be pulled out.
ADrawCount: The number of lucky guys.
I (the variable) are only used in For-statements, while Nr are given a value by the
Random function.
TempDrawList: The “set”. This dynamic array knows who’s pulled out and who’s not,
stored in the CanBeDrawn field.
The preparations:
11 SetLength(TempDrawList, ARecordCount);
12 SetLength(ARecords, ARecordCount);
13 SetLength(Result, ADrawCount);
14 for I := 0 to ARecordCount - 1 do // (1 to x = 0 to x-1, and we need to start with
15 0)
16 begin
17 TempDrawList[I].Value := ARecords[I];
18 // Loading the records from the argument to the variable.
19 TempDrawList[I].CanBeDrawn := True; // Making sure that all records can be drawn.
20 end;
21 Randomize;
First, I allocate place in the memory for the arrays. I do not intend to explain
the SetLength procedure. If you need help, consult the Delphi help file.
The next five lines are preparing the TempDrawList for the rest of the procedure,
by loading in the records from the argument and setting all “CanBeDrawn”-s to
“True”. (The name CanBeDrawn should really be self-explaining!)
At last, I call Randomize. Now the fun begins!
The rest:
22
23 for I := 0 to ADrawCount - 1 do // You know what I just wrote: 1 to x = 0 to x-1!
24 begin
25 repeat
26 Nr := Random(ARecordCount);
27 until TempDrawList[Nr].CanBeDrawn = True;
28 Result[I] := TempDrawList[Nr].Value;
29 TempDrawList[Nr].CanBeDrawn := False;
30 end;
To explain step for step:
ADrawCount times do this:
Draw a random number from 0 to AReocordCount, and draw until the CanBeDrawn field
in the TempDrawList at [Nr] is True.
Then, put the Value in the TempDrawList[Nr] in Result[I]. Result is a TDrawList,
prepared above. “I” is the For counter. (And Nr is a random number, not pulled out
before)
The last thing to do is to make sure that it cannot be drawn again.
31 TempDrawList[Nr].CanBeDrawn := False.
32 end;
That’s it. Easy, isn’t it?
(Yes, you’ll say. Easy enough, but… how do I USE this function?)
Using this function:
There are two ways to use it: To make a random list, or to make a random selection
from a list:
program UseFunction;
33
34 {$APPTYPE CONSOLE}
35
36 uses
37 SysUtils;
38
39 type
40 TDrawList = array of ShortString;
41
42 var
43 Selection, TheList: TDrawList;
44 I: Integer;
45
46 function Drawing(ARecordCount: Integer; ARecords: TDrawList; ADrawCount: Integer):
47 TDrawList; // The complete function, though without comments.
48
49 var
50 I, Nr: Integer;
51 TempDrawList: array of record
52 Value: ShortString;
53 CanBeDrawn: Boolean;
54 end;
55
56 begin
57 SetLength(TempDrawList, ARecordCount);
58 SetLength(ARecords, ARecordCount);
59 SetLength(Result, ADrawCount);
60 for I := 0 to ARecordCount - 1 do
61 begin
62 TempDrawList[I].Value := ARecords[I];
63 TempDrawList[I].CanBeDrawn := True;
64 end;
65 Randomize;
66 for I := 0 to ADrawCount - 1 do
67 begin
68 repeat
69 Nr := Random(ARecordCount);
70 until TempDrawList[Nr].CanBeDrawn = True;
71 Result[I] := TempDrawList[Nr].Value;
72 TempDrawList[Nr].CanBeDrawn := False;
73 end;
74 end;
75
76 begin
77 SetLength(Selection, 3);
78 SetLength(TheList, 5);
79 for I := 0 to High(TheList) do
80 TheList[I] := IntToStr(I);
81 Selection := Drawing(Length(TheList), TheList, (Length(Selection));
82 for I := 0 to High(Selection) do
83 WriteLn(IntToStr(Selection[I]));
84 ReadLn;
85 end.
86
87 //If you change it to this:
88
89 SetLength(Selection, 5);
then the result will be a resorted (?) list.
|