type
ENoMoreNumbers =
Exception;
TUniqueRandomSequenceGenerator =
class
private
FCounter: Integer;
FNumberList:
array of Integer;
procedure BuildSequence(aStart, aEnde: Integer);
public
constructor Create(aStart, aEnde: Integer);
function GetNextNumber: Integer;
function TotalCount: Integer;
function RemainingCount: Integer;
end;
implementation
{ TUniqueRandomGenerator }
constructor TUniqueRandomSequenceGenerator.Create(aStart, aEnde: Integer);
begin
BuildSequence(aStart, aEnde);
end;
procedure TUniqueRandomSequenceGenerator.BuildSequence(aStart, aEnde: Integer);
var
i, j, tmp: Integer;
begin
SetLength(FNumberList, aEnde - aStart + 1);
// Zahlenliste erzeugen
for i := 0
to TotalCount - 1
do
FNumberList[i] := aStart + i;
// Mischen nach Fisher-Yates
for i := Low(FNumberList)
to High(FNumberList)
do begin
j := i + Random(TotalCount - i);
tmp := FNumberList[j];
FNumberList[j] := FNumberList[i];
FNumberList[i] := tmp;
end;
FCounter := 0;
end;
function TUniqueRandomSequenceGenerator.GetNextNumber: Integer;
begin
if FCounter < TotslCount
then begin
Result := FNumberList[FCounter];
Inc(FCounter);
end
else
raise ENoMoreNumbers.Create('
No more numbers');
end;
function TUniqueRandomSequenceGenerator.RemainingCount: Integer;
begin
Result := TotalCount - FCounter;
end;
function TUniqueRandomSequenceGenerator.TotalCount: Integer;
begin
Result := Length(FNumberList);
end;