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



BeitragVerfasst: Do 11.02.10 18:55 
Hallo zusammen,

zuerst einmal: natürlich habe ich die Suche verwendet, es gibt da ein paar Threads zu Lottozahlen, aber meine Frage ist etwas anders.
Wir haben in der Schule in Informatik heute mit Arrays angefangen und sollten zum Anfang einen Lottozahlen-generator-Konzept entwickeln, mit einem Struktogramm.

Hier mal mein Versuch:
Struktogramm_Lotto

EDIT: Ups, erst nach dem Uploaden gemerkt: Die Abfrage, ob die Zahl schon mal gezogen wurde, wird ja nur einmal ausgeführt. Wenn die neue Zufallszahl unwahrscheinlicherweise nochmal die gleiche sein sollte, wird das ja nicht nochmal abgefragt. Deswegen muss die Abfrage in die Prozedur "Ziehen" rein.

Ich habe jedoch ein paar Probleme:

1. Ich habe das auf zwei Prozeduren bzw. Struktogramme aufgeteilt, da ich nicht wusste, wie ich sonst nochmal beliebig oft eine neue Zufallszahl generieren lassen sollte, falls die aktuelle in den letzten gezogenen Zahlen schon enthalten sein sollte

2. Ich habe die Zähschleife erst bei 2 starten lassen und davor manuell Lottozahlen[1] eine Zufallszahl zugewiesen, da ich ja sonst bei in der Zählschleife kein Lottozahl[i-1] gehabt hätte, mit dem ich hätte vergleichen können.

3. Aus den zwei Prozedure entsteht ein Problem: Die Zählervariable i muss global sein, damit die Prozedur "Ziehen" weiß, welchem Index von Lottozahl die Zufallszahl gewiesen werden muss. Mein Informatiklehrer meinte aber glaube ich mal, Zählervariablen lässt Delphi nicht global zu?

Falls es trotzdem in Delphi realisirbar sein sollte, ist es trotzdem ziemlich unelegant, oder? Wie könnte ich das besser machen? Ich danke euch für alle Antworten ;)


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Fr 12.02.2010 um 17:33
Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 11.02.10 19:07 
also
1) Die 2. Prozedur ist nicht nötig. Schreibs einfach rein. Wegen einer Anweisung brauch man keine 2.Prozedur, der du das Array und die Variable übergeben musst.
2) Statt dem Wenn, muss ein SOLANGE verwendet werden sonst:
Lottozahl[1]<-5
Für...
Lottozahl[2]<-5
Dann...
Lottozahl[2]<-5
Für...
Lottozahl[3]<-44

-->Die 5 kann (im Extremfall) mehrfach auftreten, da du nur nach der ersten zuweisung prüfst.
Dann lieber eine Fußgesteuerte Schleife, dann brauchst du auch die Anweisung nur einmal (zweimal mit dem einen vor der Für...)
theevilworm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61



BeitragVerfasst: Do 11.02.10 19:16 
Hallo,

danke für deine Hilfe, hat mir nen Denkanstoß verpasst. Ist es so besser:

Struktogramm_Lotto_2

Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 11.02.10 19:22 
besser ja
aber ich hatte was von fußgesteuerter schleife gesagt ;-)
guck dir die mal an ;-)
theevilworm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61



BeitragVerfasst: Do 11.02.10 19:45 
Hm, ich bin nicht sicher, was du meinst... Vielleicht so:
Struktogramm_Lotto_3
Aber wie sollte ich die Endbedingung in Delphi realisieren?

ausblenden Delphi-Quelltext
1:
Until Lottozahl[i] not in [Lottozahl[1]..Lottozahl[i-1]];					


Ich glaube nicht, dass diese Zeile in Delphi durch den Debugger kommt.

Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Do 11.02.10 20:01 
Für zufällige, gleichverteilte Lottozahlen sollte man aber diesen Algorithmus benutzen:
www.delphi-library.d...t+shuffle_71713.html
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 11.02.10 20:37 
ist richtig!
auch delphi kann das.

3 schleifen arten
for: Zählschleife wenn anzahl vorher feststeht
kopfgesteuert, fußgesteuert: bedingung prüfen, fußgesteuert: wird mind. 1 mal ausgeführt
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Fr 12.02.10 17:23 
user profile iconBoldar hat folgendes geschrieben Zum zitierten Posting springen:
Für zufällige, gleichverteilte Lottozahlen sollte man aber diesen Algorithmus benutzen:
www.delphi-library.d...t+shuffle_71713.html

Da möchte ich noch einmal einen ganz interessanten Blog-Eintrag in die Runde werfen: The Danger of Naïveté. :)

Für diesen Beitrag haben gedankt: Mitmischer 1703
theevilworm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61



BeitragVerfasst: Mo 15.02.10 13:43 
Hi Leute, habe das gerade mal versucht in Delphi zu realisieren, doch folgendes klappt so nicht:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);
var lottozahlen:array[0..6of Integer;
    i:integer;
begin
lottozahlen[1]:=Random(49)+1;

For i:=2 to 6 do
  begin
  Repeat
  lottozahlen[i]:=Random(49)+1;
  Until
  lottozahlen[i] not in [Lottozahlen[1]..Lottozahlen[i-1]];
  end;

end;


Fehlermeldungen:
Zitat:

Operator oder Semikolon fehlt
Operator ist auf diesen Operandentyp nicht anwendbar


EDIT:
Habs nun wenigstens zum Laufen gebracht, indem ich statt "Repeat...Until" "While" eingesetzt habe:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
For i:=2 to 6 do
  begin
  Randomize;
  Lottozahlen[i]:=Random(49)+1;
  While Lottozahlen[i] in [Lottozahlen[1]..Lottozahlen[i-1]] do
    Lottozahlen[i]:=Random(49)+1;
  end;


Das startet ohne Fehlermeldungen, funktioniert aber nicht. Nach nur dreimal Generieren sind schon doppelte Zahlen erschienden, obwohl das doch eigentlich nicht passieren sollte!
martin300
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Mo 15.02.10 15:13 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  Lottozahlen[i]:=Random(49)+1;
  While Lottozahlen[i] in [Lottozahlen[1]..Lottozahlen[i-1]] do
    Lottozahlen[i]:=Random(49)+1; <-- hier wird wieder eine neue Zahl erzeugt
  end;

...es sollte jedoch die zuvor erzeugte verwendet werden und daher können sie doppelt sein.
martin300
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Mo 15.02.10 15:18 
Wenn ich mir Lottozahlen erzeugen müsste würde ich so vorgehen:
+ Menge der möglichen Zahlen (1..49) erzeugen
+ Zufallszahl generieren
+ Befindet sich Zahl in der Menge --> ja: Lottozahl speichern und aus möglichen Zahlen entfernen
--> nein: nochmal eine Zahl erzeugen
+ das ganze so oft wiederholen bis gewünschte Anzahl von Zahlen erzeugt wurde.
SvenAbeln
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 334
Erhaltene Danke: 3



BeitragVerfasst: Mo 15.02.10 16:25 
Zu deinem Fehler:
Zitat:

Operator oder Semikolon fehlt
Operator ist auf diesen Operandentyp nicht anwendbar

In deiner Zeile muss das not an den Anfang:
ausblenden Delphi-Quelltext
1:
not (lottozahlen[i] in [Lottozahlen[1]..Lottozahlen[i-1]])					


Dein Vergleich macht aber nicht das was du erwartest.
(lottozahlen[i] in [Lottozahlen[1]..Lottozahlen[i-1]]
Prüft nicht gegen alle Einträge deines Array, sondern nur ob die neue Zahl zwischen der ersten und der letzten Zahl ist.
z.B:
1 Zahl = 8
2 zahl = 25
Dann darf die dritte Zahl bei dir nicht zwischen 8 und 25 sein.

Für Lottozahlen[1] > Lottozahlen[i-1] ist dann jede Zahl erlaubt.
theevilworm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61



BeitragVerfasst: Mi 17.02.10 15:56 
Hallo,

danke für eure Hinweise - da wäre ich gar nicht drauf gekommen. Doofe Logikfehler.
Und wie kann ich das jetzt so schreiben, dass es keine doppelten Zahlen generiert?

@martin300

Auch eine Möglichkeit, ich habe aber keine Ahnung, wie ich das realisieren könnten - hast du einen Tipp?
COMMANDER86
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 167

Win XP, Win Vista
D3 Prof., D7 Pers., Lazarus
BeitragVerfasst: Do 18.02.10 00:14 
Heyho,

ich habe sowas auch mal gebastelt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TfrmLotto.btnGenerierenClick(Sender: TObject);
var
  I, ZAHL: integer;
label
  RETOUR;
begin
  Randomize;
  ZAHL := Random(49) + 1;

  for I := 1 to 6 do
  begin
    RETOUR:
    if ZahlenCheck(ZAHL) = True then
    begin
      ZAHL := Random(49) + 1;
      goto RETOUR;
    end else LOTTO[I] := ZAHL;
  end;
//...


Den Array (LOTTO) hab' ich da global deklariert, weil die Überprüfung, ob die Zahl im Array vorkommt (ZahlenCheck), ausgelagert ist:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function ZahlenCheck(ZAHL: integer): boolean;
var I: integer;
begin
  RESULT := False;

  for I := 1 to 6 do
  begin
    if LOTTO[I] = ZAHL then
    begin
      RESULT := True;
      Exit;
    end;
  end;
end;


Der Rest ist noch eine Sortierung und die Ausgabe.

Ja, ich weiß... goto. ;) Ich bin der Meinung, dass man das an einer so übersichtlichen Stelle durchaus mal einsetzen darf.

LG
Fabian

_________________
Streichen Sie bitte sämtlichen Sarkasmus aus vorhergehender Nachricht. Dann wissen Sie, was ich sagen möchte. Meine Lösungen sind die vermutlich Umständlichsten, aber sie funktionieren (bei mir). ;)
martin300
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Do 18.02.10 11:21 
hi,
hier eine andere Möglichkeit:
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:
29:
30:
procedure TForm1.btn1Click(Sender: TObject);
var
  lottozahlen : set of 1..49//1,2,3..48,49
  lottozahl : array [1..6of Integer;
  i: Integer;
begin
  i := 1;
  while i <= 6 do
  begin
    lottozahl[i] := Random(49)+1;
    if (lottozahl[i] in lottozahlen) then
    begin
      // Zahl ist das erste Mal in der Liste
      i := i + 1;
      // Entferne Zahl aus der Menge
      lottozahlen := lottozahlen - [lottozahl[i]];
    end else
    begin
      // Zahl kommt schon mal vor
      // else kann komplett wegfallen
    end;
  end;

  // Ausgabe
  for i := 1 to 6 do
  begin
    // Ausgabe in Memo Komponente
    mmo1.Lines.Add(IntToStr(lottozahl[i]));
  end;
end;

Für diesen Beitrag haben gedankt: Petroglyph
TechCruncher
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mi 12.10.11 18:44 
Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Danke, der Code geht bei mir!!!
Ich würde das gerne für ein weiteres Tool für [url=www.gewinn-zahlen.co...us49-lotto-samstag/]lottozahlen[/URL] nutzen, darf man das überhaupt oder muss man zuerst um Zustimmung bitten?