waynemodz
waynemodz

Reputation: 118

Delphi Random Returns Zero on a low range

I am using delphi 7 and im trying to shuffle a set of numbers from one list box to another.

02H,02D,02S,02C,03H,03D,03S,03C,10H,10D,10S,10C,11H,11D,11S,11C,20H,20D,20S,20C,30H,30D,30S,30C.

but for some reason, 30C always seems to be last, when i random 0,2 or 0,1 it seems to always give me 0.

procedure TMainForm.btShuffleClick(Sender: TObject);
var I: integer;
begin
    lstShufd.Clear;
    while lstNew.Count <> 0 do
        begin
             Randomize; 
             I:=RandomRange(0,lstNew.Count-1);
             lstShufd.Items.Add(lstNew.Items.Strings[I]);
             lstNew.Items.Delete(I);
        end;
end;

Upvotes: 2

Views: 753

Answers (1)

David Heffernan
David Heffernan

Reputation: 612834

You have two errors:

  1. You must not call Randomize repeatedly in the way you do in the question. Doing so will destroy the distributional properties of your random sequence. Typical usage is to call Randomize once at the start of the program.
  2. RandomRange returns a value I in the range AFrom <= I < ATo. So you are passing the wrong parameters. Use RandomRange(0, lstNew.Count) or even just Random(lstNew.Count).

The second of these errors explains the behaviour that you observe. In your code, by calling RandomRange(0, lstNew.Count-1) you get a value in the range 0 <= I < lstNew.Count-1 and so the final item in lstNew, that is the item with index lstNew.Count-1 cannot be chosen until the final iteration of the loop.

The documentation for RandomRange says:

function RandomRange(const AFrom, ATo: Integer): Integer;

Description

Returns a random integer from a specified range.

RandomRange returns a random integer from the range that extends between AFrom and ATo (non-inclusive). RandomRange can handle negative ranges (where AFrom is greater than ATo).

Upvotes: 6

Related Questions