![]() |
Re: Zufallszahl ziehen ohne wiederholung
Zitat:
Delphi-Quellcode:
hier eine Exception (wenn du mal die Bereichsprüfung anschaltes)
for i:=0 to length(zufall) do
Delphi-Quellcode:
die 40 (Index 39) gibt's nicht, da 0..38
a:=random(39);
Delphi-Quellcode:
OK, kein Fehler, aber der Index is die Zahl-1, da braucht man nicht unbedingt ein Array of Integer ... Array of Boolean hätt's auch getan,
zufall: array of integer;
denn die zugehörige Zahl kann man sich ja aus dem Index errechnen. PS: bei Array[1..40] of Boolean wär der Index direkt die Zahl
Delphi-Quellcode:
If MeinZahlenArray[gezogeneZahl] Then {zahl wurde gezogen}
oder gleich ein Set of 1..40 :angel:
Delphi-Quellcode:
Var gezogeneZahlen: Set of 1..40;
Zufallszahl: Integer; gezogeneZahlen := []; // init If gezogeneZahlen <> [1..40] Then Begin Repeat Zufallszahl := Random(40) + 1; Until not (Zufallszahl in gezogeneZahlen); Include(gezogeneZahlen, Zufallszahl); End Else Raise Exception.Create('Es gibt keine Zahlen mehr.'); MessageBox(0, PChar(Format('Die Zahl %d wurde soeben gezogen.', [Zufallszahl])), 'test', MB_OK);
Delphi-Quellcode:
Var gezogeneZahlen: Set of 1..40;
Zufallszahl, i: Integer; gezogeneZahlen := []; For i := 1 to 15 do Begin Repeat Zufallszahl := Random(40) + 1; Until not (Zufallszahl in gezogeneZahlen); Include(gezogeneZahlen, Zufallszahl); MessageBox(0, PChar(Format('Die %d. Zahl ist eine %d.', [i, Zufallszahl])), 'test', MB_OK); End; |
Re: Zufallszahl ziehen ohne wiederholung
Wenn's nicht mehr als 255 Fragen sein sollen, könnte man auch eine Lösung mit einem String basteln.
Das sieht dann so aus: Stelle 1 = #1 Stelle 2 = #2 etc. Nach jedem Ziehen wird das gezogene Zeichen aus dem String gelöscht. beispielsweise so:
Delphi-Quellcode:
const gesamt=40;
anzahl=15; var liste: string; procedure TForm1.FormCreate(Sender: TObject); var i:integer; begin Randomize; liste:=''; for i:=1 to gesamt do liste:=liste+chr(i); end; procedure TForm1.Button1Click(Sender: TObject); var p,z:integer; begin if length(liste)<=gesamt-anzahl then begin showmessage('Fertig!'); exit; end; p:=Random(length(liste))+1; z:=ord(liste[p]); delete(liste,p,1); frage(z); end; procedure TForm1.frage(z: integer); begin ListBox1.Items.Add(IntToStr(z)); // hier sollte natürlich die eigentliche Frage // mit der Nr. z bearbeitet werden end; Zitat:
|
Re: Zufallszahl ziehen ohne wiederholung
@globetrotter77: mit WideString/UnicodeString ginge das bis 65536
und mit einem "eigenem" Delete ginge das noch viel weiter, wobei man da auch direkt die Fragen/Antworten direkt in das array packen kann, oder da zusätzlich noch einen Benutzt-Boolean in das Array of Record und man braucht garnicht löschen. |
Re: Zufallszahl ziehen ohne wiederholung
@ Globetrotter!
deine Antwort fand ich bis jetzt am besten, da sie für mich einigermaßen verständlich war! ich weiß nur nicht, wo ich den teil mit
Delphi-Quellcode:
[b]hinpacken soll bei der deklaration!? Public, Private??
const gesamt=40;
anzahl=15; |
Re: Zufallszahl ziehen ohne wiederholung
Zitat:
Das mit dem Benutzt-Kennzeichen funktioniert aber nicht ganz so gut, weil du dann zumindest theoretisch in eine Endlosschleife kommen könntest. Die Fragen würde ich von außen über eine INI beisteuern. z.B. Zitat:
|
Re: Zufallszahl ziehen ohne wiederholung
Zitat:
Da es sich aber um ganz einfache Definitionen handelt, die nicht unbedingt was mit der Klasse zu tun haben, geht es ebenso im implementation-Bereich, wobei du nur darauf achten musst, dass die Definition OBERHALB derjenigen Funktionen und Prozeduren steht, die darauf zugreifen! z.B. so:
Delphi-Quellcode:
var
Form1: TForm1; implementation {$R *.DFM} const gesamt=40; anzahl=15; var liste: string; procedure TForm1.FormCreate(Sender: TObject); begin Randomize; ButtonNeuClick(Sender); end; |
Re: Zufallszahl ziehen ohne wiederholung
Danke Globetrotter, mit deiner Variante hab ichs hinbekommen!!!
|
Re: Zufallszahl ziehen ohne wiederholung
Zitat:
Versuch aber auf jeden Fall, genau zu verstehen, wieso das so funktioniert! Sonst stehst du da nächste Mal wieder da wie der Ochs vor dem Berg! :? |
Re: Zufallszahl ziehen ohne wiederholung
Hallo zusammen,
auch wenn es schon Lösungen gibt, so möchte ich für die genannte Anforderung auf die Umsetzung in Form eines boolschen Array hinweisen. Für einen Lottogenerator hatte ich es mal wie nachfolgend zu sehen umgesetzt.
Delphi-Quellcode:
Hiermit hat man die 2 Eigenschaften welche benötigt werden (Anzahl von Werten und den boolschen Wert ob schon "gezogen" oder nicht).
procedure TForm1.Btn1Click(Sender: TObject);
var lAb_Anzahl_Werte_Depot: Array[1..49] of Boolean; i, Zufallszahl: Integer; begin for i:= 1 to 49 do lAb_Anzahl_Werte_Depot[i]:=false; for i:=1 to 6 do begin repeat Zufallszahl:=random(49)+1 until lAb_Anzahl_Werte_Depot[Zufallszahl] = false; lAb_Anzahl_Werte_Depot[Zufallszahl]:=true; end; Edit1.Text:=''; for i:=1 to 49 do if lAb_Anzahl_Werte_Depot[i] then Edit1.Text:= Edit1.Text + ' ' + Inttostr(i) + ' '; end; |
Re: Zufallszahl ziehen ohne wiederholung
Zitat:
Zitat:
Delphi-Quellcode:
oder besser noch 'nen knuffiges While-Do-Schleifchen
i := -1;
for i2 := 1 to 40 if not meinArray[i2].istSchonBenutzt then begin i := i2; break; end; if i <> -1 then begin meinArray[i].isSchonBenutzt := true; ShowMessage('Zahl ', i, ' wurde gezogen.'); end else nichts_mehr_frei;
Delphi-Quellcode:
i := 1;
while (i <= 40) and meinArray[i].istSchonBenutzt do Inc(i); if i <= 40 then begin meinArray[i].isSchonBenutzt := true; ShowMessage('Zahl ', i, ' wurde gezogen und die Frage is "', meinArray[i].dieFrage, '".'); end else nichts_mehr_frei; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:17 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 by Thomas Breitkreuz