Autor Beitrag
xsus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51

Win 2000, Win XP, Win 7; Ubuntu
Delphi 7, Delphi XE2, C
BeitragVerfasst: So 17.06.12 16:06 
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:
ausblenden volle Höhe 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32
Erhaltene Danke: 2

Win10
D5 Std., Turbo-Delphi (w32), Delphi 2010
BeitragVerfasst: 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

ausblenden 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

Für diesen Beitrag haben gedankt: xsus
xsus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51

Win 2000, Win XP, Win 7; Ubuntu
Delphi 7, Delphi XE2, C
BeitragVerfasst: Di 19.06.12 14:32 
Hat funktioniert, musste es aber zusätzlich noch in die Prozedur verschieben einbauen. Danke


Zuletzt bearbeitet von xsus am Di 13.05.14 22:19, insgesamt 1-mal bearbeitet
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: 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?