Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   "Lego Logo für Arme" - Brauche Hilfe (https://www.delphipraxis.net/122691-lego-logo-fuer-arme-brauche-hilfe.html)

Juggy D 20. Okt 2008 17:42


"Lego Logo für Arme" - Brauche Hilfe
 
Hallo,

wir behandeln grad das Thema theoretische Informatik. Und ich kommt damit irgendwie nicht klar (zumnidest nicht mit den ganzen Automaten).

Also wir sollen das Programm "Lego Logo für Arme" erstellen, ich habs auch schon teilweise raus.
W steht für wiederholung, v für vorwärts, r für "nach rechts"/winkel und die zahl für anzahl der pixel.
Also man gibt z.B. "w4(v100r90)" ein und es wird ein rechteck gezeichnet. Mit dem Programm, das ich erstellt habe geht das auch (da ich für die befehle einzelne Edit Felder genommen habe).
Doch wie sieht das ganze aus, wenn ich da z.b. "w4(w7(v100r90)r10)" eingeben möchte. Ich kann da ja nicht unzählige Edit Felder hinmachen für mehrere w's und r's. Habt ihr eine idee? Bzw. wie ist es möglich, aus einem einzigen Editfeld heraus die w's mit der zahl der pixel und die r's mit der zahl der pixel voneinander zu trennen bzw. zeichnen zu lassen.
Meine jetzige version sieht halt so aus:

Delphi-Quellcode:
unit UersterVersuch;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    BStart: TButton;
    EVorwaerts: TEdit;
    EWinkel: TEdit;
    LVorwaerts: TLabel;
    LWinkel: TLabel;
    Shape1: TShape;
    EWiederhol: TEdit;
    LWiederholung: TLabel;
    procedure BStartClick(Sender: TObject);
    procedure drehe(Winkel:real);
    procedure gehe(Schritte:real);


  private
    { Private-Deklarationen }
  public

    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  x1, y1, alpha: real;

implementation

{$R *.dfm}

procedure TForm1.drehe(Winkel:real);
begin
    alpha:=alpha-Winkel*PI/180;
end;

procedure TForm1.gehe(Schritte:real);
  var x2,y2:real;
  begin
    Form1.Canvas.MoveTo(round(x1),round(y1));
    x2:=x1+Schritte*cos(alpha);
    y2:=y1-Schritte*sin(alpha);
    Form1.Canvas.LineTo(round(x2),round(y2));
    x1:=x2;
    y1:=y2;
  end;


procedure TForm1.BStartClick(Sender: TObject);
var i, z: integer;
begin
  x1:=300;
  y1:=300;
  z:= Strtoint(EWiederhol.Text);

    for i:=1 to z do
      begin
        gehe(strtofloat(EVorwaerts.Text));
        drehe(Strtofloat(EWinkel.Text));
      end;
end;

end.
Wäre für jede Hilfe dankbar. :-D

Uwe Raabe 20. Okt 2008 18:49

Re: "Lego Logo für Arme" - Brauche Hilfe
 
Der Einfachheit halber lasse ich mal nur ganze Zahlen als Weg bzw. Winkel zu. Das läßt sich aber leicht erweitern.

Delphi-Quellcode:
procedure TForm1.Execute(var S: string);

  function GetZahl(var S: string): Integer;
  var
    neg: Boolean;
  begin
    Result := 0;
    neg := false;
    if S[1] in ['-', '+'] then begin
      neg := S[1] = '-';
      Delete(S, 1, 1);
    end;
    while (Length(S) > 0) and (S[1] in ['0'..'9']) do begin
      result := 10*result + Ord(S[1]) - Ord('0');
      Delete(S, 1, 1);
    end;
    if neg then
      result := -result;
  end;

var
  I: Integer;
  N: Integer;
  save: string;
begin
  while Length(S) > 0 do begin
    case UpCase(S[1]) of
      'W': begin
        Delete(S, 1, 1);
        N := GetZahl(S);
        Assert(S[1] = '(', '''('' expected');
        Delete(S, 1, 1);
        save := S;
        for I := 1 to N - 1 do begin
          S := save;
          Execute(S);
        end;
      end;
      'V': begin
        Delete(S, 1, 1);
        Gehe(GetZahl(S));
      end;
      'R': begin
        Delete(S, 1, 1);
        Drehe(GetZahl(S));
      end;
      ')': begin
        Delete(S, 1, 1);
        Break;
      end;
    else
      raise Exception.Create('ungültiges Zeichen');
    end;
  end;
end;

// Aufruf
var
  S: String;
begin
  S := Trim(Edit1.Text);
  Execute(S);
  Assert(S = '', 'Befehle nicht vollständig abgearbeitet');
end;

Juggy D 20. Okt 2008 20:04

Re: "Lego Logo für Arme" - Brauche Hilfe
 
Hi,

Erstmal vielen Dank für deine Hilfe & Mühe. Das dumme ist nur, ich versteh da ziemlich wenig. Meine Delphikentnisse sind relativ begrenzt. :oops:

Hab weitergesucht und rausgekriegt, dass man das auch mit nem Kellerautomaten lösen kann. Automat hört sich ja schonmal gut an, da wir sowas auch in der Schule bearbeitet haben.

Hätte jemand vielleicht dafür nen Ansatz?

Juggy D 21. Okt 2008 17:24

Re: "Lego Logo für Arme" - Brauche Hilfe
 
Kann mir hier sonst wirklich keiner helfen?? :( Oder kann mir jemand das obige etwas genauer erklären, so dass ich es auch verstehe?

Uwe Raabe 21. Okt 2008 19:03

Re: "Lego Logo für Arme" - Brauche Hilfe
 
Na dann...

Die Methode Execute bearbeitet den übergebenen String und "frisst" sozusagen alle Zeichen, mit denen sie etwas anfangen kann. Wenn sie die Befehlssequenz vollständig abarbeiten kann, ist S hinterher leer.

Innerhalb der Methode wird zunächst das erste Zeichen untersucht und entsprechend verzweigt. Bei den V- und R-Befehlen wird der anschließende Zahlenwert gelesen (auch GetZahl frisst die Zeichen, die es liest) und der Befehl direkt ausgeführt. Im Falle einer Wiederholung lesen wir auch die folgende Zahl und löschen die folgende öffnende Klammer. Dann merken wir uns den aktuellen Inhalt der restlichen Befehlssequenz und rufen in einer Schleife das Execute immer wieder mit dem gespeicherten Wert rekursiv auf. Die schließende Klammer in der Case-Anweisung sorgt für den notwendigen Rücksprung aus der Rekursion (bricht die while-Schleife ab).

Diese Lösung ist rein pragmatisch auf die geschilderte Aufgabe bezogen und erhebt keinen Anspruch auf didaktische Brauchbarkeit für das Lernen der Theoretischen Informatik. Die übergeordnete Routine fährt dann mit dem Reststring fort.

Juggy D 21. Okt 2008 19:52

Re: "Lego Logo für Arme" - Brauche Hilfe
 
Okay,

habs soweit kapiert. Ich werde mich mal morgen an das ganze ranmachen, sollte ich Hilfe brauchen (was wahrscheinlich der Fall sein wird), melde ich mich wieder.

Vielen dank nochmal :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz