Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Doppelte Zahlen beim Lotto Generator (https://www.delphipraxis.net/66568-doppelte-zahlen-beim-lotto-generator.html)

g-hun 31. Mär 2006 15:01


Doppelte Zahlen beim Lotto Generator
 
Hallo!

Ich habe ein kleines Problem:

Ich versuche in moment ein Lotto Generator zu Programmieren.
Ich habe nix weiteres außer if... then und repeat...until eingesetzt.
Aber irgendwie klappt das nicht und es kommen doppelte Zahlen raus.
Guckt euch das mal an:

Delphi-Quellcode:
....

var zahl:array[1..6] of integer;
    nr1,nr2:integer;
procedure TForm1.Button1Click(Sender: TObject);
begin

  randomize;
  zahl[1]:=random(49)+1;
  zahl[2]:=random(49)+1;
  zahl[3]:=random(49)+1;
  zahl[4]:=random(49)+1;
  zahl[5]:=random(49)+1;
  zahl[6]:=random(49)+1;

  panel1.caption:=inttostr(zahl[1]);
  panel2.caption:=inttostr(zahl[2]);
  panel3.caption:=inttostr(zahl[3]);
  panel4.caption:=inttostr(zahl[4]);
  panel5.caption:=inttostr(zahl[5]);
  panel6.caption:=inttostr(zahl[6]);



    if zahl[1] = zahl[2] or zahl[3] or zahl[4] or zahl[5] or zahl[6] then
      begin
      repeat
      zahl[1]:=random(49)+1;
      panel1.Caption:=inttostr(zahl[1]);
      until zahl[1] <> zahl[2] or zahl[3] or zahl[4] or zahl[5] or zahl[6];
      end;


       if zahl[2] = zahl[1] or zahl[3] or zahl[4] or zahl[5] or zahl[6] then
      begin
      repeat
      zahl[2]:=random(49)+1;
      panel2.Caption:=inttostr(zahl[2]);
      until zahl[2] <> zahl[1] or zahl[3] or zahl[4] or zahl[5] or zahl[6];
      end;

       if zahl[3] = zahl[2] or zahl[1] or zahl[4] or zahl[5] or zahl[6] then
      begin
      repeat
      zahl[3]:=random(49)+1;
      panel3.Caption:=inttostr(zahl[3]);
      until zahl[3] <> zahl[2] or zahl[1] or zahl[4] or zahl[5] or zahl[6];
      end;

       if zahl[4] = zahl[2] or zahl[3] or zahl[1] or zahl[5] or zahl[6] then
      begin
      repeat
      zahl[4]:=random(49)+1;
      panel4.Caption:=inttostr(zahl[4]);
      until zahl[4] <> zahl[2] or zahl[3] or zahl[1] or zahl[5] or zahl[6];
      end;

       if zahl[5] = zahl[2] or zahl[3] or zahl[4] or zahl[1] or zahl[6] then
      begin
      repeat
      zahl[5]:=random(49)+1;
      panel5.Caption:=inttostr(zahl[5]);
      until zahl[5] <> zahl[2] or zahl[3] or zahl[4] or zahl[1] or zahl[6];
      end;

       if zahl[6] = zahl[2] or zahl[3] or zahl[4] or zahl[5] or zahl[1] then
      begin
      repeat
      zahl[6]:=random(49)+1;
      panel6.Caption:=inttostr(zahl[6]);
      until zahl[6] <> zahl[2] or zahl[3] or zahl[4] or zahl[5] or zahl[1];
      end;

Matze 31. Mär 2006 15:06

Re: Doppelte Zahlen beim Lotto Generator
 
Hi,

der Code ist mies *g* Hier im Forum suchenLotto da findest sicher was schöneres. Aber als Übung ok, keine Frage.

Dein Fehler liegt im until Abschnitt, es müsste so in der Art lauten:

Delphi-Quellcode:
until (zahl[1] <> zahl[2]) and (zahl[1] <> zahl[3]) and
  (zahl[1] <> zahl[4]) and (zahl[1] <> zahl[5]) and (zahl[1] <> zahl[6]);
Nachtrag: Irgendwie müsste es doch and lauten. ^^

3_of_8 31. Mär 2006 15:13

Re: Doppelte Zahlen beim Lotto Generator
 
Wie soll das denn gehen? if zahl[1]=zahl[2] or zahl[3]...

Ich schlage vor du siehst dir nochmal ein paar Anfänger Tutorials an.

Delphi-Quellcode:
procedure GenerateLottoNumbers;
var isdouble: Boolean;
  I, J: Integer;
  zahl: array[1..6] of Integer;
begin;
randomize;
for I:=1 to 6 do
repeat
zahl[I]:=Random(49)+1;
for J:=1 to 6 do
begin
isdouble:=False;
if I<>J then isdouble:=isdouble or (zahl[I]=zahl[J]);
end;
until not isdouble;
for I:=1 to 6 do (findcomponent('Label'+inttostr(I))as TLabel).caption:=
   inttostr(zahl[I]);
end;

Nikolas 31. Mär 2006 15:20

Re: Doppelte Zahlen beim Lotto Generator
 
Hi Solche Blöcke wie
Delphi-Quellcode:
 zahl[1]:=random(49)+1;
zahl[2]:=random(49)+1;
zahl[3]:=random(49)+1;
zahl[4]:=random(49)+1;
zahl[5]:=random(49)+1;
zahl[6]:=random(49)+1;
sollten eher über eine Schleife gemacht werden, also
Delphi-Quellcode:
for i:=1 to 6 do
zahl[i]:= random(49)+1;
Wenn du nicht willst, dass Zahlen doppelt sind, kannst du auch von Anfang an nur die Zahlen benutzen, die noch nicht vorkamen. Du könntest dir z.B. ein Set anlegen, in dem die Zahlen stehen, die schon gezogen wurden, etwa so:
Delphi-Quellcode:
var
list: set of Byte;
begin
list:=[];
for i:=1 to 6 do
begin
  repeat
  j:= random(49)+1;
  until not j in list;
zahl[i]:=j;
list:= list+[j]; // Das sollte man nicht vergessen... s.u.
end;

end;
Für die Ausgabe wird dir FindComponent helfen, damit ist die Ausgabe auch ein zweizeiler:
Delphi-Quellcode:
for i:=1 to 6 do
fincomponent('Panel'+inttostr(i)).caption:=inttostr(Zahl[i]); // Oder so ähnlich.

himitsu 31. Mär 2006 15:22

Re: Doppelte Zahlen beim Lotto Generator
 
Oder so, wenn er nicht unbeding in 'ner Schleife alles machen will.
Wozu erst setzten, dann prüfen und danach was neues suchen, wenn man gleich passend suchen kann ^^
Delphi-Quellcode:
zahl[1] := random(49) + 1;
repeat
  zahl[2] := random(49) + 1;
until zahl[2] <> zahl[1];
repeat
  zahl[3] := random(49) + 1;
until (zahl[3] <> zahl[1]) and (zahl[3] <> zahl[2]);
repeat
  zahl[4] := random(49) + 1;
until (zahl[4] <> zahl[1]) and (zahl[4] <> zahl[2]) and (zahl[4] <> zahl[3]);
repeat
  zahl[5] := random(49) + 1;
until (zahl[5] <> zahl[1]) and (zahl[5] <> zahl[2]) and (zahl[5] <> zahl[3])
  and (zahl[5] <> zahl[4]);
repeat
  zahl[6] := random(49) + 1;
until (zahl[6] <> zahl[1]) and (zahl[6] <> zahl[2]) and (zahl[6] <> zahl[3])
  and (zahl[6] <> zahl[4]) and (zahl[6] <> zahl[5]);

panel1.caption := IntToStr(zahl[1]);
panel2.caption := IntToStr(zahl[2]);
panel3.caption := IntToStr(zahl[3]);
panel4.caption := IntToStr(zahl[4]);
panel5.caption := IntToStr(zahl[5]);
panel6.caption := IntToStr(zahl[6]);

alcaeus 31. Mär 2006 15:22

Re: Doppelte Zahlen beim Lotto Generator
 
Ok, und weil ich so langsam bin, korrigiere ich nur noch den Code von Toxman :mrgreen:

Delphi-Quellcode:
procedure GenerateNumbers();
var
  TakenNumbers: set of Byte;
  i: Integer;
  Numbers: array[1..6] of Byte;
begin
  TakenNumbers := [];
  for i := 1 to 6 do
  begin
    repeat
      Number[i] := Random(49)+1;
    until (not (Number[i] in TakenNumbers));
    TakenNumbers := TakenNumbers + [Number[i]];
  end;
end;
Was das sein soll lasse ihc dich ueberlegen. Es kompiliert, ob es funktioniert darfst du testen und es evtl. korrigieren.

@3_of_8: Deine Einrueckung ist ja schrecklich... ;)

Greetz
alcaeus

DP-Maintenance 31. Mär 2006 15:25

DP-Maintenance
 
Dieses Thema wurde von "Sharky" von "VCL / WinForms / Controls" nach "Object-Pascal / Delphi-Language" verschoben.
So oder so ist es keine Frage die in diese Sparte passt ;-)

Nikolas 31. Mär 2006 16:08

Re: Doppelte Zahlen beim Lotto Generator
 
hm. ja, stimmt, das ist ein sinnvoller Einwand. Mir war die Idee wichtig, da hab ich auf Feinheiten wie die Grenze nicht geachtet, aber das neue Setzen der Liste hab ich einfach vergessen. :duck:

Zitat:

Oder so, wenn er nicht unbeding in 'ner Schleife alles machen will.
Naja, wenn er aber mal 8 oder 20 solcher Zahlen haben will, wird so eine Lösung recht schnell recht unübersichtlich. Mit einer Schleife dauert die Anpassung 10sec.

g-hun 31. Mär 2006 16:12

Re: Doppelte Zahlen beim Lotto Generator
 
...

freak4fun 31. Mär 2006 16:16

Re: Doppelte Zahlen beim Lotto Generator
 
Es wird nur geschaut, ob die Zahl gleich der Zahl zuvor war, nicht ob sie gleich allen anderen sit. :)

MfG
freak

3_of_8 31. Mär 2006 16:18

Re: Doppelte Zahlen beim Lotto Generator
 
Also mein Code ist getestet und funktioniert. Hab einfach jetzt ned eingerückt, sonst mach ich das schon immer.

marabu 31. Mär 2006 16:24

Re: Doppelte Zahlen beim Lotto Generator
 
Hier noch ein paar Anregungen: klick

Grüße vom marabu

himitsu 31. Mär 2006 17:16

Re: Doppelte Zahlen beim Lotto Generator
 
nein, der Code sollte nicht ordnungsgemäß funtionieren:
isdouble:=False; muß for die Schleife, denn so wird nur die letzte Zahl geprüft.
for J:=1 to 6 do du prüfst auf Zahlen, die es noch nicht gibt (funktioniert zwar, ist aber nicht schön).
Und wozu 2 Schleifen?
Delphi-Quellcode:
procedure GenerateLottoNumbers;
var isdouble: Boolean;
  I, J: Integer;
  zahl: array[1..6] of Integer;

begin;
  randomize;
  for I:=1 to 6 do
  begin
    repeat
      zahl[I]:=Random(49)+1;
      isdouble:=False;
      for J:=1 to I - 1 do
        isdouble:=isdouble or (zahl[I]=zahl[J]);
    until not isdouble;
    TLabel(FindComponent('Label'+IntToStr(I))).Caption:=ItToStr(zahl[I]);
  end;
end;

Nikolas 31. Mär 2006 18:07

Re: Doppelte Zahlen beim Lotto Generator
 
Zitat:

for J:=1 to 6 do du prüfst auf Zahlen, die es noch nicht gibt (funktioniert zwar, ist aber nicht schön).
Und wozu 2 Schleifen?
Beziehst du dich auf meinen Post?

Die erste Schleife [for i:=1 to 6 do zahl[i]:= random(49)+1;] war nur dazu gedacht, zu zeigen, wie man den Block abkürzen kann und hat mit dem eigentlichen Ansatz nichts zu tun.

Um zu überprüfen, ob eine Zahl schon gezogen wurde, benutze ich das set, weil es schöner und wahrscheinlich schneller ist, einfach nur auf 'in Set' zu prüfen, als eine Schleife über alle schon gezogenen Zahlen zu machen, so wie du es in deinem Beispiel gemacht hast.

Delphi-Quellcode:
list: set of Byte;
i,j: integer;
zahl: array[1..6] of byte;
begin
list:=[];

for i:=1 to 6 do
begin
  repeat
  j:= random(49)+1;
  until (not (j in list));
zahl[i]:=j;
list:= list+[j];
end;

himitsu 31. Mär 2006 18:21

Re: Doppelte Zahlen beim Lotto Generator
 
Ups ... neee, dat war auf 3_of_8's Post bezogen °_°

Also auf Beitrag #3 und
Zitat:

Zitat von 3_of_8
Also mein Code ist getestet und funktioniert. Hab einfach jetzt ned eingerückt, sonst mach ich das schon immer.

Und das SET ist hier auch nicht schlecht, aber sobald die Zahlen nicht zwischen 0 und 255 liegen wird es damit etwas schwer, bis unmöglich :)

gfjs 1. Apr 2006 07:23

Re: Doppelte Zahlen beim Lotto Generator
 
Guten Morgen, Allerseits.

Ich würde folgende Arrays anlegen:

AlleZahlen : array[1..49] of byte;
EineZiehung : array[1..7] of byte; // sofern eine Zeihung simuliert werden soll
EinEinsatz : array[1..x] of byte; // wenn zufällig erzeugte Einsätze für x Zahlen erzeugt werden sollen;

Jede erzeugt Zahl würde ich im Array AlleZahlen auf Null setzen, so dass ich bei der nächsten Zahl ganz einfach prüfen könnte, ob die Zahl bereits einmal erzeugt wurde. Das ganze so lange laufen lassen, bis die gewünschte Zahl von Zahlen erzeugt ist und abschließend das Array AlleZahlen wieder in den ursprünglichen Zustand verseten.

Delphi-Quellcode:
procedure Ziehung;
begin
  i := 1;
  repeat
    Ramdomize;
    zahl := random(49)+1;
    if AlleZahlen(zahl] <> 0 then
    begin
      EineZiehung[i] := zahl; // oder EinEinsatz[i] := zahl;
      AlleZahlen[i] := 0;
      inc[i];
    end;
  until i = 7; // oder i = x für Einsätze mit x Zahlen
  for i := 1 to 49 do AlleZahlen[i] := i;
end;
Ich habe das nur mal so schnell hingeschrieben und nicht getestet, weil ich im Büro kein Delphi auf dem Rechner habe, sollte aber klappen.

mfg gfjs

KLS 1. Apr 2006 07:49

Re: Doppelte Zahlen beim Lotto Generator
 
Das selbe thema hatte ich vor kurzem in nem anderen Forum auch gesehen.

http://forum.giga.de/showthread.php?t=698407

Khabarakh 1. Apr 2006 08:28

Re: Doppelte Zahlen beim Lotto Generator
 
Bei 7 aus 49 noch kein wirkliches Problem, aber sobald sich die Anzahl der gezogenen Elemente vergrößert, führt die Random-Try-And-Error-Taktik immer mehr zur Endlosschleife hin. Permutationen würden sich dann eher anbieten, die bleiben immer linear.

[edit] @gfjs: Wenn du nur auf Ungleichheit zu 0 prüfst, kannst du gleich ein Boolean-Array verwenden. [/edit]

negaH 1. Apr 2006 11:22

Re: Doppelte Zahlen beim Lotto Generator
 
Lies dir diesen Thread http://www.delphipraxis.net/internal...ct.php?t=10946 mal ganz genau durch.
Alle Vorschläge hier sind defakto falsch und betrachten das Problem nur ingenieurtechnisch und sind selbst dann nicht sonderlich elegant.

Gruß Hagen

Armageddon 1. Apr 2006 12:33

Re: Doppelte Zahlen beim Lotto Generator
 
Das hab ich grad durch Zufall im Easy Delphi Helper gesehen. Dachte ich poste es mal, vielleicht hilfts ja.

Delphi-Quellcode:
procedure TMainForm.Button1Click(Sender: TObject);
 var Zahlen: Array[1..49] of Boolean;
     i, z: Integer;
begin
  for i:= 1 to 49 do Zahlen[i]:=false;
  for i:=1 to 6 do begin
   repeat
    z:=random(49)+1
   until Zahlen[z] = false;
   Zahlen[z]:=true;
  end;
  Edit1.Text:='';
  for i:=1 to 49 do
   if Zahlen[i] then Edit1.Text:=Edit1.Text+' '+Inttostr(i)+' ';
end;

Khabarakh 1. Apr 2006 12:44

Re: Doppelte Zahlen beim Lotto Generator
 
Zitat:

Zitat von negaH
Alle Vorschläge hier sind defakto falsch und betrachten das Problem nur ingenieurtechnisch und sind selbst dann nicht sonderlich elegant.

Permutationen werden zwar ein 0..48-Array benötigen, aber die Warsrcheinlichkeiten sollten doch die gleichen wie in deinem Code sein: 1/49, 1/48, 1/47, ...
Soll heißen, ich fülle das Array, erzeuge eine zufällige Permutation und betrachte die ersten n Elemente als Ergebnis.

@Armageddon: Du erinnerst mich an axelf98 aus Hagens verlinktem Thread...

negaH 1. Apr 2006 13:53

Re: Doppelte Zahlen beim Lotto Generator
 
@Khabarakh:

Oh, dein Kommentar ist die einzigste korrekte Feststellung im Thread gewesen ! Dich hatte ich also garnicht gemeint. Eine zufällige Permutation mit dem Ziel nur die ersten 6 Elemente mit einem Schlage herauszunehmen produziert tatsächlich eine Wahrscheinlichkeit die dem Verfahren "Ziehung ohne Zurücklegen" entspräche.
Der Unterschied ist ja:

Permutation -> Wahrscheinlichkeiten wie bei "Ziehung ohne Zurücklegen" -> Lotto
Kombination -> Wahrscheinlichkeiten wie bei "Ziehung mit Zurücklegen" -> Würfeln

Ich zielte aber nicht auf den theoretischen Sachverhalt ab, sondern eher auf die Diskrepanz zwischen der Realität einer Lottoziehung und der dahinter liegenden Theorie hin zur den hier vorgestellten praktischen Umsetzungen.
Diese Umsetzungen erfüllen eben nicht diese Vorgaben !

Und exakt die Aufgabe eines "Lotto" Generators benutzte ich gerne bei Lehrlingen um zu sehen ob diese den obigen Sachverhalt aus der Problemstellung selbstständig erkennen konnten. Und ich meine das dies der gleiche Grund ist warum bei Lehrern dieses Problem so beliebt ist.

@Armageddon:

nimmt man's genau dann holft dies eben nicht, siehe oben.

Gruß Hagen

Armageddon 1. Apr 2006 15:37

Re: Doppelte Zahlen beim Lotto Generator
 
Zitat:

@Armageddon: Du erinnerst mich an axelf98 aus Hagens verlinktem Thread...
Keine Ahnung wen Du meinst. Hab das einfach dort rauskopiert und hier gepostet weil mit der Helper auf meiner Festplatte beim entrümpeln grad über den Weg gelaufen ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz