AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

Ein Thema von yga · begonnen am 25. Jan 2012 · letzter Beitrag vom 26. Jan 2012
Antwort Antwort
Seite 1 von 2  1 2      
yga

Registriert seit: 25. Jan 2012
4 Beiträge
 
#1

Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 20:14
Delphi-Version: 7
Hallo Community,
ich bin Info-Neuling und schlicht erschlagen von der Masse an Subforen, ich hoffe ich poste hier im richtigen Bereich. Ich brauche Hilfe bei einem Info-Projekt. Ich habe zahlreiche Änderungen am Code vorgenommen, es funktionierte sogar kurzzeitig, doch dann bei nebensächlichen Bugfixes wieder nicht, etc. Ich bin vollkommen aufgeschmissen, bin das Programm zig mal durchgegangen und am Ende mit meinem spärlichen Delphi-Wissen.

Die Aufgabe ist einfach: in einem Topf sind schwarze und weiße Kugeln, man greift zufällig zwei raus. Sind die Kugeln gleichfarbig, wird eine Schwarze Kugel zurückgelegt. Sind sie unterschiedlich, legt man eine Weiße zurück. (drei Fälle also, 2 Schwarze rausnehmen, 2 Weiße oder unterschiedlichfarbige Kugeln rausnehmen)
Dieser Prozess soll simuliert werden. Es sollen die Farbe der letzten Kugel und die Anzahl der Züge ausgegeben werden.
Zur Kontrolle:
die Anzahl der Züge ist immer die Gesamtanzahl der Kugeln - 1
Bsp:
5 Schwarze, 4 Weiße Kugeln
Benötigt 9-1=8 Züge

Die letzte Kugel basiert immer auf die Anzahl der Weißen Kugeln:
ist Weiß gerade, ist die letzte Kugel Schwarz
ist Weiß ungerade, ist die letzte Kugel Weiß

Natürlich könnte ich die gesuchten Ergebnisse kurzerhand mit if/else und einer Rechnung ausgeben, dennoch soll das Ganze simuliert werden mit einer Schleife bis nur noch eine Kugel verbleibt.

Hier mein Layout, Ästhetik mal außen vorgelassen:

http://img692.imageshack.us/img692/632/layoutit.jpg

Zwei Edit-Felder, Button, und Label für die Ausgabe

Hier mein Code:

Delphi-Quellcode:
procedure TForm1.KugelnZiehen(Sender: TObject);
var s,w,fall,zug:integer;
begin

w:=StrToInt(Weiss.text);
s:=StrToInt(Schwarz.text);

repeat
 begin
  randomize;
  fall:=(Random(2)+1); {Welcher Fall tritt ein?}
  Case fall of
   1: begin {Zwei Schwarze Kugeln rausgenommen, eine Schwarze wieder rein}
       if s>=2 then
        begin
        s:=s-1;
        zug:=zug+1;
        end
        else
      end;
   2: begin {Zwei Weiße Kugeln rausgenommen, eine Schwarze wieder rein}
       if w>=2 then
        begin
        w:=w-2;
        s:=s+1;
        zug:=zug+1;
        end
        else
      end;
   3: begin {Zwei unterschiedliche Kugeln rausgenommen, eine Schwarze wieder rein}
       if (s>0) and (w>0) then
        begin
        s:=s-1;
        zug:=zug+1;
        end
        else
      end;
 end;
end;
until s+w=1;

Textausgabe.Caption:='Züge: '+(inttostr(zug))+' Schwarze Kugeln: '+(inttostr(zug))+' Weiße Kugeln: '+(inttostr(zug))+' ';


end;
Delphi spuckt mehrstellige Nonenswerte aus oder bleibt je nach Zahlenkombination hängen (keine Fehlermeldung, nichts). Er beschwert sich "nur", dass die Variable Zug nicht initialisiert wurde.

Ich bitte um dringende Hilfe, es ist so simpel und ich hasse mich dafür, nicht selbst auf meine alte Lösung zu kommen. Vielen Dank.
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 20:38
Hallo,

zuerst einmal solltest du die Variable "Zug" initialisieren.

Delphi-Quellcode:
procedure TForm1.KugelnZiehen(Sender: TObject);
 var s,w,fall,zug:integer;
begin
  //init
  Zug := 0;
 
  w:=StrToInt(Weiss.text);
  s:=StrToInt(Schwarz.text);
Zum Anderen sollst/musst randomize in OnCreate der Form legen. Damit es nur einmal aufgerufen wird.

Wenn eine IF-Anweisung kein else hat, dann brauchst es auch nicht schreiben.
Also anstatt:

Delphi-Quellcode:
        begin
         w:=w-2;
         s:=s+1;
         zug:=zug+1;
         end
         else
besser:

Delphi-Quellcode:
        begin
         w:=w-2;
         s:=s+1;
         zug:=zug+1;
         end;
Des weiteren, bist du dir sicher, dass deine Ausstiegs-Logik stimmt?
until s+w=1; Kann das eintreten?

Ich habe es mal getestet, bei weiss = 3 und schwarz = 5 wird w und s jeweils minimal 1
und 1 + 1 = 2

[Edit]
Ist nur Schönheit: Aber den begin/end-Block im repeat-Teil kannst dir sparen. Bei repeat braucht man keinen begin/end-Block
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
einbeliebigername

Registriert seit: 24. Aug 2004
140 Beiträge
 
Delphi XE8 Professional
 
#3

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 20:42
Hallo yga,

abgesehen von den Tipps von Helmi, hast du glaube ich das Ziehen der Kugeln falsch umgesetzt. Kleine Denkaufgabe:
Du hast 5 Weiße und 5 Schwarze Kugeln im Topf. Und bei der Zeile
  fall:=(Random(2)+1); {Welcher Fall tritt ein?}
kommt die ersten dreimal eine 2 raus. Kann das funktionieren? Kann man wirklich 6 Weise Kugel ziehen ob wohl nur 5 im Topf sind.
Ich würde das Ziehen einer Kugel so machen:
Delphi-Quellcode:
 if Random(s+w)> s then
   // Eine Weiße gezogen
 else
   // Eine Schwarz gezogen
Und dann   randomize; ruft man nur einmal auf. Zum testen und debuggen ersetzt man diesen durch eine Zuweisung einer Konstanten Zahl zu RandSeed . Also für das Debuggen so:
Delphi-Quellcode:
procedure TForm1.KugelnZiehen(Sender: TObject);
...
begin
  RandSeed:= 42;
  // Jetzt Algo mit Zufallszahlengenerator
end;
Dadurch bekommt man beim Durchdebuggen immer wieder reproduzierbare Zufallszahlen.

einbeliebigername.
  Mit Zitat antworten Zitat
yga

Registriert seit: 25. Jan 2012
4 Beiträge
 
#4

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 21:12
Aah, danke. Vielen Dank für die schnelle Hilfe.
Sorry, Random(x) wurde mir anders erklärt, dass er dort eine zufällige Zahl aus der Menge 0 bis x raussucht. Deswegen auch diese umständliche Beschreibung. Ist gemerkt.
until s+w=1; war so gemeint, dass wenn die Anzahl beider Kugeln im Topf 1 ist, die Schleife enden soll. Muss ich mir nochmal genauer anschauen.

Mir war beim Code noch ein Fehler unterlaufen mit der Ausgabe, bei den inttostr(zug) im Ausgabetext, da sollte natürlich noch inttostr(s bzw. w) stehen. Typischer Copy-Paste-Fehler meinerseits.

Danke, ihr beiden, das hat mich einen großen Schritt nach vorn gebracht.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 21:15
Random funktioniert genau so, wie man es dir erklärt hat, jedoch solltest du auf die Problematik hingewiesen werden, dass du mit deiner Logik auch dann weiße Kugeln aus dem Topf ziehst, wenn dort eigentlich keine mehr drin sind.

Somit hast du in deiner Logik den Copperfield-Faktor

EDIT: Random( x ) liefert Werte von 0 bis x-1
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
yga

Registriert seit: 25. Jan 2012
4 Beiträge
 
#6

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 21:39
Random funktioniert genau so, wie man es dir erklärt hat, jedoch solltest du auf die Problematik hingewiesen werden, dass du mit deiner Logik auch dann weiße Kugeln aus dem Topf ziehst, wenn dort eigentlich keine mehr drin sind.

Somit hast du in deiner Logik den Copperfield-Faktor
Okay, das verwirrt mich. Ich hab doch bei jedem der drei Fälle mit if abgesichert, dass sich auch mehr als 2 Kugeln der Farbe dort befinden, ansonsten springt er doch sofort zum Ende und "lost" den nächsten Fall aus. Mein einziges Problem besteht nun noch darin, dass wenn Weiß eine ungerade Anzahl hat, sich das Programm aufhängt. Ich weiß bloß nicht, wie das damit zusammenhängt...
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#7

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 21:44
Hallo,

vielleicht solltest noch die Eingabe etwas abfangen.

Falls es TryStrToInt in deinem Delphi schon gibt, könntest folgendes machen:

Delphi-Quellcode:
procedure TForm1.KugelnZiehen(Sender: TObject);
 var s,w,fall,zug:integer;
begin
  If (not TryStrToInt(Weiss.Text, w)) or (not TryStrToInt(Schwarz.Text, s)) then
    begin
      ShowMessage('Eingaben prüfen!'); //oder was auch immer
      exit;
    end;
 
repeat
Somit gibts keine unschöne Exception wenn man keine Zahlen in die Edits eingibt.
Oder man verwendet MaskEdit´s statt Edits.

[Edit]
Klammerfehler beseitigt
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<

Geändert von Helmi (25. Jan 2012 um 21:48 Uhr)
  Mit Zitat antworten Zitat
yga

Registriert seit: 25. Jan 2012
4 Beiträge
 
#8

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 22:05
Danke an alle, der Thread kann geschlossen werden, es klappt jetzt alles.
@Helmi: Das ist TryStrToInt ist praktisch, das werd ich auch in Zukunft benutzen, thx.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 25. Jan 2012, 22:07
ok, ich hatte die Schleife übersehen

Ich habe deinen Ursprungs-Quelltext mal etwas modifiziert und entsprechende Kommentare hinzugefügt
Delphi-Quellcode:
procedure TForm1.KugelnZiehen(Sender: TObject);
var s,w,fall,zug:integer;
begin

w:=StrToIntDef( Weiss.text, 0 ); // Wenn keine Zahl im Edit-Feld,
s:=StrToIntDef( Schwarz.text, 0 ); // dann wird der Default-Wert genommen, hier 0
zug := 0; // Initialisierung vergessen, ansonsten hat Zug einen Zufallswert

// Wenn die Summe aus s und w < 1 ist, dann hast du eine Endlosschleife, darum

if ( s + w ) < 1 then
  begin
    ShowMessage( 'Ungültige Eingabe für Schwarz und Weiß!' );
    Exit; // diese procedure wird nun verlassen
  end;

repeat
 begin
  // randomize; // Sollte nur einmal in Anwendung aufrufen werden
  // fall:=(Random(2)+1); {Welcher Fall tritt ein?}
  // Random( 2 ) + 1 ergibt Werte von 1..2 Fall 3 würde also niemals eintreten
  fall := Random( 3 ) + 1; // jetzt gibt es Werte von 1..3 :o)
  Case fall of
   1: begin {Zwei Schwarze Kugeln rausgenommen, eine Schwarze wieder rein}
       if s>=2 then
        begin
        s:=s-1;
        zug:=zug+1;
        end
        // else
      end;
   2: begin {Zwei Weiße Kugeln rausgenommen, eine Schwarze wieder rein}
       if w>=2 then
        begin
        w:=w-2;
        s:=s+1;
        zug:=zug+1;
        end
        // else
      end;
   3: begin {Zwei unterschiedliche Kugeln rausgenommen, eine Schwarze wieder rein}
       if (s>0) and (w>0) then
        begin
        s := s-1;
        zug:=zug+1;
        end
        // else
      end;
 end;
end;
until s+w=1;

  // Textausgabe.Caption:='Züge: '+(inttostr(zug))+' Schwarze Kugeln: '+(inttostr(zug))+' Weiße Kugeln: '+(inttostr(zug))+' ';
  // ist etwas umständlich und du hast immer nur die Variable Zug angegeben, besser so
  // %d ist ein Platzhalter für eine Integer-Zahl
  Textausgabe.Caption := Format( 'Züge: %d Schwarze Kugeln: %d Weiße Kugeln %d', [zug, s, w] );

end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (25. Jan 2012 um 22:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#10

AW: Einfache "Kugeln Ziehen"-Aufgabe mit Schleife

  Alt 26. Jan 2012, 05:24
Ich hab da grad noch einen grossen Fehler entdeckt:
fall := Random( 3 ) + 1; // jetzt gibt es Werte von 1..3
Das ist aber aus Sicht der Wahrscheinlichkeit nicht korrekt, denn es gibt 4 Fälle:
1: Schwarz + Schwarz
2: Weiss + Weiss
3: Schwarz + Weiss
4: Weiss + Schwarz
Die Wahrscheinlichkeit zweier Kugeln mit unterschiedlicher Farbe beträgt 50% aller Fälle.
So wie es bisher programmiert wurde wäre die Wahrscheinlichkeit nur 1/3.

Achja, der Kommentar bei dem Fall #2 ist wohl durch Copy & Paste entstanden;
   2: begin {Zwei Weiße Kugeln rausgenommen, eine Schwarze wieder rein}
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:33 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