Einzelnen Beitrag anzeigen

Hanoi1

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

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