Mega Code Archive

 
Categories / Delphi / Graphic
 

Making a reliable drawing procedure (No painting, but random numbers!)

Title: Making a reliable drawing procedure (No painting, but random numbers!) Question: 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, dont read further. I doubt I can tell you any new) Answer: Im not going to make a whole program for you thats 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!) Im 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.) | Function Drawing(ARecordCount: Integer; ARecords: TDrawList; ADrawCount: Integer): TDrawList; | | var | I, Nr: Integer; | TempDrawList: Array of Record | Value: ShortString; | CanBeDrawn: Boolean; | 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 whos pulled out and whos not, stored in the CanBeDrawn field. ---------------------------------------------------------- The preparations: | SetLength(TempDrawList, ARecordCount); | SetLength(ARecords, ARecordCount); | SetLength(Result, ADrawCount); | For I := 0 to ARecordCount-1 do // (1 to x = 0 to x-1, and we need to start with 0) | Begin | TempDrawList[I].Value := ARecords[I]; // Loading the records from the argument to the variable. | TempDrawList[I].CanBeDrawn := True; // Making sure that all records can be drawn. | End; | 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: | For I := 0 to ADrawCount-1 do // You know what I just wrote: 1 to x = 0 to x-1! | Begin | Repeat | Nr := Random(ARecordCount); | Until TempDrawList[Nr].CanBeDrawn = True; | Result[I] := TempDrawList[Nr].Value; | TempDrawList[Nr].CanBeDrawn := False; | 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. TempDrawList[Nr].CanBeDrawn := False. End; Thats it. Easy, isnt it? (Yes, youll 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; {$APPTYPE CONSOLE} uses SysUtils; type TDrawList = Array of ShortString; var Selection, TheList: TDrawList; I: Integer; Function Drawing(ARecordCount: Integer; ARecords: TDrawList; ADrawCount: Integer): TDrawList; // The complete function, though without comments. var I, Nr: Integer; TempDrawList: Array of Record Value: ShortString; CanBeDrawn: Boolean; End; begin SetLength(TempDrawList, ARecordCount); SetLength(ARecords, ARecordCount); SetLength(Result, ADrawCount); For I := 0 to ARecordCount-1 do Begin TempDrawList[I].Value := ARecords[I]; TempDrawList[I].CanBeDrawn := True; End; Randomize; For I := 0 to ADrawCount-1 do Begin Repeat Nr := Random(ARecordCount); Until TempDrawList[Nr].CanBeDrawn = True; Result[I] := TempDrawList[Nr].Value; TempDrawList[Nr].CanBeDrawn := False; End; end; begin SetLength(Selection, 3); SetLength(TheList, 5); For I := 0 to High(TheList) do TheList[I] := IntToStr(I); Selection := Drawing(Length(TheList), TheList, (Length(Selection)); For I := 0 to High(Selection) do WriteLn(IntToStr(Selection[I])); ReadLn; end. If you change it to this: SetLength(Selection, 5);, then the result will be a resorted (?) list.