Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Rekursion entfernen (Türme von Hanoi)


xsus - So 17.06.12 16:06
Titel: Rekursion entfernen (Türme von Hanoi)
Hallo,
ich habe ein Programm geschrieben, dass mir die Türme von Hanoi optisch Anzeigt, in Form von Listboxen (Eigentlich waren richtige Teller, Scheiben geplant, aber das wird mir zu komplex mit Canvas etc.). Der Prozess findet aber so schnell statt, dass der Zwischenspeicher, also der 2. Turm nicht ersichtlich wird..alle Meine versuche die Rekursion herrauszunehmen, um mit einem weiteren Button (3) einzeln weiter zu takten sind Fehlgeschlagen. Es tat sich garnichts mehr.

Hier mein Quelltext mit Rekursion:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
unit TürmevonHanoi;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    ListBox1: TListBox;
    ListBox2: TListBox;
    ListBox3: TListBox;
    ListBox4: TListBox;
    edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);  // Erstellt den ersten Turm
var i: Integer;
begin
Listbox1.Clear;
Listbox2.Clear;
Listbox3.Clear;
Listbox4.Clear;
for i := 1 to strtoint(edit1.text) do
begin
   Listbox1.Items.Add(inttostr(i));
   end;
end;



procedure TForm1.Button2Click(Sender: TObject);
procedure verschieben(a,b:Integer);
// von LB a nach b
var
temp :String;
begin
    // lesen
    case a of
    1begin temp := Listbox1.Items[0]; Listbox1.Items.Delete(0); end;
    2begin temp := Listbox2.Items[0]; Listbox2.Items.Delete(0); end;
    3begin temp := Listbox3.Items[0]; Listbox3.Items.Delete(0); end;
    end;
    // schreiben
    case b of
    1begin Listbox1.Items.Insert(0,temp); end;
    2begin Listbox2.Items.Insert(0,temp); end;
    3begin Listbox3.Items.Insert(0,temp); end;
    end;
// Ausgabe der Aktion in LB4
ListBox4.Items.Add('Scheibe ' + temp + ' von ' + inttostr(a) + ' --> ' + inttostr(b));
end;


function laenge(a:Integer):Integer;
// Abfrage der Laenge
begin
     case a of
     1: Result := Listbox1.Items.Count;
     2: Result := Listbox2.Items.Count;
     3: Result := Listbox3.Items.Count;
     end;
end;


procedure hanoi(anzahl, a, b, c:Integer); // Anzahl, Ausgangspos. / Zielpos. / Hilfsstab
begin
if(anzahl = 1then
begin
    verschieben(a, b);
    end
else
begin
     hanoi(anzahl - 1, a, c, b);
     verschieben(a, b);
     hanoi(anzahl - 1, c, b, a);
     end;
end;
begin
if(laenge(1) > 0then
             hanoi(laenge(1), 132)
else
    ShowMessage('Fehler: Auf dem linken Stab liegen keine Scheiben!!');
Label1.Caption := inttostr(Listbox4.Items.Count) + ' Züge';
end;
end.


Wäre nett, wenn mir jmd. weiterhelfen könnte. Ich habe bis jetzt versucht, in der Prozedur Hanoi, das Verschieben bzw auch Hanoi selbst herraus zu nehmen...

Mit freundlichen Grüßen

Moderiert von user profile iconGausi: Quote- durch Delphi-Tags ersetzt


TomyN - So 17.06.12 20:31

Hi,

der Trick ist aber doch die Rekursion, oder?

Bau halt in die Hannoi-routine ein sleep(500) ein,

oder einen Trigger


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
warten: boolean;

...hanoi...
warten:= true;
while warten do begin
 sleep(20);
 application.processmessages; //Verbessert die Reaktionszeit
end;


Bei der Weitertaste setzt du dann im onClick einfach warten auf false.

Tomy


xsus - Di 19.06.12 14:32

Hat funktioniert, musste es aber zusätzlich noch in die Prozedur verschieben einbauen. Danke


Boldar - Di 19.06.12 20:22

Also das ist ja totaler Unsinn...
Muss also ein Programm wie die Türme von Hanoi jetzt schon 100% CPU-Last beanspruchen, nur weil der Programmierer unfähig ist, z.B. vorher eine Liste mit den Schritten zu erstellen und die dann abzuarbeiten oder gleich den Algorithmus iterativ umzusetzen? [http://www.google.de/search?hl=de&q=t%C3%BCrme+von+hanoi+iterativ]