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
Seite 1 von 3  1 23      
Hanoi1

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

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

  Alt 12. Feb 2016, 21:09
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...
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

Geändert von Hanoi1 (12. Feb 2016 um 23:16 Uhr)
  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
 
#2

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

  Alt 12. Feb 2016, 21:20
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;
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
Hanoi1

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

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

  Alt 12. Feb 2016, 22:45
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.
  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
 
#4

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

  Alt 12. Feb 2016, 23:05
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.
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
Hanoi1

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

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

  Alt 12. Feb 2016, 23:17
Oh, das habe ich falsch verstanden...
Ich bin erst seit heute hier.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

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

  Alt 12. Feb 2016, 23:37
Herzlich willkommen erst mal.

Versuch mal ein 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.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Hanoi1

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

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

  Alt 12. Feb 2016, 23:53
Danke für den Tipp! Das werde ich bald umsetzen.
  Mit Zitat antworten Zitat
Hanoi1

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

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

  Alt 13. Feb 2016, 13: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.144 Beiträge
 
Delphi 10.3 Rio
 
#9

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

  Alt 13. Feb 2016, 14: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 14:54 Uhr)
  Mit Zitat antworten Zitat
Hanoi1

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

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

  Alt 13. Feb 2016, 20: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
Antwort Antwort
Seite 1 von 3  1 23      

 

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 20:37 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