Einzelnen Beitrag anzeigen

Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.143 Beiträge
 
Delphi 10.3 Rio
 
#17

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

  Alt 15. Feb 2016, 12:37
Wie rufe ich den Code dafür ab?
Die wesentlichen Teilen:

Delphi-Quellcode:
unit Main;


interface

uses
...

const
  Größe = 250.0;
  MaxHeight = 240;
  Dauer = 1;
  Dicke = 25;

type
  TZug = record
    Von, Nach: integer;
    constructor Create( AVon, ANach: integer );
  end;

  TKindOfAnimation = ( Up, RightOrLeft, Down, Next );

  TForm128 = class( TForm )
..
  private
    { Private-Deklarationen }
    Scheiben : array of TRectangle;
    Pole : array [ 1 .. 3 ] of TPointF;
    Stange : array [ 1 .. 3 ] of TStack<integer>;
    Colors : array [ 0 .. 9 ] of TAlphaColor;
    Zugliste : TQueue<TZug>;
    ScheibenNr : integer;
    AktAnimation: TKindOfAnimation;
    AktZug : TZug;

    procedure Init( const AAnzahl: integer );
    procedure DeInit;
    procedure dohanoi( Anzahl, AFrom, ATo, ASave: integer );
    procedure ShowZüge;
    function GetZug( out AZug: TZug ): boolean;
    procedure ShowZug( AZug: TZug );
    procedure Animation( AKind: TKindOfAnimation );
    function GetColor( A, B: integer ): TAlphaColor;
  public
    { Public-Deklarationen }
  end;

implementation

{$R *.fmx}

procedure TForm128.dohanoi( Anzahl, AFrom, ATo, ASave: integer );
begin
  if Anzahl > 0
  then
    begin
      dohanoi( Anzahl - 1, AFrom, ASave, ATo );
      Zugliste.Enqueue( TZug.Create( AFrom, ATo ) );
      dohanoi( Anzahl - 1, ASave, ATo, AFrom );
    end
end;

procedure TForm128.FloatAnimation1Finish( Sender: TObject );
begin
  AktAnimation := Succ( AktAnimation );
  if AktAnimation = Next
  then
    begin
      Application.ProcessMessages;
      ShowZüge;
    end
  else
    Animation( AktAnimation );
end;

procedure TForm128.FormCreate( Sender: TObject );
begin
  Colors[ 0 ] := TAlphaColorRec.Black;
  Colors[ 1 ] := TAlphaColorRec.Darkviolet;
  Colors[ 2 ] := TAlphaColorRec.Blue;
  Colors[ 3 ] := TAlphaColorRec.Deepskyblue;
  Colors[ 4 ] := TAlphaColorRec.Mediumseagreen;
  Colors[ 5 ] := TAlphaColorRec.Greenyellow;
  Colors[ 6 ] := TAlphaColorRec.Yellow;
  Colors[ 7 ] := TAlphaColorRec.Orange;
  Colors[ 8 ] := TAlphaColorRec.Orangered;
  Colors[ 9 ] := TAlphaColorRec.Red;

  Setlength( Scheiben, 0 );
  TrackBar1.Value := Dauer * 1000;

  Stange[ 1 ] := TStack<integer>.Create;
  Stange[ 2 ] := TStack<integer>.Create;
  Stange[ 3 ] := TStack<integer>.Create;

  Pole[ 1 ].X := Leftpole.Position.X + ( Leftpole.Width / 2 );
  Pole[ 2 ].X := MidPole.Position.X + ( MidPole.Width / 2 );
  Pole[ 3 ].X := RightPole.Position.X + ( RightPole.Width / 2 );

  Init( trunc( SpinBox1.Value ) );
end;


function TForm128.GetColor( A, B: integer ): TAlphaColor;
var
  M: Single;
begin
  if A = 0
  then
    Exit( Colors[ 0 ] );
  if A = B
  then
    Exit( Colors[ 9 ] );

  M := ( 9 / B ) * A;

  Result := Colors[ trunc( M ) ];
end;

function TForm128.GetZug( out AZug: TZug ): boolean;
begin
  if Zugliste.Count > 0
  then
    begin
      AZug := Zugliste.Dequeue;
      Result := true;
    end
  else
    Result := false;
end;

procedure TForm128.Animation( AKind: TKindOfAnimation );
begin
  AktAnimation := AKind;

  case AKind of
    Up:
      begin
        FloatAnimation1.Stop;
        FloatAnimation1.Parent := Scheiben[ ScheibenNr ];
        FloatAnimation1.StartValue := Scheiben[ ScheibenNr ].Position.Y;
        FloatAnimation1.StopValue := MaxHeight;
        FloatAnimation1.AnimationType := TAnimationType.&In;
        FloatAnimation1.Interpolation := TInterpolationType.Quadratic;
        FloatAnimation1.Start;
      end;
    RightOrLeft:
      begin
        FloatAnimation2.Stop;
        FloatAnimation2.Parent := Scheiben[ ScheibenNr ];
        FloatAnimation2.StartValue := Scheiben[ ScheibenNr ].Position.X;
        FloatAnimation2.StopValue := Pole[ AktZug.Nach ].X - ( Scheiben[ ScheibenNr ].Width / 2 );
        FloatAnimation2.Start;
      end;
    Down:
      begin
        FloatAnimation1.Stop;
        FloatAnimation1.Parent := Scheiben[ ScheibenNr ];
        FloatAnimation1.StartValue := MaxHeight;
        FloatAnimation1.StopValue := Ground.Position.Y - ( Stange[ AktZug.Nach ].Count * Dicke );
        FloatAnimation1.AnimationType := TAnimationType.Out;
        FloatAnimation1.Interpolation := TInterpolationType.Bounce;
        FloatAnimation1.Start;
      end;
  end; // of case
end;

procedure TForm128.Button1Click( Sender: TObject );
begin
  Button1.Enabled := false;
  SpinBox1.Enabled := false;
  Application.ProcessMessages;

  Init( trunc( SpinBox1.Value ) );

  Zugliste := TQueue<TZug>.Create;
  dohanoi( trunc( SpinBox1.Value ), 1, 3, 2 );

  ShowZüge;
end;

procedure TForm128.DeInit;
begin
  Zugliste.Free;
  FloatAnimation1.Parent := nil;
  FloatAnimation2.Parent := nil;
  Button1.Enabled := true;
  SpinBox1.Enabled := true;
end;

procedure TForm128.Init( const AAnzahl: integer );
var
  i : integer;
  StartSize, StartStack, DeltaW: Single;
begin
  Stange[ 1 ].Clear;
  Stange[ 2 ].Clear;
  Stange[ 3 ].Clear;

  for i := 0 to high( Scheiben ) do
    Scheiben[ i ].Free;

  StartSize := Größe;
  StartStack := Ground.Position.Y - Dicke;
  Setlength( Scheiben, AAnzahl );

  FloatAnimation1.Duration := TrackBar1.Value / 1000;
  FloatAnimation2.Duration := TrackBar1.Value / 1000;

  DeltaW := 230 / AAnzahl;

  for i := 0 to AAnzahl - 1 do
    begin
      Scheiben[ i ] := TRectangle.Create( Self );
      Scheiben[ i ].Parent := Layout1;
      Scheiben[ i ].Height := Dicke;
      Scheiben[ i ].Width := StartSize;
      Scheiben[ i ].Position.X := Pole[ 1 ].X - ( StartSize / 2 );
      Scheiben[ i ].Position.Y := StartStack;
      Scheiben[ i ].Fill.Color := GetColor( i, AAnzahl - 1 );
      StartStack := StartStack - Dicke;
      StartSize := StartSize - DeltaW;
      Stange[ 1 ].Push( i );
    end;
end;

procedure TForm128.ShowZug( AZug: TZug );
begin
  ScheibenNr := Stange[ AZug.Von ].Pop;
  Stange[ AZug.Nach ].Push( ScheibenNr );

  AktZug := AZug;
  Animation( Up );
end;

procedure TForm128.ShowZüge;
var
  Zug: TZug;
begin
  if GetZug( Zug )
  then
    ShowZug( Zug )
  else
    DeInit;
end;


{ TZug }

constructor TZug.Create( AVon, ANach: integer );
begin
  Von := AVon;
  Nach := ANach;
end;

end.
  Mit Zitat antworten Zitat