![]() |
3 Zufallszahlen ohne Wiederholung
Hallo! =)
Ich habe ein kleines Problem, bin aber ein ziemlicher Delphi-Neuling, also bitte nicht hauen ;) Es geht um Folgendes: Es sollen per Klick auf eine Schaltfläche 3 Zufallszahlen zwischen 1 und 100 in Labelfeldern ausgegeben werden. Das an sich würde ich ja auch hinbekommen, aber jetzt geht es darum, dass bei einem erneuten Klick auf besagten Button die 3 bereits "gezogenen" Zahlen von der Generation der 3 nächsten Zahlen ausgeschlossen werden. Es soll also keine Zahl doppelt vorkommen können. Das soll dann immer so weiter laufen. Wie schon erwähnt kenne ich mich noch nicht so sonderlich gut aus, Delphi-Codes zu den Wortbeschreibungen wären also sehr hilfreich. :) Hoffe, ihr könnt mir da irgendwie weiterhelfen. Tschüss, Scarlett |
Re: 3 Zufallszahlen ohne Wiederholung
Kennst du Arrays?
Wenn ja, gut, wenn nein, Informieren! Genauer gesagt, brauchst du dynamische Arrays. Die Sucher hilft dir gerne weiter ... Dann speicherst du bei jedem Klick auf den Generieren-Knopf die Zahlen in dem Array. Bei einer weiteren Generierung wird dann zuerst gecheckt, ob die Zahl/-en bereits vorhanden sind ... wenn nein werden sie ins Array übernommen und ausgegeben, wenn ja wird eine neue Zahl erzeugt. Als Ablaufdiagramm
Code:
mfGProgrammstart | Es wird ein dynamisches Array der Länge 0 definiert | Benutzer klickt auf Button | Es wird eine Zufallszahl erzeugt <---------------------------------------------------------- | | Entscheidungsvaribale := false; | | | <Kontrolle: ist die Zahl im Array? Am besten per for i := low(array) to high(array)> | Wenn ja, dann break und Entscheidungsvariable auf OK setzen | | | Wenn die Entscheidungsvariable auf true steht, setlength(array,lenght(array)+1); | und dann array[high(array)] := zahl; | Ansonsten wieder zurück zur Generierung ------------------------------------------------------- //Diese Operation wird 3x durchgeführt, einmal für jedes Label Markus EDIT: Heureka, er hat mir nur den Start verschoben ... und gar kein Roter Kasten? |
Re: 3 Zufallszahlen ohne Wiederholung
Hallo,
ich habe mal ein Formular mit dem nötigen Code erzeugt:
Delphi-Quellcode:
Auf dem Formular müssen ein Button und vier Label liegen.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; const // Zahlen von 1 bis 100 sind möglich. AnzahlZahlen = 100; type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Label3: TLabel; Button1: TButton; Label4: TLabel; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private ZahlVerwendet : array[1..AnzahlZahlen] of boolean; AnzahlverwendeterZahlen : Integer; public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var lk : Integer; begin // Es wurden noch keine Zahlen gezogen AnzahlverwendeterZahlen := 0; // Stellt im Array für jede Zahl ein, // dass sie noch nicht gezogen wurde. for lk := 1 to AnzahlZahlen do begin ZahlVerwendet[lk] := False; end; Randomize; end; procedure TForm1.Button1Click(Sender: TObject); var lk : Integer; li : Integer; Rnd : Integer; Cnt : Integer; begin if ((AnzahlZahlen - AnzahlverwendeterZahlen) < 3) then begin MessageDlg('Es können keine Zufallszahlen mehr gezogen', mtInformation, [mbOK], 0); Exit; end; // drei Zahlen werden gezogen for lk := 1 to 3 do begin // Berechnet, welche Zahl als Zufalllszahl genommen werden soll. // Ist Rnd = 4 soll z.B. die vierte noch nicht verwendete Zahl // benutzt werden. Rnd := Random(AnzahlZahlen - AnzahlverwendeterZahlen) + 1; Cnt := 0; for li := 1 to AnzahlZahlen do begin if (not ZahlVerwendet[li]) then begin Inc(Cnt); end; if (Cnt = Rnd) then begin Rnd := li; // Dies ist die zufällige Zahl ZahlVerwendet[li] := True; break; end; end; // for li Inc(AnzahlverwendeterZahlen); // Trägt die Zufallszahl in ein Label ein. case lk of 1: Label1.Caption := Format('%d', [Rnd]); 2: Label2.Caption := Format('%d', [Rnd]); 3: Label3.Caption := Format('%d', [Rnd]); end; // case end; // for lk Label4.Caption := Format('Anzahl verbleibender Züge: %d', [(AnzahlZahlen - AnzahlverwendeterZahlen) DIV 3]); end; end. Viele Grüße, pszopp |
Re: 3 Zufallszahlen ohne Wiederholung
Herzlich willkommen in der Delphi-PRAXiS, Scarlett.
Hier noch eine Alternative zum Ansatz von Markus. Dabei wird nicht immer wieder aus der Vorratsmenge gezogen und geprüfft, ob es zu einer Wiederholung kam. Hier wird das Urnenprinzip umgesetzt, bei dem eine Zahl nicht nocheinmal gezogen werden kann, da sie nach der Ziehung nicht mehr zum Vorrat gehört:
Delphi-Quellcode:
Den Vorrat bildest du vorher so:
uses
Types; function RandomSelect(var ida: TIntegerDynArray): Integer; var iRandom: Integer; begin iRandom := Random(Length(ida)); Result := ida[iRandom]; ida[iRandom] := ida[High(ida)]; SetLength(ida, High(ida)); end;
Delphi-Quellcode:
Freundliche Grüße vom marabu
var
Vorrat: TIntegerDynArray; begin SetLength(Vorrat, 10); for i := Low(Vorrat) to High(Vorrat) do Vorrat[i] := Succ(i); end; |
Re: 3 Zufallszahlen ohne Wiederholung
Vielen Dank für die vielen ausführlichen Antworten! :) Bin ja ganz begeistert!
Ich werd mir das alles noch mal ganz in Ruhe ansehen und ausprobieren. Falls ich dann noch irgendwelche Probleme haben sollte, dann melde ich mich wieder. Nochmals danke für die schnelle Hilfe! Adjööö, Scarlett |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz