AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Lazarus (IDE) Grafische Lösung der Türme von Hanoi (Rekursion)
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von Hanoi1 · begonnen am 12. Feb 2016 · letzter Beitrag vom 17. Feb 2016
Antwort Antwort
Hanoi1

Registriert seit: 12. Feb 2016
11 Beiträge
 
#1

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

  Alt 13. Feb 2016, 12:27
Gibt es noch weitere Vorschläge bezüglich sleep oder Timer?
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#2

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

  Alt 13. Feb 2016, 13:51
Bitte beachten!

Code:
[DELPHI]
procedure foo;
begin
end;
[/DELPHI] // <<---  "/" nicht vergessen

Vielleicht eher die Verwendung von

Delphi-Quellcode:
CASE XY of
  1 : A := B;
end; // of case
oder erstelle die Shapes in einem Array dann brauchst Du die Case auch nicht...

und

 Form1.Label2.caption:= IntToStr(StrToInt(Form1.Label2.Caption)-1);
Mach aus der Procedure eine Procedure der Form...

Dann keine Datenhaltung von integer in einem String - Dafür gibt es Variablen

Delphi-Quellcode:
var
  Whatever : Integer;

...
Label1.Caption := inttostr(Pred(Whatever));
Delphi-Quellcode:
Repeat
  // Whatever
Until;

Ohne begin & end
Wenn Du das alles berücksichtigt hast, hänge und das Projekt an den Thread dran, dann können wir die besser helfen...

Geändert von Mavarik (13. Feb 2016 um 13:54 Uhr)
  Mit Zitat antworten Zitat
Hanoi1

Registriert seit: 12. Feb 2016
11 Beiträge
 
#3

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

  Alt 13. Feb 2016, 19:19
Über die Array-Shapes habe ich auch nachgedacht, diese aber wieder verworfen, weil ich diesen Algorithmus in möglichst kurzer Zeit erklären muss - und mein Publikum hat keine Ahnung von Arrays (kein Witz). Darum würde nur zusätzlicher Erklärungsbedarf entstehen...

Die Sache mit der Variablen ist zwar auch eine Möglichkeit, aber direkt vereinfachen würde es mein Problem ja nicht.

Die Anmerkung zu meiner Schleife ist allerdings berechtigt. Danke!
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#4

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

  Alt 14. Feb 2016, 11:42
Über die Array-Shapes habe ich auch nachgedacht, diese aber wieder verworfen, weil ich diesen Algorithmus in möglichst kurzer Zeit erklären muss - und mein Publikum hat keine Ahnung von Arrays (kein Witz). Darum würde nur zusätzlicher Erklärungsbedarf entstehen...
Das Satz das ist eine Liste der Shapes ist zu lang?

Die Sache mit der Variablen ist zwar auch eine Möglichkeit, aber direkt vereinfachen würde es mein Problem ja nicht.
Macht aber den Code "richtig"

Die Anmerkung zu meiner Schleife ist allerdings berechtigt. Danke!
Nur das?

Mit den Sourceocode würdest Du bei mir durchfallen...
  Mit Zitat antworten Zitat
Hanoi1

Registriert seit: 12. Feb 2016
11 Beiträge
 
#5

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

  Alt 14. Feb 2016, 15:13
Ich habe die Vorschläge jetzt eingearbeitet und verwende statt des sleeps jetzt einen Timer.

Wie zu erwarten war, wird die Rekursion im Hauptprogramm jetzt normal ausgeführt, während die Bewegung durch den Timer "hinterherhängt".
Wie schaffe ich es jetzt, dass das Hauptprogramm sozusagen auf den Timer wartet?

Außerdem gibt es noch ein kleineres Definitions problem in der Timersequenz. Wie kann ich das beheben?

Hier mein neuer Code:
Delphi-Quellcode:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    PaintBox1: TPaintBox;
    Links: TShape;
    Rechts: TShape;
    Mitte: TShape;
    ShapeMOVE: TShape;
    TA: TShape;
    TB: TShape;
    TC: TShape;
    ShapeMF: TShape;
    ShapeMT: TShape;
    ShapeT2: TShape;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
    z: integer;
    q: boolean;
    cL,cM,cR: integer;
    Scheibe: array[1..10] of TShape;
    Tr: integer;

implementation

{$R *.lfm}

{ TForm1 }

procedure draw(a,b,c,d: integer; n: string);
var Shape : TShape;
begin
 Shape := TShape.Create(Form1);
 With Shape do
  begin
   Parent := Form1;
   Left := a;
   Top := b;
   Width:= c;
   Height:=d;
   Name := n;
  end;
end;

procedure Ground(e,f: integer);
begin
 draw(100,550,e,f,'Links');
 draw(400,550,e,f,'Mitte');
 draw(700,550,e,f,'Rechts');
end;

procedure towerA(t: integer);
var i,z: integer;
begin
 i:=0;
 z:=t+1;
 repeat
  i:=i+1;
  z:=z-1;
  Scheibe[t] := TShape.Create(Form1);
 With Scheibe[t] do
  begin
   Parent := Form1;
   Left := 100+((i-1)*10);
   Top := 550-(i*50);
   Width:= 200-((i-1)*20);
   Height:=50;
  end;
 until i=t;
end;

procedure movetop(r: integer;ShapeMF,ShapeMT: TShape);
begin
 Tr:=r;
 Form1.ShapeT2:=ShapeMT;
 if ShapeMT.left=Form1.Mitte.left then
 begin
    cM:=cM+1;
    z:=550-(cM*50);
 end;
 if ShapeMT.left=Form1.Links.left then
 begin
    cL:=cL+1;
    z:=550-(cL*50);
 end;
 if ShapeMT.left=Form1.Rechts.left then
 begin
    cR:=cR+1;
    z:=550-(cR*50);
 end;
 if ShapeMF.left=Form1.Mitte.left then
 begin
    cM:=cM-1;
 end;
 if ShapeMF.left=Form1.Links.left then
 begin
    cL:=cL-1;
 end;
 if ShapeMF.left=Form1.Rechts.left then
 begin
    cR:=cR-1;
 end;
 Form1.Timer1.Enabled:=true;
end;

procedure rec(r: integer;TA,TB,TC: TShape);
begin
 if r>0 then
 begin
   rec(r-1,TA,TC,TB);
   movetop(r,TA,TC);
   rec(r-1,TB,TA,TC);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var k: Integer;
begin
 k:=StrToInt(Edit1.Text);
 Label1.caption:= 'Scheiben';
 cL:= k;
 cM:= 0;
 cR:= 0;
 Ground(200,50);
 towerA(k);
end;

procedure TForm1.Button2Click(Sender: TObject);
var k: Integer;
begin
 k:=StrToInt(Edit1.Text);
 q:=true;
 rec(k,Links,Mitte,Rechts);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 if q=true then
 begin
    if Scheibe[Tr].Top > 50 then
    Scheibe[Tr].Top:=Scheibe[Tr].Top-10;
 end;
 if Scheibe[Tr].Top=50 then
 begin
   if Scheibe[Tr].Left > ShapeT2.Left+((200-Scheibe[Tr].width)DIV 2) then
      Scheibe[Tr].Left:=Scheibe[Tr].Left-10;
   if Scheibe[Tr].Left < ShapeT2.Left+((200-Scheibe[Tr].width)DIV 2) then
      Scheibe[Tr].Left:=Scheibe[Tr].Left+10;
 end;
 if Scheibe[Tr].Left = ShapeT2.Left+((200-Scheibe[Tr].width)DIV 2) then
 begin
   q:=false;
   if Scheibe[Tr].Top < z then
    Scheibe[Tr].Top:=Scheibe[Tr].Top +10;
   if Scheibe[Tr].Top = z then
    q:=true;
    Timer1.Enabled:=false;
 end;
end;

end.

Geändert von Hanoi1 (14. Feb 2016 um 15:16 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#6

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

  Alt 14. Feb 2016, 15:24
Mit Deinem Code kann ich mich jetzt nicht weiter befassen, aber schreib doch erst mal ein kleines Testprogramm, in dem Du ein Panel verschieben lässt.

Delphi-Quellcode:
for I := 0 to 1000 do
begin
  Panel.Left := I;
  Sleep(500);
end;
Die Schleife wird das Panel zwar verschieben, aber das Formular kommt nicht dazu, jeden Zwischenschritt anzuzeigen.
Du brauchst daher nach der Positionszuweisung ein Application.Processmessages.

Mein Tipp, versuche erst mal ein kleines Minimalprojekt um zu prüfen, wo das Problem genau liegt.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#7

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

  Alt 14. Feb 2016, 16:31
Na das sieht doch schon ganz anders aus...

Leider hast Du immer noch nicht die proceduren in der Form definiert, deswegen muss du immer noch

Form1.Timer1.Enabled:=true;
schreiben.

Auch wenn ich das so nie programmieren würde, könntest Du an dieser Stelle schreiben:

Delphi-Quellcode:
Form1.Timer1.Enabled:=true;

While Form1.Timer1.Enabled = true do
begin
  Application.Processmessages;
  Sleep(10);
end;
Das Erzeugen der Scheiben ist falsch [t] ??? Vielleicht [i]?

Die Animation funktioniert auch nicht... Weil Du den Timer zu früh abschaltest...

Geändert von Mavarik (14. Feb 2016 um 20:25 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 

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 06:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz