Autor Beitrag
theevilworm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61



BeitragVerfasst: Do 18.02.10 10:34 
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:

ausblenden 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..49of integer;
    gezogen:array[1..6of 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 183
Erhaltene Danke: 7

Win7
Delphi XE5 Starter, RAD Studio XE7 Pro
BeitragVerfasst: 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.

ausblenden 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..49of integer;
    gezogen:array[1..6of 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.

ausblenden volle Höhe 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..6of 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

_________________
Es gibt keine dummen Fragen, nur dumme Antworten.
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 18.02.10 14:06 
user profile iconjackle32 hat folgendes geschrieben Zum zitierten Posting springen:
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:

ausblenden 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 .. 6of integer, Zahl: Integer): Boolean;
   var i : Integer;
begin
   result := Zahl in gezogen; //Uuuh lang ist's her dass ich Delphi gecoded hab - funktioniert das??
   //wenn nicht, nutze diesen code hier: (erste Zeile auskommentieren, die {} hier wegmachen.
   {result := false;
   for i := 1 to 6 do
      result := result or (gezogen[i] = Zahl);}

end;

procedure TForm1.Button2Click(Sender: TObject);
var
  gezogen: array[1..6of 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 182
Erhaltene Danke: 14



BeitragVerfasst: Do 18.02.10 14:26 
user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 18.02.10 14:27 
user profile iconguinnes hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 182
Erhaltene Danke: 14



BeitragVerfasst: Do 18.02.10 14:37 
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: 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. :les: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: 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 :)

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.