Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi







Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (2)


Making a reliable drawing procedure (No painting, but random numbers!)Format this article printer-friendly!Bookmark function is only available for registered users!
How to make sure the same field/record/name/number/what/ever is not drawn twice?
Product:
Delphi all versions
Category:
Object Pascal
Skill Level:
Scoring:
Last Update:
04/19/2003
Search Keys:
delphi delphi3000 article borland vcl code-snippet draw random array
Times Scored:
2
Visits:
2199
Uploader: Martin Strand
Company:
Reference: N/A
 
Question/Problem/Abstract:
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.)
|   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 who’s pulled out and who’s 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;

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;

{$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.





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
Complex
    Jos Visser (Jun 27 2003 10:18AM)

I think you're making the article more complex than you should. In fact, you say that the article is actually about using arrays, but then again, it pretends te be an article about drawing.
If you stick to only one problem, the answer will be much more comprehendable.
Respond

RE: Complex
Martin Strand (Jun 29 2003 11:53PM)

Maybe. I wrote this article in pure joy, five minutes after I learned this myself. I guess you're right, but then, it can be copied, and used at once. I'm not going to change or re-write it now, but who knows about the future...
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
D. Souchard
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)