Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Lottozahlen generieren
theevilworm - Do 18.02.10 10:34
Titel: Lottozahlen generieren
Hallo,
nachdem ihm im Thread Lottozahlen generieren - Struktogramm viele Tipps bekommen habe,
hab ich mal versucht, die vielen Tipps in Delphi umzusetzen.
Folgendes ist mein Quellcode:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| procedure TForm1.Button1Click(Sender: TObject); var pott:array[1..49] of integer; gezogen:array[1..6] of integer; i,k:integer;
label JUMPHERE; begin
for i:=1 to 49 do pott[i]:=i;
for i:=1 to 6 do JUMPHERE: k:=Random(49)+1; gezogen[i]:=pott[k];
If gezogen[i]=333 Then goto JUMPHERE else pott[k]:=333;
For i:=1 to 6 do label1.Caption:=label1.caption+IntToStr(gezogen[i])+' '; |
Das startet zwar, funktioniert aber gar nicht so, wie ich wollte.
Mein eigentlicher Ablauf sollte so sein:
1.Generiere einen Pott aller Zahlen von 1 bis 49.
2.Ziehe dir eine Zufällige Zahl und weise sie einer der gezogenen Zahlen zu.
3. Prüfe, ob die gezogene Zahl 333 ist.
4. Wenn ja: Springe wieder zu 2. und generiere eine neue Zahl.
4b. Wenn nein: Behalte die gezogene Zahl und weise der Zahl im Pott 333 zu.
5. Schreibe alle gezogenen Zahlen.
333 habe ich einfach als Merkmal für bereits gezogene Zahlen genommen, ich hätte auch 555 oder sowas nehmen können.
Das Problem: Beim Klick auf den Button generiert er mir total merkwürdige Zahlen, z.B.:
1242836 0 1 2011200533 1242376 380
Diese Zahlen sind immer ziemlich ähnlich und haben gleich viele Stellen.
Warum? Ich habe doch nur einen Pott von 1 bis 49. Woher kommen diese Zahlen?
jackle32 - Do 18.02.10 11:51
Hi,
zu deinem Sourcecode gibt es folgendes zu sagen. Du hast die "begin" und "end" bezeichner vergessen. Da ohne diese die for Schleife nur die nächste Zeile immer wieder ausführt. Das führt dazu, dass das gezogen array nie gefüllt wird und dadurch einfach die zufälligen Zahlen drin stehen, wie eben der Speicher an dieser Stelle aussieht.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| procedure TForm1.Button1Click(Sender: TObject); var pott:array[1..49] of integer; gezogen:array[1..6] of integer; i,k:integer;
label JUMPHERE; begin
for i:=1 to 49 do pott[i]:=i;
for i:=1 to 6 do JUMPHERE: begin k:=Random(49)+1; gezogen[i]:=pott[k];
If gezogen[i]=333 Then goto JUMPHERE else pott[k]:=333; end;
For i:=1 to 6 do label1.Caption:=label1.caption+IntToStr(gezogen[i])+' ';
end; |
Grundsätzlich finde ich eine Programmierung mit Jumps nicht wirklich gut (meine Meinung). Daher hätte ich noch eine Variante nur mit Schleifen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| procedure TForm1.Button2Click(Sender: TObject); var gezogen: array[1..6] of integer; zeiger, i, temp: integer; gueltig: boolean; begin zeiger := 1;
repeat gueltig := true; temp := Random(49)+1;
for i := 1 to zeiger do begin if gezogen[i] = temp then begin gueltig := false; break; end; end;
if gueltig then begin gezogen[zeiger]:= temp; zeiger := zeiger+1; end;
until zeiger > 6;
For i:=1 to 6 do label1.Caption:=label1.caption+IntToStr(gezogen[i])+' ';
end; |
Ich hoffe es hilft weiter.
Gruß Jack
JayEff - Do 18.02.10 14:06
jackle32 hat folgendes geschrieben : |
Grundsätzlich finde ich eine Programmierung mit Jumps nicht wirklich gut (meine Meinung). |
Pfui! Pfuipfuipfuipfuipfui! Während Spagetti mit Tomatensoße sicherlich lecker sind, haben die im Quellcode wirklich garnichts verloren! :evil:
Niemals Goto verwenden. Und kommt mir micht mit "hmmm manchmal ganz sinnvoll", denn das ist nicht korrekt. Es lässt sich mathematisch Beweisen dass goto gleichmächtig ist wie while - nur viel hässlicher! An der Uni verbieten sie uns sogar explizit, goto zu verwenden, und bestrafen uns mit 0 Punkten für die Abgabe, wenn auch nur eines vorkommt. Aber das ist Off Topic :oops:
Zum ziehen von 6 einzigartigen Zufallszahlen: nutze eine Repeat-Until-schleife um zu verhindern, dass eine Zahl 2 mal gezogen wird:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| function GabsSchon(gezogen: array[1 .. 6] of integer, Zahl: Integer): Boolean; var i : Integer; begin result := Zahl in gezogen; end;
procedure TForm1.Button2Click(Sender: TObject); var gezogen: array[1..6] of integer; i, temp : Integer; begin for i := 1 to 6 do begin repeat temp := Random(49) + 1; until not GabsSchon(gezogen, temp); gezogen[i] := temp; end; end; |
Ich bin mir jetzt nicht mehr sicher, ob man auf die Art arrays an Funktionen übergeben kann :oops:
guinnes - Do 18.02.10 14:26
JayEff hat folgendes geschrieben : |
Ich bin mir jetzt nicht mehr sicher, ob man auf die Art arrays an Funktionen übergeben kann :oops: |
Warum eigentlich ein Array ? Benutz doch einfach ein Set. Dann brauchst du nicht mal eine extra Funktion
JayEff - Do 18.02.10 14:27
guinnes hat folgendes geschrieben : |
Warum eigentlich ein Array ? Benutz doch einfach ein Set. |
Hmm :gruebel: Kannst du mir dazu Beispielcode geben? Ich versteh grad nicht ganz, wie du das meinst.
guinnes - Do 18.02.10 14:37
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| Type TLottoZahl = 1..49; TLottoSet = set of TLottoZahl;
procedure ZieheZahlen; var I : Integer; TheSet : TLottoSet; Zahl : TLottoZahl; begin TheSet := []; For I := 1 to 6 do Begin Repeat Zahl := Random(49) + 1; until not (Zahl in Theet; Include(TheSet,Zahl); end; end; |
Narses - Fr 19.02.10 01:49
Moin!
Ich werde vermutlich nie verstehen, warum man Lottozahlen (in der Schule) immer nach dem Zufallszahl-ziehen-und-schauen-ob-schon-gezogen-wurde-wenn-ja-verwerfen-und-neu-ziehen "Algorithmus" vermittelt werden... :gruebel: Das widerspricht doch total der natürlichen Herangehensweise. :nixweiss: Es wird ja sogar im Fernsehn übertragen, wobei mir noch nie aufgefallen ist, dass die immer neue Kugeln pressen, zufällig eine Zahl draufschreiben, schauen, ob die schon da ist und - ach wie schade - im Mülleimer landet, so dass die nächste Kugel aus der Kugelpresse rollen kann... :nut: :lol:
Vielmehr existieren alle Kugeln passend bedruckt schon ;) werden nur noch gemischt, und dann werden 6 Stück "gezogen". Also Array 1..49 anlegen, mischen, und die ersten 6 Zahlen nehmen, fertig. :think: Details gibt´s
hier [
http://www.delphi-library.de/topic_perfektes+Mischen+nach+FisherYates+perfect+shuffle_71713.html]. :les: ;)
cu
Narses
JayEff - Fr 19.02.10 12:11
Sicher, das wär auch meine erste Idee gewesen, aber ich denke mal, man sollte den Algorithmus den man schreibt auch verstehen - Sicher, der Fisher-Yates ist jetzt nicht wahnsinnig kompliziert aber doch komplizierter als meine repeat-until-Schleife, die freilich an Effizienz kaum zu unterbieten ist.
Also, theevilworm, wenn du's effizient haben willst und ein bisschen Ehrgeiz beweisen willst, schau dir den Fisher-Yates an, den Narses gepostet hat, und versuche zu verstehen, wie der auf ein Array mit Zahlen von 1-49 wirkt und nutz den, um deine Lotto-Zahlen zu generieren ;)
Viel Erfolg damit :)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!