Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Lazarus (IDE) (https://www.delphipraxis.net/81-lazarus-ide/)
-   -   Grafische Lösung der Türme von Hanoi (Rekursion) (https://www.delphipraxis.net/188246-grafische-loesung-der-tuerme-von-hanoi-rekursion.html)

Mavarik 16. Feb 2016 18:43

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Zitat:

Zitat von Hanoi1 (Beitrag 1330571)
Eine Kleinigkeit noch:
Durch

Delphi-Quellcode:
While Form1.Timer1.Enabled = true do
begin
  Application.Processmessages;
  Sleep(10);
end;
friere ich das Programm mit Ausnahme des Timers ein. Ohne das funktioniert der Algorithmus ja auch nicht.

Wenn ich jetzt aber beispielsweise 10 Scheiben generiere und die Lösung aktiviere, dauert das ja seine Zeit, bis das Programm "entfriert".

Nöö Nur bis der Timer auf false geht weil die Scheibenanimation beendet ist...
Dann geht es ganz normal weiter...

stahli 16. Feb 2016 19:23

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Ein grundsätzliches Problem ist, dass Du die GUI (Formular und Controls) mit der Businesslogik (Berechnung) verknüpfst.
Das ist anfänglich ganz normal, aber man sollte beide Ebenen etwas entkoppelt.

Ich gehe davon aus, dass Du an dem Projekt lernen möchtest.
Dann versuche mal folgenden Ansatz:

Erstelle eine neue Unit Hanoi.pas.
Dort legst Du Variablen für die Positionen Deiner Steine ab (z.B. in einem Array) und dazu Funktionen, die die Bewegungen berechnen.
In der Unit passiert nichts grafisches sondern nur reine (virtuelle) Berechnungen.
Dann brauchst Du eine Art Schrittzähler, damit Du weißt, wie viele Schritte schon berechnet sind.

Und jetzt das Wichtigeste:
Du brauchst eine Prozedur Init und eine NextStep.

Init setzt den Schrittzähler auf 0.
NextStep erhöht den Schrittzähler und berechnet den nächsten Schritt.

Das alles ist Deine Businesslogik.


Jetzt zur GUI (also dem Formular).

Du brauchst natürlich Deine Shapes wie gehabt.
Der Button ruft Init aus der anderen Unit auf und startet den Timer.

Der Timer veranlasst die Berechnung des nächsten Schrittes und korrigiert die Positionen der Shapes.
Wenn NextStep als Funktion ausgelegt wird kann diese sogar gleich mitteilen, dass keine weiteren Berechnungen notwendig sind (also das Ende erreicht ist).

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := NextStep;
  ÜbertrageBerechnetePositionenInDiePositionenDerShapes;
end;
So muss das Formular sich nicht weiter drum kümmern, wie die Berechnung korrekt erfolgt und die Berechnung muss nicht die Shapes herum schieben.
Die Zuständigkeiten sind so übersichtlicher.
Natürlich muss man dann beide Ebenen aufeinander abstimmen.

Jetzt wird Dein Formular nicht einfrieren - bzw. immer nur ganz kurz, wenn Dein Timer die Änderungen berechnen lässt und zeichnet.
Während der anderen Zeit könntest Du sogar etwas in einem Edit schreiben - also quasi ohne Einschränkung.


Das ist natürlich auch alles keine endgültige Lösung, aber für den Anfang vielleicht mal interessant um eine Vorstellung von der Trennung von GUI und BL zu erhalten (wenngleich das noch keine richtige Trennung ist).

Um das noch ein wenig weiter zu treiben könntest Du die Positionsliste zur Berechnung übergeben und die Werte so zwischen den Units austauschen.
So muss Dein Formular nicht wissen, wie die Berechnungsunit die Positionen verwaltet.

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := NextStep(Positionsliste);
  ÜbertrageFolgendePositionenInDiePositionenDerShapes(Positionsliste);
end;

Wenn Du Lust hast kannst Du Dich ja mal schrittweise dort heran tasten.
Als Testprojekt würde ich mal ein Programm schreiben, dass einen Ball (Panel) schrittweise bewegt, was durch einen Button gestartet und gestoppt wird.
Das klingt trivial und ist es auch. Aber so versteht man gut, welche Aufgaben in welche Unit gehören und wie beide Ebenen miteinander verbunden werden.

Wichtig dabei: Die Berechnungsunit soll NIE auf das Formular zugreifen sondern NUR das Formular auf die Berechnungsunit.


So, wenn der Kopf nicht mehr raucht, dann frisch ans Werk. :-)

Mavarik 17. Feb 2016 09:48

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Zitat:

Zitat von stahli (Beitrag 1330578)
Dann versuche mal folgenden Ansatz:

Erstelle eine neue Unit Hanoi.pas.
Dort legst Du Variablen für die Positionen Deiner Steine ab (z.B. in einem Array) und dazu Funktionen, die die Bewegungen berechnen.
In der Unit passiert nichts grafisches sondern nur reine (virtuelle) Berechnungen.
Dann brauchst Du eine Art Schrittzähler, damit Du weißt, wie viele Schritte schon berechnet sind.

Und jetzt das Wichtigeste:
Du brauchst eine Prozedur Init und eine NextStep.

Init setzt den Schrittzähler auf 0.
NextStep erhöht den Schrittzähler und berechnet den nächsten Schritt.

Das alles ist Deine Businesslogik.

Oder Du schaust in meinen Source Code und machst es so wie ich... Nicht die Darstellung in die Rekursion, sondern alle "von -> nach" speichern und wenn alles fertig ist nur noch mit dem Timer darstellen...

Wobei ich im Prinzip ein Init NextStep wie oben beschrieben programmiert habe...


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:49 Uhr.
Seite 3 von 3     123   

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