Delphi-PRAXiS
Seite 1 von 3  1 23      

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)

Hanoi1 12. Feb 2016 20:09


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

Ich arbeite gerade an den berühmten Türmen und versuche, eine grafische Umsetzung des rekursiven Algorithmus mittels Shapes zu programmieren.
Das ist mir bisher in soweit gelungen, dass das Problem gelöst wurde, aber keine Bewegung sichtbar war. :?

Das wollte ich durch die sleep(...)-Funktion verbessern, sodass wenigstens Pausen zwischen den Sprüngen sind - jedoch vergeblich... :cry:
Nach dem Klick auf Button2 ist nun eine lange Pause und danach "hüpft" der Turm in die Lösungsposition.

Hier mein Quelltext (er ist teilweise wahrscheinlich ziemlich umständlich, aber eins nach dem anderen!):


Code:
[DELPHI]
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;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    PaintBox1: TPaintBox;
    Links: Tshape;
    Rechts: Tshape;
    Mitte: Tshape;
    Shape1: TShape;
    Shape2: TShape;
    Shape3: TShape;
    Shape4: TShape;
    Shape5: TShape;
    Shape6: TShape;
    Shape7: TShape;
    Shape8: TShape;
    Shape9: TShape;
    Shape10: TShape;
    ShapeMOVE: TShape;
    TA: TShape;
    TB: TShape;
    TC: TShape;
    ShapeMF: TShape;
    ShapeMT: TShape;
    Timer1: TTimer;
    Timer2: TTimer;
    Timer3: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

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 counterLplus;
begin
  Form1.Label2.caption:= IntToStr(StrToInt(Form1.Label2.Caption)+1);
end;

procedure counterMplus;
begin
  Form1.Label3.caption:= IntToStr(StrToInt(Form1.Label3.Caption)+1);
end;

procedure counterRplus;
begin
  Form1.Label4.caption:= IntToStr(StrToInt(Form1.Label4.Caption)+1);
end;

procedure counterLminus;
begin
  Form1.Label2.caption:= IntToStr(StrToInt(Form1.Label2.Caption)-1);
end;

procedure counterMminus;
begin
  Form1.Label3.caption:= IntToStr(StrToInt(Form1.Label3.Caption)-1);
end;

procedure counterRminus;
begin
  Form1.Label4.caption:= IntToStr(StrToInt(Form1.Label4.Caption)-1);
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,x,y,w,h: integer; g: string;
begin
 i:=0;
 z:=t+1;
 repeat
 begin
  i:=i+1;
  z:=z-1;
  x:=100+((i-1)*10);
  y:=550-(i*50);
  w:=200-((i-1)*20);
  h:=50;
  g:='Shape'+IntToStr(z);
  draw(x,y,w,h,g);
 end;
 until i=t;
end;

procedure define(l: integer);
begin
 if l=1 then
 begin
 Form1.ShapeMOVE:=Form1.Shape1;
 end;
 if l=2 then
 begin
 Form1.ShapeMOVE:=Form1.Shape2;
 end;
 if l=3 then
 begin
 Form1.ShapeMOVE:=Form1.Shape3;
 end;
 if l=4 then
 begin
 Form1.ShapeMOVE:=Form1.Shape4;
 end;
 if l=5 then
 begin
 Form1.ShapeMOVE:=Form1.Shape5;
 end;
 if l=6 then
 begin
 Form1.ShapeMOVE:=Form1.Shape6;
 end;
 if l=7 then
 begin
 Form1.ShapeMOVE:=Form1.Shape7;
 end;
 if l=8 then
 begin
 Form1.ShapeMOVE:=Form1.Shape8;
 end;
 if l=9 then
 begin
 Form1.ShapeMOVE:=Form1.Shape9;
 end;
 if l=10 then
 begin
 Form1.ShapeMOVE:=Form1.Shape10;
 end;
end;

procedure undefine(l: integer);
begin
 if l=1 then
 begin
 Form1.Shape1:=Form1.ShapeMOVE;
 end;
 if l=2 then
 begin
 Form1.Shape2:=Form1.ShapeMOVE;
 end;
 if l=3 then
 begin
 Form1.Shape3:=Form1.ShapeMOVE;
 end;
 if l=4 then
 begin
 Form1.Shape4:=Form1.ShapeMOVE;
 end;
 if l=5 then
 begin
 Form1.Shape5:=Form1.ShapeMOVE;
 end;
 if l=6 then
 begin
 Form1.Shape6:=Form1.ShapeMOVE;
 end;
 if l=7 then
 begin
 Form1.Shape7:=Form1.ShapeMOVE;
 end;
 if l=8 then
 begin
 Form1.Shape8:=Form1.ShapeMOVE;
 end;
 if l=9 then
 begin
 Form1.Shape9:=Form1.ShapeMOVE;
 end;
 if l=10 then
 begin
 Form1.Shape10:=Form1.ShapeMOVE;
 end;
end;

procedure movetop(r: integer;ShapeMF,ShapeMT: TShape);
begin
 define(r);
 Form1.ShapeMOVE.left:=ShapeMT.left+((200-Form1.ShapeMOVE.width)DIV 2);
 if ShapeMT.left=Form1.Mitte.left then
 begin
    counterMplus;
    Form1.ShapeMove.top:=550-((StrToInt(Form1.Label3.caption))*50);
 end;
 if ShapeMT.left=Form1.Links.left then
 begin
    counterLplus;
    Form1.ShapeMove.top:=550-((StrToInt(Form1.Label2.caption))*50);
 end;
 if ShapeMT.left=Form1.Rechts.left then
 begin
    counterRplus;
    Form1.ShapeMove.top:=550-((StrToInt(Form1.Label4.caption))*50);
 end;
 if ShapeMF.left=Form1.Mitte.left then
 begin
    counterMminus;
 end;
 if ShapeMF.left=Form1.Links.left then
 begin
    counterLminus;
 end;
 if ShapeMF.left=Form1.Rechts.left then
 begin
    counterRminus;
 end;
 sleep(1000);
 undefine(r);
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';
 Label2.caption:= IntToStr(k);
 Label3.caption:= IntToStr(0);
 Label4.caption:= IntToStr(0);
 Ground(200,50);
 towerA(k);
end;

procedure TForm1.Button2Click(Sender: TObject);
var k: Integer;
begin
 k:=StrToInt(Edit1.Text);
 rec(k,Links,Mitte,Rechts);
end;
[DELPHI]
Ich dachte über eine Lösung mittels Timer nach. Macht das vielleicht mehr Sinn? Falls ja, wie bewirke ich, dass das Heuptprogramm, während der Timer läuft, stillsteht?

Vielen Dank im Voraus!

LG

Sir Rufo 12. Feb 2016 20:20

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Könntest du bitte deinen Beitrag bearbeiten und den Quelltext dann in die
Code:
[DELPHI]
procedure foo;
begin
end;
[/DELPHI]
einbetten?

Das wird dann zu
Delphi-Quellcode:
procedure foo;
begin
end;

Hanoi1 12. Feb 2016 21:45

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Entschuldigung, aber ich weiß nicht genau, wie man das macht.

Das ist mein ertes "größeres" Projekt und ich habe fast keine Erfahrung mit Delphi.:oops:

Sir Rufo 12. Feb 2016 22:05

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Hmm, bei deinem ersten Beitrag auf den Button Bearbeiten drücken
Vor und nach dem Quelltext ein paar Zeichen einfügen

Das geht ganz ohne Delphi - und wir können dann deinen Quelltext anschauen ohne Augenkrebs zu bekommen.

Hanoi1 12. Feb 2016 22:17

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Oh, das habe ich falsch verstanden...
Ich bin erst seit heute hier.

stahli 12. Feb 2016 22:37

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Herzlich willkommen erst mal.

Versuch mal ein
Delphi-Quellcode:
Application.ProcessMessages;
in Deiner Schleife. Dann erhält das Formular die Möglichkeit, sich neu zu zeichnen.

Generell ist die VCL allerdings für anspruchsvollere grafische Anwendungen nicht unbedingt geeignet.

Hanoi1 12. Feb 2016 22:53

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Danke für den Tipp! Das werde ich bald umsetzen.

Hanoi1 13. Feb 2016 12:27

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Gibt es noch weitere Vorschläge bezüglich sleep oder Timer?

Mavarik 13. Feb 2016 13:51

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

Zitat:

Zitat von Sir Rufo (Beitrag 1330221)
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

Delphi-Quellcode:
 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
Delphi-Quellcode:
begin
&
Delphi-Quellcode:
end

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

Hanoi1 13. Feb 2016 19:19

AW: Grafische Lösung der Türme von Hanoi (Rekursion)
 
Ü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!


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:11 Uhr.
Seite 1 von 3  1 23      

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