unit Zelvaci; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Spin; type TForm1 = class(TForm) I_Obrazek: TImage; GB_Data: TGroupBox; E_Load: TEdit; E_Save: TEdit; Label1: TLabel; Label2: TLabel; B_Prochazet: TButton; B_Load: TButton; OD_Open: TOpenDialog; B_Print: TButton; SE_Pocet: TSpinEdit; Label3: TLabel; B_Clear: TButton; procedure B_ProchazetClick(Sender: TObject); procedure B_LoadClick(Sender: TObject); procedure B_PrintClick(Sender: TObject); procedure B_ClearClick(Sender: TObject); procedure FormCreate(Sender: TObject); private public end; var Form1: TForm1; Prikazy:array of String; //prikazy pro vykreslovani implementation {$R *.dfm} //Otevreni OpenDialogu a vypsani nazvu souboru do Editu procedure TForm1.B_ProchazetClick(Sender: TObject); begin if (OD_Open.Execute) then begin E_Load.Text := OD_Open.FileName; B_Print.Enabled := false; end;//if OD_Open.Execute end;//procedure //nacitani dat procedure TForm1.B_LoadClick(Sender: TObject); var M_Data:TMemo; //TMemo, do ktereho se budou nacitat data ze souobru .txt cyklus:Integer; //promenna pouzivena pro cykleni v cyklech Data:TStrings; //pole oddelenych dat, ketre bude naplneno prikazy OutPut:Array of String; //Defintivni vystupni data, ktera prijdou do promenne Prikazy Pozice:Integer; //Pozice pri oddelovani jednotlivych prikazu LoadText:String; //celkovy nacteny text ze souboru begin //overeni, zda jsou vyplnena vsechna potrebna data if (E_Load.Text = '') or (E_Save.Text = '') then begin MessageBox(Form1.Handle,'Zvolte cestu k nacteni souboru txt a cestu k ulozeni souboru bmp!','Chyba',MB_OK OR MB_ICONWARNING); Exit; end;//if ... //vytvoreni Mema za ucelem nacitani souboru M_Data := TMemo.Create(Form1); //nastaveni jeho rodicu M_Data.Parent := Form1; //zneviditelneni M_Data.Visible := false; //nacteni prislusneho souboru M_Data.Lines.LoadFromFile(E_Load.Text); //zpracovani dat zacatek //nastaveni delky pole s prikazy na delku pole, kde je nacteny text SetLength(Prikazy,Length(M_Data.Text)); //cykleni za ucelem eliminovani nezadoucich znaku for cyklus := 1 to Length(M_Data.Text)-1 do begin //overovani nezadoucich znaku if ((M_Data.Text[cyklus] <> ' ') and (M_Data.Text[cyklus] <> #13) and (M_Data.Text[cyklus] <> #10) and (M_Data.Text[cyklus] <> #9)) then begin //pokud je znak v poradku, prida se do stringu LoadText LoadText := LoadText + M_Data.Text[cyklus]; end;//konec podminky na overovani znaku end;//konec cyklus //zniceni Mema M_Data.Free; //vytvoreni objektu typu TStringList za ucelem rozdeleni prikazu na jednotlive samostatne prikazy Data := TStringList.Create; //oznacuje radek v seznamu prikazu Pozice := 0; //rozdeleni celeho textu na jednotlive prikazy ExtractStrings([')'],[],PChar(LoadText),Data); //trideni jednotlivych prikazu do pole pomoci cyklu for cyklus := 0 to Data.Count-1 do begin //prubezne zvetsovani pole - nevim, kolik prikazu se v souboru vyskutyje SetLength(OutPut,Length(OutPut)+1); //dodani zavorky za prislusny text, protoze ExtractString rozdeli text podle znaku ")" a tento znak z textu eliminuje OutPut[Pozice] := Data[cyklus]+ ')'; //nastavni pozice, na jakem prikazu jsme (resp. na jakem radku) Pozice := Pozice + 1; end;//konec tridiciho cyklu //zniceni promenne na uchovu rozdelenecho textu Data.Free; //zpracovani dat konec //nastaveni velikosti pole pro cely program (OutPut je jen lokalnui promenna) SetLength(Prikazy,Length(OutPut)); //predavani dat z pole do pole po jednotlivych polozkach for cyklus := 0 to Length(OutPut)-1 do begin Prikazy[cyklus] := OutPut[cyklus]; end;//konec predavani dat //aktivace tlacitka vykreslit B_Print.Enabled := true; //nasataveni maximalniho poctu prikazu jako hodnoty MaxValue do objekty SE_Pocet SE_Pocet.MaxValue := Length(Prikazy); end;//procedure //zajistuje vykreslovani trajektorie procedure TForm1.B_PrintClick(Sender: TObject); var cyklus,cyklus2:Integer; //promenne pro cykleni X,Y:Integer; //Aktualni pozice na obrazovce Data:TStrings; //oddelena data (prikazy versus jeich parametry) Uhel:Integer; //aktualni uhel ve stupnich Kresleni:Boolean; //zda probiha kresleni - pero je dole Radiany:Extended; //uhel v radianech na desetinna mista Pocet:Integer; //pocet prikazu begin //nejdrive vymazu zobrazovaci plochu B_ClearClick(Self); //nastaveni vychozi barvu pera a nastaveni barvy pozadi I_Obrazek.Canvas.Pen.Color := clBlack; I_Obrazek.Canvas.Brush.Color := clWhite; //nastaveni tloustky pera I_Obrazek.Canvas.Pen.Width := 1; //nastaveni nekresleni po zacatku Kresleni := false; //nastaveni vychozich souradnic a uhlu X := 350; Y := 350; uhel := 270; //overovani, zda se ma tahnou tolikrat, kolik je v programu prikazu if (SE_Pocet.Value = 0) then begin Pocet := Length(Prikazy); end else begin Pocet := SE_Pocet.Value; end;//else pocet = 0 //vytvoreni promenne pro oddeleni prikazu od jejich parametru Data := TStringList.Create; //cykleni prikazama for cyklus := 0 to Pocet do begin //vycisteni prikazu Data.Clear; //rozdeleni prikazu na prikazy a jejich paramtry pomoci zavorek a carek to promenne Data ExtractStrings(['(',')',','],[],PChar(Prikazy[cyklus]),Data); //overovani jednotlivych prikazu //prikaz na nastaveni barvy if (Data[0] = 'color') then begin //overovani vyjimek pri spatne zadanych barvach zacatek if (StrToInt(Data[1]) < 0) then begin Data[1] := '0'; end; if (StrToInt(Data[2]) < 0) then begin Data[2] := '0'; end; if (StrToInt(Data[3]) < 0) then begin Data[3] := '0'; end; if (StrToInt(Data[1]) > 255) then begin Data[1] := '255'; end; if (StrToInt(Data[2]) > 255) then begin Data[2] := '255'; end; if (StrToInt(Data[3]) > 255) then begin Data[3] := '255'; end; //overovani vyjimek pri spatne zadanych barvach konec //nastaveni prislusne barvy ve formatu RGB I_Obrazek.Canvas.Pen.Color := RGB(StrToInt(Data[1]),StrToInt(Data[2]),StrToInt(Data[3])); end; //otoceni doleva if (Data[0] = 'left') then begin //overovani, zda jsme neprekrocili nulovou hranici - uhel by byl zaporny if (Uhel-StrToInt(Data[1]) < 0) then begin Uhel := Uhel + (360-StrToInt(Data[1])); end else begin Uhel := Uhel - StrToInt(Data[1]); end;//else Uhel > 360 end; //otoceni doprava if (Data[0] = 'right') then begin //overovani, zda jsme neprekrocili hranici 360 stupnu - uhel by byl vetsi, nez 360 stupnu if (Uhel+StrToInt(Data[1]) >= 360) then begin Uhel := Uhel - (360 - StrToInt(Data[1])); end else begin Uhel := Uhel + StrToInt(Data[1]); end;//else Uhel > 360 end; //nastaveni pera if (Data[0] = 'pen') then begin if (StrToInt(Data[1]) <= 0) then begin //vypnuti kresleni Kresleni := false; end else begin //zapnuti kresleni Kresleni := true; //nastaveni tloustky pera I_Obrazek.Canvas.Pen.Width := StrToInt(Data[1]); end;//else Data[1] <= 0 end; //kresleni jednotlivych car if (Data[0] = 'forward') then begin //vypocitani uhlu v radianech Radiany := Uhel/57.29577951308232087721; //overeni, zda opravdu kreslime, nebo se jen pohybujeme po obrazovce bez kresleni if (Kresleni) then begin //kresleni pomoci prikazu MoveTo a LineTo I_Obrazek.Canvas.MoveTo(X,Y); //vypocitani novych souradnic podle zadani X := X + StrToInt(Data[1])*round(cos(Radiany)); Y := Y + StrToInt(Data[1])*round(sin(Radiany)); I_Obrazek.Canvas.LineTo(X,Y); end else begin//if Kresleni //pouze nastavime nove souradnice X a Y do promennych - nekreslime X := X + StrToInt(Data[1])*round(cos(Radiany)); Y := Y + StrToInt(Data[1])*round(sin(Radiany)); end; end; //opakovani if (Data[0] = 'repeat') then begin //zde se opakuji vsechny prikazy - stejny cyklus, jako nahore akorat do nej vnoreny for cyklus2 := 0 to StrToInt(Data[1])-1 do begin Data.Clear; ExtractStrings(['{','}',','],[],PChar(Prikazy[cyklus2]),Data); if (Data[0] = 'color') then begin if (StrToInt(Data[1]) < 0) then begin Data[1] := '0'; end; if (StrToInt(Data[2]) < 0) then begin Data[2] := '0'; end; if (StrToInt(Data[3]) < 0) then begin Data[3] := '0'; end; if (StrToInt(Data[1]) > 255) then begin Data[1] := '255'; end; if (StrToInt(Data[2]) > 255) then begin Data[2] := '255'; end; if (StrToInt(Data[3]) > 255) then begin Data[3] := '255'; end; I_Obrazek.Canvas.Pen.Color := RGB(StrToInt(Data[1]),StrToInt(Data[2]),StrToInt(Data[3])); end; if (Data[0] = 'left') then begin if (Uhel-StrToInt(Data[1]) < 0) then begin Uhel := Uhel + (360-StrToInt(Data[1])); end else begin Uhel := Uhel - StrToInt(Data[1]); end;//else Uhel > 360 end; if (Data[0] = 'right') then begin if (Uhel+StrToInt(Data[1]) > 360) then begin Uhel := Uhel - (360 - StrToInt(Data[1])); end else begin Uhel := Uhel + StrToInt(Data[1]); end;//else Uhel > 360 end; if (Data[0] = 'pen') then begin if (StrToInt(Data[1]) <= 0) then begin Kresleni := false; end else begin Kresleni := true; I_Obrazek.Canvas.Pen.Width := StrToInt(Data[1]); end;//else Data[1] <= 0 end; //konec pen if (Data[0] = 'forward') then begin Radiany := Uhel/57.29577951308232087721; if (Kresleni) then begin I_Obrazek.Canvas.MoveTo(X,Y); X := X + StrToInt(Data[1])*round(cos(Radiany)); Y := Y + StrToInt(Data[1])*round(sin(Radiany)); I_Obrazek.Canvas.LineTo(X,Y); end else begin//if Kresleni X := X + StrToInt(Data[1])*round(cos(Radiany)); Y := Y + StrToInt(Data[1])*round(sin(Radiany)); end; end; //konec forward end;//for cyklus2 end;//konec prikazu repeat end;//konec cykleni za ucelem kresleni //uvolneni promenne Data z pameti Data.Free; //ulozeni obrazku jako daneho souboru .bmp s nazvem zvolenym uzivetelem I_Obrazek.Picture.SaveToFile(E_Save.Text+'.bmp'); end;//procedure //vymazani platna procedure TForm1.B_ClearClick(Sender: TObject); begin //vyukresleni jednoho velkeho bileho obdelniku pres celou kreslici plochu I_Obrazek.Canvas.Pen.Color := clWhite; I_Obrazek.Canvas.Brush.Color := clWhite; I_Obrazek.Canvas.Rectangle(0,0,I_Obrazek.Width,I_Obrazek.Height); end;//procedure //pri vytvoreni okna procedure TForm1.FormCreate(Sender: TObject); begin //smazani platna a nastaveni cesty do proslusneho adresare B_ClearClick(Self); E_Save.Text := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName))+'Obrazek'; end;//procedure end.//unit