Programowanie w języku Logo

Page 1

Józef Zieliński

Programowanie w języku Logo

Kraków 2009


© Copyright by Oficyna Wydawnicza „Impuls”, Kraków 2009

Projekt okładki: Ewa Beniak-Haremska

ISBN 978-83-7587-205-7

Oficyna Wydawnicza „Impuls” 30-619 Kraków, ul. Turniejowa 59/5 tel. (0-12) 422-41-80, fax (0-12) 422-59-47 www.impulsoficyna.com.pl, e-mail: impuls@impulsoficyna.com.pl Wydanie I, Kraków 2009


Spis treści Wprowadzenie

5

1. Grafika żółwia 1.1. Podstawowe procedury . . . . . . 1.2. Instrukcje iteracyjne . . . . . . . 1.3. Definiowanie procedur . . . . . . 1.4. Zastosowanie funkcji . . . . . . . 1.5. Kolorowanie . . . . . . . . . . . . 1.6. Grubość pisaka . . . . . . . . . . 1.7. Styl kreślonej linii . . . . . . . . . 1.8. Styl zamalowywania powierzchni . 1.9. Bezwzględne położenie żółwia . .

. . . . . . . . .

7 7 10 11 14 17 20 20 21 22

2. Programowanie strukturalne 2.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Wirówki . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3. Przykłady . . . . . . . . . . . . . . . . . . . . . . . . . . .

23 23 28 32

3. Okręgi i łuki 3.1. Okręgi . . . . . . . . . 3.2. Półokręgi . . . . . . . . 3.3. Łuki . . . . . . . . . . 3.4. Procedura standardowa 3.5. Przykłady . . . . . . .

. . . . .

39 39 46 53 58 60

4. Procedury rekurencyjne 4.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . 4.2. Spirale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3. Płatek Kocha . . . . . . . . . . . . . . . . . . . . . . . . .

63 63 64 66

. . . . . . . . . . . . . . . . . . ellipse . . . . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .

. . . . . . . . .

. . . . .


4

SPIS TREŚCI 4.4. Trójkąt i dywan Sierpińskiego 4.5. Krzywa Peano . . . . . . . . . 4.6. Smok Hartera . . . . . . . . . 4.7. Krzywa Hilberta . . . . . . . . 4.8. Drzewo binarne . . . . . . . . 4.9. Drzewo Pitagorasa . . . . . . 4.10. Paprotka . . . . . . . . . . . 4.11. Przykłady . . . . . . . . . .

. . . . . . . .

69 72 74 76 78 80 89 94

. . . .

105 105 108 109 112

6. Słowa i listy 6.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . 6.2. Procedury pierwotne . . . . . . . . . . . . . . . . . . . . . 6.3. Przykłady . . . . . . . . . . . . . . . . . . . . . . . . . . .

117 117 119 125

Podsumowanie

140

Bibliografia

141

5. Obliczenia w Logo 5.1. Wprowadzenie . . . . 5.2. Funkcje . . . . . . . 5.3. Notacja polska . . . . 5.4. Funkcje rekurencyjne

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .

. . . . . . . .

. . . .


Wprowadzenie Język programowania Logo został opracowany przez Seymourta Paperta i jego współpracowników z Laboratorium Sztucznej Inteligencji w MIT (Massachussetts Institute of Technology), zainspirowanych pracami i działalnością francuskiego psychologa i pedagoga J.Piageta, który badał sposoby myślenia dzieci, w różnych etapach ich rozwoju i podejmował próby przyspieszenia tego rozwoju. Logo powstało na początku lat siedemdziesiątych, jako język edukacyjny, przeznaczony do pierwszych kontaktów z komputerem. Spełnia w dużym stopniu warunki stawiane nowoczesnym językom programowania. Jest łatwe oraz wygodne w użyciu, czytelne i nieobciążające zbędnymi szczegółami użytkownika przy rozwiązywaniu problemów z wykorzystaniem komputera. Mimo swojej prostoty i łatwości w posługiwaniu się nim, Logo jest językiem dość wszechstronnym, nie ograniczającym programisty do wąskiej klasy zastosowań. S.Papert charakteryzuje Logo jednym zdaniem: „Logo nie ma progów i sufitów, jest łatwe do nauczenia się, ale równocześnie jest interesującym wyzwaniem dla wytrawnych programistów”1 . Charakterystycznym elementem tego języka jest tzw. „grafika żółwia”, najbardziej widoczna w pierwszych kontaktach z Logo. Logo wykorzystuje grafikę do poglądowego, wręcz wciągającego do zabawy, uczenia podstawowych pojęć informatyki związanych z programowaniem strukturalnym, tworzeniem procedur, posługiwaniem się mechanizmem rekurencji, tworzeniem procedur niezmienniczych i prawidłowym konstruowaniem wymiany parametrów między poszczególnymi procedurami. Język Logo jest językiem proceduralnym i programowanie w nim polega na tworzeniu procedur rozwiązujących konkretne zadanie. Zwykle procedury te używają innych, te z kolei innych i w rzeczywistości może być to bardzo rozbudowana struktura. Wywołanie głównej procedury, to jakby wywołanie programu, ale można też wywołać każdą procedurę osobno, aby 1

A.Jeske, Logo w zadaniach, 1988


6

WPROWADZENIE

na przykład sprawdzić jej poprawność. Tak więc w środowisku Logo mamy do dyspozycji pojedyncze procedury, które wiążemy w logiczną całość lub używamy ich samodzielnie w zależności od tego co chcemy osiągnąć. Praca z programem jest konwersacyjna, Logo jest językiem interpretowanym. Tok rozumowania przy programowaniu w Logo jest zgodny z naszym naturalnym sposobem myślenia - rozbijania problemu na mniejsze części, które dadzą się już łatwo rozwiązać i składania z tych części rozwiązania całości. Użytkownik łatwo może sam rozbudować Logo o nowe instrukcje (procedury) i dopasować je do rozwiązania określonego problemu. W przeciągu ponad 35 lat od opracowania angielskiej wersji Logo, utworzono szereg interpreterów Logo, również całych środowisk, wykorzystujących coraz większe możliwości komputerów i systemów operacyjnych. Oprócz interpreterów w języku angielskim opracowywano również interpretery w języku ojczystym lub w obu tych językach. Kolejne wersje Logo oprócz wzbogacanego zestawu instrukcji standardowych umożliwiały tworzenie animacji, pracę z wieloma żółwiami, oraz tworzenie rysunków trójwymiarowych. W Polsce pierwszą szeroko rozpowszechnioną wersją było ACLogo, z 1992 roku, przystosowane do systemu operacyjnego DOS. Następnym interpreterem jest Logo Komeniusz, rozpowszechniany w Polsce od 2000 roku. Kolejnym interpreterem jest Logomocja-Imagine, rozpowszechniany w Polsce od 2003 roku. Niektóre szkoły, zwłaszcza te mniejsze, ze względów oszczędnościowych, korzystają z bezpłatnego interpretera MSWLogo, utworzonego w USA (tylko w wersji angielskiej). Występują pewne różnice w niektórych instrukcjach, zwłaszcza w iteracyjnych i warunkowych. W Logo Komeniuszu w celu kontynuacji listy w następnej linii trzeba na końcu linii wstawić znak tyldy. W pracy przedstawiono wybrane instrukcje i ich zastosowanie oraz przykłady algorytmów. Przyjęto wersję angielską, gdyż większość młodzieży uczy się języka angielskiego. Wszystkie przykłady zostały uruchomione interpreterem Logomocja-Imagine.


Rozdział 1 Grafika żółwia 1.1.

Podstawowe procedury

Istotą grafiki żółwia w Logo jest użycie wskaźnika graficznego, zwanego żółwiem. Wskaźnik może mieć różny kształt, zależnie od implementacji. W obecnych implementacjach można używać wiele żółwi oraz indywidualnie nadawać im kształty, najczęściej żółwiem jest trójkącik. Żółwiem można sterować podając komendy z klawiatury i w ten sposób rysować obraz na ekranie. Podsumowując, ruch generuje obraz. Stosunkowo łatwo można rysować bardzo złożone figury. Bezpośednio na ekranie widać w postaci graficznej wyniki swojej pracy. Można porównać otrzymaną figurę z oczekiwaną, wykryć i usunąć błędy. Logo w formie zabawy uczy myśleć i wprowadza w tajniki programowania. W Logo jest możliwość definiowania nowych poleceń, czyli w przenośni uczeń staje się nauczycielem komputera. Żółw na ekranie ma określone położenie w układzie kartezjańskim (współrzędne X i Y), oraz kierunek, w jakim jest ustawiony. Żołw może poruszać się naprzód i wstecz za pomocą prostych komend, można również zmieniać jego kierunek poleceniami lewo lub prawo (kąt jest wyrażony w stopniach). Żółw trzyma pióro, które może być opuszczone lub podniesione, ewentualnie zamienione na gumkę. Poniżej przedstawione są podstawowe komendy sterujące ruchem żółwia. W Polsce są używane różne wersje Logo, bardziej uniwersalne angielskie i bardziej przystępne polskie. W tych wersjach niektóre komendy mają dwie postacie, pełną i skróconą. W pracy przedstawiono zasadniczo komendy angielskie oraz dodatkowo kursywą w nawiasach kątowych komendy w języku polskim, komendy


8

ROZDZIAŁ 1. GRAFIKA ŻÓŁWIA

są w postaciach pełnych i skróconych. Natomiast wszystkie przykłady są w wersji angielskiej. Dwie poniższe procedury sterujące ruchem żółwia wymagają tylko jednego argumentu, ilości pikseli na ekranie, o którą należy przesunąć żółwia: 1. przesunięcie żółwia naprzód o podaną liczbę pikseli (forwrd, fd <naprzód, np>), 2. przesunięcie żółwia wstecz o podaną liczbę pikseli (back, bk <wstecz, ws>). Dwie kolejne procedury sterujące ruchem żółwia też wymagają tylko jednego argumentu, kąta wyrażonego w stopniach, o który ma się obrócić żółw: 1. obrót żółwia w prawo o podaną liczbę stopni (right, rt <prawo, pw >), 2. obrót żółwia w lewo o podaną liczbę stopni (left, lt <lewo, lw >). Następne procedury, sterujące zółwiem, są bezargumentowe: 1. podniesienie pisaka (penup, pu <podnieś, pod >), 2. opuszczenie pisaka (pendown, pd <opuść, opu>), 3. ścieranie, pisak staje się gumką i wymazuje ślad, pozostawiając podczas ruchu linię koloru tła (penerase, pe <ścieranie, ścier >), 4. odwracanie, pisak zmienia kolor pikseli z koloru tła na kolor atramentu, a z koloru atramentu na kolor tła (penreverse, px <odwracanie, odwr >), 5. czyszczenie okienka graficznego, czyli wypełnianie kolorem tła, oraz umieszczenie żółwia w środku okienka, skierowanie pionowo w górę (clearscreen, cs <czyść, cs>), 6. czyszczenie okienka graficznego, czyli wypełnianie kolorem tła, ale pozostawienie zółwia w tym samym położeniu (clean, <zmaż >), 7. umieszczenie żółwia w położeniu początkowym, w środku okienka, skierunkowianie pionowo w górę, bez czyszczenia okienka graficznego (home <wróć>),


1.1. PODSTAWOWE PROCEDURY

9

8. pokazanie żółwia (showturtle, st <pż >), ale z widocznym żółwiem wolniej są rysowane złożone figury i przysłaniane niektóre szczegóły 9. schowanie żółwia (hideturtle, ht <sż >). Wyjście z trybu ścierania dokonuje się za pomocą jednej z instrukcji: • penup (pu), • pendown (pd), • penreverse (px). W rozwiązywaniu zadań graficznych głównie używa się pierwszych sześciu procedur graficznych. Nowsze interpretery Logo umożliwiają posługiwanie się wieloma żółwiami. Nie przyspiesza i nie upraszcza to rysowania złożonych figur, ale ułatwia tworzenie animacji, gdyż żółwie mogą mieć różne postacie i różne własności. W trybie bezpośrednim, konwersacyjnym wpisuje się polecenia i po zatwierdzeniu klawiszem Enter nastąpuje ich wykonanie. Poszczególne polecenia mogą byc wpisywane pojedynczo, w oddzielnych liniach, oddzielnie zatwierdzane klawiszem Enter. Ten sposób umożliwia obserwację wykonywania poszczególnych poleceń. Polecenia mogą być też wpisane w jednej linii. Przykładowo wykonanie następujących poleceń spowoduje narysowanie rysunku 1.1, przedstawiającego trójkąt równoboczny: cs fd fd fd

st rt 30 100 rt 120 100 rt 120 100 rt 90

Rys. 1.1. W trybie bezpośrednim narysowany trójkąt równoboczny


10

1.2.

ROZDZIAŁ 1. GRAFIKA ŻÓŁWIA

Instrukcje iteracyjne

W języku Logo są dwie instrukcje iteracyjne: repeat i while. Instrukcja repeat <powtórz > powtarza listę instrukcji określoną liczbę razy. Po słowie repeat jest wyrażenie arytmetyczne, które podaje liczbę powtórzeń, następnie jest zamknięta w nawiasy kwadratowe lista instrukcji. Przykład zastosowania instrukcji iteracyjnej do narysowania kwadratu o boku 100: repeat 4 [fd 100 rt 90] . Instrukcja while <dopóki> powtarza listę instrukcji aż do uzyskania określonego skutku. Po słowie while występują dwie listy. Lista pierwsza zawiera wyrażenie logiczne, a lista druga ciąg instrukcji do wykonania. Dopóki wartością wyrażenia logicznego jest prawda, to powtarzane jest wykonanie instrukcji z listy drugiej. Kolejnym przykładem zastosowania instrukcji iteracyjnej jest narysowanie figury przdstawionej na rysunku 1.2.

Rys. 1.2. Przykładowy rysunek (kwadrat z krzyżem)

Dalej przedstawiono zestaw instrukcji do otrzymania rysunku, w trybie konwersacyjnym. cs rt 45 repeat 4 lt 45 pu bk 50 repeat 4 pu rt 90

(wyczyszczenie ekranu, ustawienie żółwia do rysowania krzyża) [fd 50 bk 50 rt 90] (narysowanie krzyża) (przywrócenie początkowego kierunku żółwia) lt 90 fd 50 rt 90 pd (ustawienie żółwia w lewym dolnym wierzchołku kwadratu) [fd 100 rt 90] (narysowanie kwadratu) fd 50 lt 90 fd 50 pd (na zakończenie przywrócenie początkowego ustawienia żółwia)


1.3. DEFINIOWANIE PROCEDUR

1.3.

11

Definiowanie procedur

Oprócz procedur (poleceń, komend) pierwotnych, można definiować własne procedury. Można w ten sposób w Logo „nauczyć” komputer wykonywania innych poleceń. Definicja procedury składa się z nagłówka, treści, zwanej też ciałem, zawierającej polecenia oraz z zakończenia. Nagłówek procedury składa się z zapowiedzi procedury, nazwy procedury i ewentualnych argumentów. Można definiować procedury bezargumentowe, z jednym lub kilkoma argumentami. Oto przykład definicji procedury bezargumentowej, rysującej kwadrat o boku 100. ?to square > repeat 4 [fd 100 rt 90] >end ?

Rys. 1.3. Wykonanie procedury square

Słowo to <oto> jest zapowiedzią definicji procedury, natomiast słowo square jest nadaną nazwą (identyfikatorem) procedury. Ponieważ procedura ma rysować kwadrat, nadano jej nazwę square, można ją nazwać inaczej, na przykład kwadrat. Następnie podaje się polecenia, tworzące treść (ciało) procedury, w tym przykładzie repeat 4 [fd 100 rt 90]. Ostatnim elementem definicji procedury jest zakończenie, słowo end <już >. W trybie konwersacyjnym interpreter zgłasza się pytajnikiem, natomiast przy definiowaniu procedury zgłasza się znakiem >. Po zakończeniu definiowania procedury ponownie zgłasza się pytajnikiem. W definiowanych procedurach pojawiać się mogą zmienne, zarówno globalne, istniejące w jednym egzemplarzu i dostępne we wszystkich procedurach, jak i lokalne, istniejące i dostępne tylko w danej procedurze. Stąd zmienne lokalne w różnych procedurach mogą mieć tę samą nazwę.


12

ROZDZIAŁ 1. GRAFIKA ŻÓŁWIA

Są to już inne zmienne, chociaż o tej samej nazwie. Deklarując nową zmienną, przed nazwą musimy umieścić cudzysłów. Bez cudzysłowu byłaby to nazwa procedury, a nie zmiennej. Zmienną globalną tworzymy za pomocą polecenia make <przypisz, przyp> podając z cudzysłowem nazwę zmiennej i jej wartość. Przykładowo możemy utworzyć zmienną globalną a i nadać jej wartość 12: make "a 12. Możemy wartość już utworzonej zmiennej a zmienić, nadając jej kolejną wartość, stosując instrukcję make: make "a 150. Jeżeli instrukcję make poprzedzimy instukcją local <lokalna>, to będzie utworzona zmienna lokalna (instrukcja local tworzy zmienną lokalną, make nadaje jej warość). Przykładowo, instrukcje: local "n make "n 3 utworzą zmienną lokalną o nazwie n i wartości początkowej 3. Zmieniamy wartość zmiennej lokalnej tak jak globalnej. Zmienną lokalną możemy utworzyć i równocześnie nadać jej wartość za pomocą instrukcji let <niech>, przykładowo, let "b 17. Jeżeli nazwę zmiennej poprzedzimy dwukropkiem, oznacza to, że dotyczy to wartości zmiennej. Na przykład za pomocą instrukcji make "v :n tworzymy zmienną v i nadajemy jej wartość wcześniej utworzonej zmiennej n. Procedura pentagon :d, rysująca pięciokąt foremny jest przykładem procedury z jednym argumentem. Jako argumenty są podawane słowa z dwukropkiem (bez dwukropka słowo oznaczałoby nazwę procedury czyli polecenie do wykonania). Argumenty procedury są zmiennymi lokalnymi, i są dostępne jedynie w definiowanej procedurze. ? to pentagon :d > repeat 5 [fd :d rt 72] > end ? Procedura rysująca wielokąt foremny o zadanej liczbie boków i zadanej długości boku (regular polygon :n :d ), jest przykładem procedury z dwoma argumentami . Procedurę nazwano regular polygon, gdyż spotyka się procedurę standardową polygon, rysującą dowolny wielokąt, dla zadanej listy wierzchołków. Użyty w nazwie procedury znak podreślenia jest jedynym znakiem, nie będącym literą, traktowanym tak jak litera. ?to regular_polygon :n :d >repeat :n [fd :d rt 360 / :n] >end ?


1.3. DEFINIOWANIE PROCEDUR

13

Rys. 1.4. Pięciokąt, a – zasada konstrukcji pięciokata, b – wykonanie procedury pentagon 100

Rys. 1.5. Wykonanie procedury regular polygon 6 80

Jako przykład procedury z trzema argumentami przedstawiono procedurę star :n :d :j. Jest to procedura rysująca gwiazdę, gdzie n jest liczba boków, d długością boku. Trzeci argument j, powoduje zwielokrotnienie kąta skrętu żółwia w wierzchołkach wielokąta i umożliwia tworzenie innych ciekawych figur, gwiazd. Gdy j ma wartość 1, to procedura rysuje wielokąty foremne. Argumenty n i j nie powinny mieć wspólnego dzielnika. Oto treść procedury. ?to star :n :a :j >repeat :n [fd :a rt 360 / :n * :j] >end ?


14

ROZDZIAŁ 1. GRAFIKA ŻÓŁWIA

Rys. 1.6. Wykonanie procedury star 8 80 1, star 8 80 3

Rys. 1.7. Wykonanie procedury star 5 80 1, star 5 80 2

1.4.

Zastosowanie funkcji

Przy konstrukcji bardziej zaawansowanych rysunków potrzebne są obliczenia, a nawet niekiedy funkcje √trygonometryczne. Aby narysować przekątne kwadratu trzeba obliczyć 2, lub wstawić przybliżoną wartość 1.41. Za pomocą funkcji (sqrt, <pierwiastek, pkw >) oblicza się pierwiastek kwadratowy z danej liczby (argumentu funkcji). Przedstawiona procedura square diagonals :d, rysuje kwadrat z przekątnymi. to square_diagonals :d repeat 4 [fd :d rt 90] rt 45 fd :d * sqrt 2 rt 135 fd :d rt 135 fd :d * sqrt 2


1.4. ZASTOSOWANIE FUNKCJI

15

rt 45 bk :d end

Rys. 1.8. Wykonanie procedury square diagonals 100

Przy konstrukcji niektórych rysunków zachodzi konieczność zastosowania funkcji trygonometrycznych. Chcąc narysować trókąt pitagoryjski, o bokach 3, 4, 5 trzeba wyznaczyć kąty wewnętrzne trójkąta, do czego można wykorzystać funkcje cyklometryczne (odwrotne trygonometryczne). Oto zestaw funkcji trygonometrycznych i cyklometrycznych: 1. funkcja sinus kąta wyrażonego w stopniach (sin <sin>), 2. funkcja cosinus kąta wyrażonego w stopniach (cos <cos>), 3. funkcja tangens kąta wyrażonego w stopniach (tan <tg>), 4. funkcja arcus tangens zwraca kąt wyrażony w stopniach (arctan <arctg>), 5. funkcja arcus sinus zwraca kąt wyrażony w stopniach (arcsin <arcsin>), 6. funkcja arcus cosinus zwraca kąt wyrażony w stopniach (arccos <arccos>). Funkcje arcsin i arccos nie są zaimplementowane w Logomocji i w Komeniuszu, natomiast są zaimplementowane w ACLogo i w MSWLogo. Oto procedura Pythagorean triangle :n rysująca trójkąt pitagoryjski o bokach bedących krotnościami liczb 3, 4, 5. Argument n jest tą krotnoscią.


16

ROZDZIAŁ 1. GRAFIKA ŻÓŁWIA

Rys. 1.9. Wykonanie procedury Pythagorean triangle 20

to Pythagorean_triangle :n fd 3 * :n rt 180 - arctan 4 / 3 fd 5 * :n rt 180 - arctan 3 / 4 fd 4 * :n rt 90 end W niektórych zadaniach potrzebne są liczby losowe. Do generowania liczb losowych służy jednoargumentowa funkcja (random <losowa>), losująca liczbę całkowitą z przedziału od zera do n−1, gdzie n jest argumentem tej funkcji. Jest jeszcze bezargumentowa funkcja (randomize <startlos>). Funkcja ta inicjalizuje wbudowany generator liczb losowych – ustalając startową losową wartość na podstawie systemowego zegara. Przeważnie funkcja ta jest wykonywana automatycznie zawsze po uruchomieniu interpretera, jak np. w Logomocji. Dzięki temu nie otrzymujemy za każdym razem tych samych wartości losowych. Jeżeli wylosowaną liczbę chcemy użyć kilka razy, to musimy ją zapamiętać. Służy do tego celu dwuargumentowa procedura (make <przypisz, przyp>). Pierwszym argumentem procedury jest słowo oznaczające nazwę zmiennej, drugim argumentem jest dowolne wyrażenie. Przykładowo make "d :n nadaje zmiennej d wartośc zmiennej n. Utworzone w ten sposób nowe zmienne są zmiennymi globalnymi, czyli są dostępne w innych procedurach danego projektu. Poniżej przedstawiono procedurę random star :n, rysującą gwiazdę o promieniach losowej długości w zakresie od n − 1 do 2n − 1. Wywołanie procedury randomize nie jest w tym przypadku konieczne. to random_star :n randomize repeat 18 [let "d :n + random :n fd :d bk :d rt 20] end


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.