MOVENT LA TORTUGA


Xavier Valls. Facultat de Ciències de l'Educació. UAB

Una bona forma de començar a aprendre LOGO és intentant fer moure la tortuga. La tortuga és un punt que ve representat per un triangle, que ocupa una posició i té una orientació. L'estat de la tortuga (posició i orientació) es pot modificar i al moure-la, normalment deixa un traç. Instruccions com AVANÇA (AV), GIRA.DRETA (GD), GIRA.ESQUERRA (GE), i RECULA (RE), són paraules que LOGO coneix (són primitives) i fan que la tortuga modifiqui la seva posició o la seva orientació. Per exemple: AV 30, fa que la tortuga avanci 30 unitats, mentre que GD 60, fa que modifiqui la seva orientació girant un angle de 60 graus cap a la esquerra (en sentit horari).

AV 30

fa que la tortuga avanci 30 unitats.

GD 90

fa que modifiqui la seva orientació girant un angle de 90 graus cap a la seva dreta (gira en sentit horari).

Com s'haurà observat aquestes instruccions van seguides d'un nombre (un paràmetre) que indica el nombre d'unitats en que desitgem modifiqui el seu estat. És imprescindible al donar la instrucció especificar també el nombre d'unitats que volem modificar, sinó, la màquina grinyola. Comproveu-ho!.

EXERCICIS

1. Fes un dibuix utilitzant totes les instruccions abans esmentades. 2. Esbrina les dimensions de la finestra gràfica en unitats de la tortuga.

Si ara el nostre desig fos construir un quadrat de 75 unitats de costat podríem fer-ho amb la següent successió d'instruccions:

av 75
GD 90
AV 75
GD 90
AV 75
GD 90
AV 75

Evidentment, un inconvenient de fer dibuixos és que la pantalla queda bruta, una manera de netejar-la és utilitzar la primitiva, INICIA.DIBUIX (ID), que neteja tota la pantalla centra la tortuga i la deixa orientada cap a dalt. Fixeu-vos que aquesta primitiva no necessita cap paràmetre.

EXERCICI

3. Proveu de donar una seqüència d'instruccions per a que la tortuga dibuixi un triangle equilàter de 75 unitats de costat, un hexàgon regular de 50, un rectangle de 40 per 70, i un pentàgon regular de 60.

Suposo que si heu fet els exercicis que us demanava, estareu d'acord amb mi que escriure tota la seqüència d'instruccions és força pesat. Hi ha una instrucció, REPETEIX, que permet estalviar-se feina en casos com aquests en els que hi ha una sèrie d'instruccions que es repeteixen varies vegades. Per exemple en el cas del quadrat podríem dir:

 

REPETEIX 4 [AVANÇA 75 GIRA.DRETA 90]

Cal fer notar que en aquest cas la tortuga queda en el mateix estat que es trobava abans d'iniciar el dibuix, cosa que no passava la primera vegada doncs li faltava fer l'últim gir. Els moviments que deixen la tortuga en el mateix estat en que es trobava abans de començar s'anomenen transparents. La sintaxi d'aquesta primitiva seria doncs, primer la instrucció REPETEIX seguida de dos paràmetres, el primer, el nombre de vegades que s'han de realitzar les instruccions que es donen com a segon paràmetre, que han d'anar incloses entre claudàtors [ ].

EXERCICIS

4. Feu l'exercici 3 utilitzant la instrucció REPETEIX.

5. Utilitzant el repeteix fes una instrucció per dibuixar polígons regulars de 5, 7, 8, … costats 6. Investigueu vosaltres mateixos fent els dibuixos que desitgeu. Per exemple una casa pot ser un quadrat amb un triangle equilàter a sobre.

Potser necessitareu altres primitives com:

NOLLAPIS: a partir d'aquest moment la tortuga no deixa traç. LLAPIS: a partir d'aquest moment la tortuga deixa traç. GOMA: la tortuga quan passa per on està guixat ho esborra. ET: fa que la tortuga es vegi. AT: fa que la tortuga no es vegi. Si amb aquestes no en teniu prou mireu al glossari de primitives LOGO que hi ha al final d'aquest manualet.

PROCEDIMENTS i MODULACIÓ

No sé si us ho haureu plantejat, però seria interessant que així com tenim un cert nombre d'instruccions que LOGO coneix (les primitives), poder definir noves paraules. Així, cada vegada que volem fer un quadrat, en lloc d'haver de teclejar totes les instruccions, podríem definir què és un quadrat i aleshores quan desitgem fer un quadrat dient únicament QUADRAT, LOGO fes un quadrat. Això és possible, i és el que anomenem procediment. Per definir un procediment, per exemple quadrat, s'han de seguir els següents passos:

TO QUADRAT

REPETEIX 4 [AV 75 GD 90]

END

Aquí, TO és una primitiva de LOGO que indica que iniciem la definició d'un procediment, a continuació donem nom al procediment, (en el exemple QUADRAT) i després creem una nova línia amb un "return" on donem les instruccions que defineixen la nova paraula (en el nostre cas REPETEIX 4 [AV 75 GD 90]) i per indicar que ja hem donat totes les instruccions creem una nova línia on solament hi ha la primitiva END, que indica el final de la definició de la nova paraula. Fixeu-vos, que quan definiu un procediment, la màquina en lloc d'executar les instruccions del procediment comunica, amb un missatge, que s'ha definit la nova paraula. En general, la sintaxi per definir un nou procediment és: TO NOM (on NOM designa la nova paraula que definim i per tant ha de ser una sola paraula) El conjunt d'instruccions que defineixen el procediment (poden ser varies línies) END (per indicar la fi del procediment, la paraula sola en una nova línia )

 

EXERCICIS

7. Crea procediments per a les figures fetes anteriorment. 8. Practiqueu ara construint un triangle equilàter, un hexàgon regular, un rectangle, un pentàgon regular i polígons regulars de més costats. 9. Seguint el mateix procés series capaç de construir una circumferència.

Com podeu imaginar-vos la idea de poder definir noves paraules és un dels instruments que fan de LOGO una eina molt potent, però lligada en aquesta n'hi ha una altra que també és molt interessant. És tracta de la idea de modulació. Per explicar-ho en poques paraules, es tracta de donada una determinada feina (més o menys complicada), subdividir-la en petites subfeines (mòduls) cada una d'elles fàcil d'entendre i de realitzar. Un exemple pot fer-ho veure més clar: suposem que volem construir una casa. Abans hem dit que podíem pensar una casa com descomposta en un quadrat i un triangle equilàter. Per tant si disposem de les definicions de QUADRAT i TRIANGLE podem pensar en definir CASA a partir d'aquestes. Una possible forma seria:

 

TO CASA

QUADRAT

AV 75

GD 30

TRIANGLE

END

Si capteu la idea, ara podeu definir POBLE, primer a partir de la més simple de CARRER, i aquest com varies cases. Apa!, ja teniu feina. Si us voleu complicar la vida, podeu afegir-hi arbres. Un ARBRE pot ser un segment vertical (el tronc) i una circumferència (la capçada). Les cases es poden complicar amb portes, finestres, teulades, … Una altre suggeriment per investigar seria la definició de diferents estels, per exemple:

 

TO ESTEL 9 PUNTES

REPETEIX 9 [QUADRAT GD 40]

END

 

EXERCICI

10. Partint del procediment quadrat construeix una finestra, una bandera, composicions amb quadrats, una quadrícula, un anell de quadrats.

 

  PARÀMETRES I VARIABLES

Suposo que amb el que portem dit, ja haureu vist un cert inconvenient a la definició dels procediments que hem donat fins ara. Em refereixo que quan volem fer un quadrat, la paraula QUADRAT sempre el fa de la mateixa mida (en el nostre cas de 75). Bé, això té fàcil solució, LOGO permet parametritzar els procediments. Dos exemples serien:

 

TO QUADRAT :COSTAT

REPETEIX 4 [AV :COSTAT GD 90]

END

TO RECTANGLE :A :B

REPETEIX 2 [AV :A GD 90 AV :B GD 90]

END

Com podeu veure l'única variació en la nova definició de QUADRAT consisteix en que a continuació del nom del procediment hi hem afegit el nom d'un paràmetre (en el exemple COSTAT) que va precedit per dos punts. Els dos punts sempre han d'anar enganxats a l'esquerra del nom del paràmetre i no es poden oblidar. (Explicació del per què dels dos punts més endavant). I a més, ara després de la primitiva AVANÇA, hem substituït el 75 pel nom del paràmetre (COSTAT) amb els dos punts a l'esquerra, lògic, no? Ara quan cridem al procediment no n'hi ha prou amb dir QUADRAT si no que a més a més hem de dir de quina mida volem pel costat. RECTANGLE és un procediment amb dos paràmetres del que no crec que s'hagi de dir gaire res més.

 

EXERCICIS

11. Podeu redefinir tots els procediments definits anteriorment parametritzant-los.

12. Construir un procediment que dibuixi circumferències en funció del radi. Recordeu que la longitud és (2*p *radi)

13. Com ho faries per realitzar els següents dibuixos utilitzant les definicions parametritzades de quadrat, triangle, hexàgon i circumferència.

 

És possible que alguns de vosaltres alhora de fer l'exercici número 12, hagueu pensat que per fer una circumferència el que podíem fer era un polígon regular de molts costats (per exemple 360 aniria bé) i aleshores el seu perímetre seria 360*:c essent :c el valor del costat del polígon regular. Ara bé, si aquest perímetre ha de ser la longitud de la circumferència, és a dir, 2*3.14*:radi, això ens dóna una relació entre el valor del radi i el del costat del polígon regular, i si coneixem un dels valors podem determinar l'altre de forma immediata. En el nostre cas concret podem determinar el valor del costat :c del polígon regular en funció del valor del radi, :c = 2*3.14*:radi/360. I per tant el procediment que ens demanen es pot escriure:

TO CIRCUMFERENCIA :RADI

REPETEIX 360 [AV 2*3.14*:RADI/360 GD 1]

END

 

Fixeu-vos bé que un inconvenient d'aquest procediment és que cada vegada que s'executa l'avança ha de fer el càlcul. Seria més lògic que ens poguéssim apuntar aquest valor en algun lloc i després utilitzar-lo tantes vegades com volguéssim. Per altra banda, segurament en els dibuixos que es demanen en l'exercici número 13, una forma ràpida de fer el del quadrats seria:

QUADRAT 20

QUADRAT 30

QUADRAT 40

QUADRAT 50

QUADRAT 60

 

Ja es veu que si fóssim capaços d'anar variant el valor del costat podríem crear un procediment que utilitzes la primitiva REPETEIX.

Aquests dos problemes es poden solucionar amb la creació de variables i sabent com s'han d'assignar els valors a les variables. Per fer que una determinada variable quedi associada a un valor ho podem fer amb la primitiva ASSIGNA. Per exemple en el cas de la circumferència podem posar

ASSIGNA "COSTAT 2*3.14*:RADI/360

 

D'aquesta manera creem una variable a la que anomenem costat i li assignem el valor 2*3.14*:radi/360. Qüestions a tenir en compte: ASSIGNA és una primitiva que requereix dos paràmetres, el primer és el nom que donem a la variable (en el nostre cas costat) i fixeu-vos que per indicar que es tracta d'una paraula, a l'esquerra del nom (al començar a definir-lo) hi posem unes cometes " (únicament a l'esquerra); el segon és el valor que associem al nom (en el nostre cas 2*3.14*:radi/360). Ara el procediment circumferència controlat pel radi el podríem escriure

TO CIRCUMFERENCIA :RADI

ASSIGNA "COSTAT 2*3.14*:RADI/360

REPETEIX 360 [AV :COSTAT GD 1]

END

 

Fixeu-vos que quan vull utilitzar el valor de la variable costat (en el repeteix després del AV) enlloc de posar simplement costat, o bé posar-hi ", em refereixo al valor posant dos punts a l'esquerra, :costat. És la manera en que distingim el valor d'una variable, del nom de la variable. En LOGO quan volem indicar que ens referim a una paraula posem sempre a l'esquerra unes cometes (per exemple "costat), mentre que si ens volem referir al valor d'una determinada variable posem dos punts a l'esquerra (per exemple :costat). Recordeu que quan hem parametritzat el procediment quadrat hem deixat per més endavant el per què del dos punts a l'esquerra, doncs ara hauria d'estar clar. Posem els dos punts a l'esquerra per referir-nos al valor que té el paràmetre. Un altre exemple d'utilització de la primitiva ASSIGNA podria ser

ASSIGNA "nom "Jordi

 

i d'aquesta manera tindríem una variable nom que tindria per valor la paraula Jordi, i de manera similar podem associar amb una paraula qualsevol cosa que desitgem. Si, per altra banda, nosaltres volem saber el valor associat a una determinada variable n'hi ha prou amb posar just enganxats a l'esquerra del nom de la variable dos punts. Així:

ESCRIU :nom

 

ens retornarà Jordi. (La primitiva ESCRIU, tal i com indica el seu nom, escriu el que ve a continuació en la pantalla de text).

Bé, retornem ara a pensar en el nostre segon problema, un procediment que faci varis quadrats canviant el valor del costat. Si dins del repeteix (que m'ha de fer els diferents quadrats) hi afegeixo després de que hagi fet el quadrat una instrucció que canviï el valor del costat ja ho tindré, i per fer-ho n'hi ha prou en posar ASSIGNA "COSTAT :COSTAT + 10. Fixeu-vos que aquesta instrucció el que fa és assignar a la variable costat l'actual valor de la variable costat incrementat en 10 unitats. És a dir, modifica el valor de la variable. Per definir el procediment variisq que faci varis quadrats puc escriure

TO VARIISQ :N :COSTAT

REPETEIX :N [QUADRAT :COSTAT ASSIGNA "COSTAT :COSTAT+10]

END

 

Per acabar de veure com funciona aquest procediment, per una banda el paràmetre n que he posat serveix per indicar quants quadrats volem, i ara hem de pensar com funciona el que hi ha dins del repeteix. Suposem que donem la instrucció VARIISQ 5 20, el primer que farà serà iniciar el repeteix assignant a n el valor 5, després farà un quadrat de 20 de costat i l'ASSIGNA farà que costat valgui 30, per tant quan torni a fer quadrat ara en farà un de 30 i l'ASSIGNA farà que costat valgui 40, i així successivament fins que s'hagin fet els 5 quadrats.

 

EXERCICIS

14. Crea procediments amb els quals es puguin realitzar varis triangles, varis hexàgons i varies circumferències. Si vols pots afegir-hi un paràmetre que et permeti controlar l'increment d'una figura a la següent.

15. Crea procediments amb els quals es puguin realitzar varis quadrats centrats, varis hexàgons centrats i varies circumferències centrades com als dibuixos

16. Crea procediments per realitzar els següents dibuixos:

 

QÜESTIONS D'ARXIU

 

Toca ara donar un xic d'informació sobre el que s'anomena l'ESPAI DE TREBALL. L'ESPAI DE TREBALL, és una part de la memòria del ordinador on s'hi emmagatzemen les definicions dels procediments que hem definit en el transcurs de l'actual sessió de treball. Amb la primitiva PROCEDIMENTS es poden saber els noms dels procediments que hi ha en l'ESPAI DE TREBALL. Una confusió força corrent al començar a treballar amb LOGO consisteix en identificar l'ESPAI DE TREBALL amb l'EDITOR. En principi no tenen res a veure. Podem tenir uns quants procediments definits a l'ESPAI DE TREBALL i estar treballant en la definició d'uns altres totalment diferents en l'EDITOR sense que de moment s'hagin validat. Tot això té interès en el sentit de que si nosaltres volem guardar el procediments que hem fet, utilitzant l'opció GUARDA… del menú d'ARXIU, aquesta ens permetrà crear un arxiu en disc de tres formes diferents. Primera guardant els procediments de l'ESPAI DE TREBALL. Segona guardant l'editor en el que estiguem treballant. I tercera guardant la pantalla gràfica que desitgem.

Com acabo d'avançar si desitgem guardar el nostre treball en disc ho podem fer amb GUARDA… i si el que volem es utilitzar un arxiu que hem creat prèviament, ho podem fer amb la opció OBRE… del menú ARXIU, que o bé carrega a l'ESPAI DE TREBALL tots el procediments que hi ha a l'arxiu, o bé ens pot obrir l'arxiu com un EDITOR.

 

 

RECURSIVITAT I CONDICIONALS

 

En l'exercici número 13 us demanava de fer un dibuix que tingués varis quadrats encaixats utilitzant la definició parametritzada de quadrat. Això m'ha servit d'excusa per presentar-vos la primitiva ASSIGNA i veure com podíem dins d'un procediment modificar el valor d'una de les variables. Recordeu que la definició de varis quadrats era

TO VARIISQ :N :COSTAT

REPETEIX :N [QUADRAT :COSTAT ASSIGNA "COSTAT :COSTAT+10]

END

 

M'agradaria ara ensenyar-vos una altra manera de fer el mateix d'una forma molt diferent. De fet, recordeu que quan us van començar a ensenyar a definir, us deien sempre que el terme a definir no podia entrar en la definició, doncs resulta que en LOGO això es pot fer. Mireu la definició del següent procediment

TO VARIISQR :COSTAT

QUADRAT :COSTAT

VARIISQR :COSTAT+10

END

 

Fixeu-vos que a la tercera línia del procediment, tal i com hem avançat, aquest es crida en ell mateix. En principi, podríem pensar que això no hauria de funcionar de cap de les maneres, però si ho proveu (no ho feu encara) veureu que sí. De fet, tal com està definit el procediment no és del tot correcte doncs te un greu inconvenient. El sabeu reconèixer?

Si pensem com ha de funcionar el procediment ens adonarem ràpidament de quin és el problema. Suposem que cridem al procediment amb VARIISQR 20, com actuarà l'ordinador? Doncs primer de tot farà un quadrat de 20 i després com a segona instrucció el procediment es cridarà en ell mateix però ara amb un valor de costat 10 unitats més gran, és a dir, 30; per tant farà un quadrat de 30 i es cridarà en ell mateix amb 40, farà un quadrat de 40 i es cridarà amb 50, … Quin és el problema? Doncs que tal i com està definit aquest procediment no s'atura mai.

Si mai perdeu el control de la màquina i no sabeu com recuperar-lo, sempre podeu anar al menú DEBUG i demanar l'opció ATURA. Ara que ja sabeu què us pot passar podeu provar si aquest procediment funciona o no.

Quan un procediment es crida en ell mateix diem que tenim un procediment recursiu.

Per tal de poder controlar aquest procediment desbocat, és precís introduir en la seva definició alguna manera de controlar-lo. Una idea seria dir-li, si el costat es fa massa gran, para. Això es pot fer, i per fer-ho hem d’aprendre a utilitzar la primitiva condicional IF. Quan nosaltres la fem servir, en principi, la màquina espera tres paràmetres. El primer és la condició de control que volem imposar. La segona, el conjunt d'accions que volem que realitzi si es verifica la condició, posades entre claudàtors. I la tercera el conjunt d'accions que volem que realitzi si no es verifica la condició. Aquest tercer paràmetre no és estrictament necessari en el sentit de que si no li diem que faci res, evidentment no fa res. Per tant, la manera dir-li, si el costat es fa massa gran, atura't, seria

IF :COSTAT > 100 [aturat]*

 

suposant que 100 és un costat massa gran.

Ara el problema està en decidir on hem de posar aquest control. Hi ha diverses possibilitats. Una podria ser

TO VARIISQR :COSTAT

IF :COSTAT > 100 [aturat]

QUADRAT :COSTAT

VARIISQR :COSTAT+10

END

 

Una altra

TO VARIISQR :COSTAT

QUADRAT :COSTAT

VARIISQR :COSTAT+10

IF :COSTAT > 100 [aturat]

END

 

Cal fer notar que aquesta última no funciona. Comproveu-ho. Per què no funciona? Doncs perquè mai no s'arriba a executar la última instrucció doncs la tercera línia sempre fa recomençar l'execució del procediment. Ho enteneu? Sí, doncs ja està. No, doncs penseu-hi un xic més.

Una forma més correcta de definir aquest procediment, utilitzant els tres paràmetres de la condicional IF, seria

TO VARIISQR :COSTAT

QUADRAT :COSTAT

IF :COSTAT > 100 [PARA] [VARIISQR :COSTAT+10]

END

 

Fixeu-vos en dues coses: primer que he canviat aturat per PARA que és la primitiva correcta i després que ara no hi ha perill de que l'ordinador quedi desbocat, doncs el control o bé porta a la recursivitat, o bé fa que s'aturi.

Suposo que estareu d'acord amb mi que la manera de controlar VARIISQR per la mida del costat és un tant matusera. Seria millor poder dir quants quadrats volem que faci, no? El següent exemple ho fa

TO VARIISQR :N :COSTAT

QUADRAT :COSTAT

IF :N = 1 [PARA] [VARIISQR :N-1 :COSTAT+10]

END

 

Aquí podeu observar que la variable n s'utilitza com un comptador, que fins que no arriba a 1, que és quan es para, es va decrementant cada vegada en una unitat.

Per acabar amb la recursivitat voldria que investiguéssiu un xic amb les següents espirals

TO ESPIRAL :N :COSTAT

AV :COSTAT GD 90

IF :N=0 [PARA] [ESPIRAL :N-1 :COSTAT+2]

END

Fixeu-vos que n és el nombre de braços de l'espiral i que aquesta espiral és quadrada doncs sempre gira 90o. Podríem afegir un paràmetre g al procediment de forma que també poguéssim controlar l'angle de gir

TO ESPIRALG :N :G :COSTAT

AV :COSTAT GD :G

IF :N=0 [PARA] [ESPIRALG :N-1 :G :COSTAT+2]

END

 

Observeu què passa amb les següents instruccions ESPIRALG 20 120 3, ESPIRALG 20 60 3, ESPIRALG 20 45 3, …

 

EXERCICIS

17. Crea procediments de varis quadrats, triangles, hexàgons, circumferències, … tan agrupats en un vèrtex, com centrats, utilitzant ara la recursivitat.

18. Pots investigar tot tipus d'espirals que vulguis. Els angles no necessàriament han de ser divisors de 360. Si vols veure coses curioses t'aconsello que provis angles com 89º, 91º, 119º, 121º, …

 

ALGUNS EXEMPLES MÉS AVANÇATS

 

Un bon exercici per aprendre i veure com pot evolucionar un projecte en LOGO és el d'intentar que la màquina simuli la LOTO-6/49. És a dir, crear un procediment que doni 6 nombres diferents al atzar entre 1 i 49. Per fer això disposeu de la primitiva ATZAR n, aquesta retorna un nombre entre 0 i n-1. Si ho desitgeu ja podeu començar.

Un primer intent podria ser:

TO LOTO

REPETEIX 6 [ATZAR 49]

END

 

Aquest procediment té molts inconvenients. El primer és que tal i com està escrit no funciona, doncs la màquina es queixa dient que no sap què fer amb el primer dels nombres triats. Aquesta és una qüestió que cal tenir molt present en LOGO, quan nosaltres donem a la màquina una instrucció, aquesta, en general, ens dóna (retorna) un resultat que pot ser gràfic (com en el cas d'un quadrat), numèric o de molts diferents tipus. El que no podem oblidar mai, és que li hem de dir a LOGO què volem que faci amb el resultat obtingut. Si la instrucció és gràfica ja queda clar que ha de fer, però si nosaltres li diem, per exemple 13*7, la màquina ens contestarà que no sap què fer amb 91. Clar no li hem dit que n'ha de fer. Podríem haver donat qualsevol de les següents instruccions:

AV 13*7

ESCRIU 13*7

 

en el primer cas la tortuga avança 91 unitats, en el segon la màquina escriu 91. Per tant una primera modificació al nostre procediment LOTO seria:

TO LOTO

REPETEIX 6 [ESCRIU ATZAR 49]

END

 

Ara, la màquina fa una cosa similar a la que desitgem, però té certs inconvenients. Primer de tot escriu tots els nombres en columna, seria més còmode tenir tots els nombres en un rengle. Segon, si us heu fixat amb la definició de ATZAR haureu vist que la nostra definició de LOTO dóna els nombres entre 0 i 48 en lloc de 1 i 49. Tercer, i el més difícil de solucionar, si heu utilitzat varies vegades el procediment LOTO us haureu adonat que de vegades dins d'una mateixa tria de 6 nombres n'hi ha de repetits i això no pot ser.

Donat que el segon és molt senzill de solucionar n'hi ha prou en pensar que si la instrucció ATZAR 49 dóna nombres entre 0 i 48, la instrucció 1 + ATZAR 49 ens proporciona un nombre entre 1 i 49.

Anem doncs, pels altres dos. De fet, hi ha una idea que soluciona els dos alhora. Suposem que nosaltres escrivim el nombre en un paper i el posem en una caixa si aquest encara no hi és, i que quan en tenim 6 ensenyem el que hi ha dins de la caixa. Si poguéssim fer alguna cosa semblant ja estaríem, no? Doncs, som-hi.

La idea de la caixa es pot materialitzar en el que s'anomena una llista, que no és res més que una sèrie d'objectes LOGO entre dos claudàtors. Un exemple de llista ja conegut són el seguit d'instruccions que s'han d'executar quan utilitzem la primitiva REPETEIX. Un exemple, d'assignació d'una llista a una variable seria:

ASSIGNA "caixa [1 2 3 4]

 

on es crea una variable anomenada caixa que té per valor la llista amb els nombres 1, 2, 3, i 4.

Ara ja sabem construir una caixa, hem de poder-hi afegir els nombres. Per fer-ho podem utilitzar la primitiva POSPOSAT, la qual retrona una llista que és la llista original a la que s'hi ha afegit com a últim element l'objecte que li hem donat. Per exemple:

ESCRIU POSPOSAT 5 :caixa

 

ens dóna 1 2 3 4 5. En el nostre cas no ens interessa que ho escrigui, si no que la nova llista ha de ser precisament la nostra caixa, per tant haurem de posar:

ASSIGNA "caixa POSPOSAT 1+ATZAR 49 :caixa

 

Pot semblar un xic estrany, però si ho penseu un xic veureu que funciona. Per tant, de moment, el nostre procediment el podríem escriure:

TO LOTO

ASSIGNA "caixa [ ]

REPETEIX 6 [ASSIGNA "caixa POSPOSAT 1+ATZAR 49 :caixa]

ESCRIU :caixa

END

 

Falta potser explicar, la primera línia. Penseu-ho.

Si voleu veure com funciona aquest procediment podeu modificar-lo afegint un ESCRIU :caixa dins del REPETEIX, al final.

TO LOTO

ASSIGNA "caixa [ ]

REPETEIX 6 [ASSIGNA "caixa POSPOSAT 1+ATZAR 49 :caixa ESCRIU :caixa]

ESCRIU :caixa

FI

 

Com podeu veure de moment encara no sabem com fer la tria. Som-hi. La primitiva PERTANY? contesta si un determinat objecte és d'una llista o no. Per tant ens pot ser útil alhora de posar o no el paperet amb el nombre a la caixa. Per poder fer la tria el procediment ha de ser:

TO LOTO

ASSIGNA "caixa [ ]

REPETEIX 6 [TRIA]

ESCRIU :caixa

FI

TO TRIA

ASSIGNA "paperet 1+ATZAR 49

IF PERTANY? :paperet :caixa [TRIA] [ASSIGNA "caixa POSPOSAT :paperet :caixa]

END

 

Hi ha un parell de coses que potser s'han d'aclarir. Fixeu-vos amb la idea de modular el procediment LOTO en la repetició, de forma que sigui el procediment TRIA qui faci la feina. La primera línia d'aquest procediment de fet crea el paperet, i la segona posa el paperet a la caixa si no hi és, però que ha de fer si hi és, doncs molt fàcil triar-ne un altre.

Si es desitja es pot encara millorar aquest procediment fent que a més a més ordeni els nombres de la caixa, i en definitiva qualsevol millora que vulgueu.

 

Glossari de les principals primitives de LOGO

Gràfiques

apunta :x :y: retorna l'orientació amb que la tortuga apuntaria al punt (x,y) des de la seva posició actual.

 

at: fa invisible la tortuga.

av :l: fa que la tortuga avanci tantes unitats com indica l.

centre: fa que la tortuga es situï en el centre de la finestra gràfica mirant cap amunt.

et: fa visible la tortuga.

fespos :x :y: mou la tortuga al punt de coordenades x i y.

fesx :x: mou la tortuga al punt d’abscissa x, mantenint el valor de l'ordenada.

fesy :y: mou la tortuga al punt d'ordenada y, mantenint el valor de l’abscissa.

gd :g: fa que la tortuga giri en sentit horari tants graus com indica g.

ge :g: fa que la tortuga giri en sentit antihorari tants graus com indica g.

goma: fa que a partir d'aquest instant la tortuga esborri quan passi per punts pintats.

id: neteja la finestra gràfica i centra la tortuga.

llapis: fa que la tortuga a partir d'aquest instant deixi un rastre.

neteja: neteja la finestra gràfica deixant la tortuga en la seva posició actual.

nollapis: fa que la tortuga a partir d'aquest instant no deixi cap rastre.

orienta :o: fa que l'orientació del la tortuga sigui o.

orientacio: retorna l'orientació actual de la tortuga.

re :l: fa que la tortuga reculi tantes unitats com indica l.

xcoor: retorna l’abscissa de l'actual posició de la tortuga.

ycoor: retorna l'ordenada de l'actual posició de la tortuga.

 

Numèriques

arctg :r1 :r2: retorna l'angle que té per tangent r1/r2.

 

arrel :n: retorna l'arrel quadrada del nombre n.

arrodonit :n: retorna el enter més proper al nombre n.

atzar :n: retorna un nombre a l'atzar entre 0 i n-1

cos :a: retrona el valor del cosinus de l'angle a.

exp :n: retorna el valor de la funció exponencial de base e de n.

ln :n: retorna el valor del logaritme neperià de n.

partentera :n: retorna l'enter més petit o igual a n.

pi: retrona el valor de pi.

quocient :a :b: retorna el quocient enter de la divisió de a per b.

residu :a :b: retorna el residu enter de la divisió de a per b.

sin :a: retrona el valor del sinus del angle a.

 

Manipulació de paraules i llistes.

anteposat :obj :ll: retrona la llista que té per primer element obj i la resta de la llista és ll.

 

compta :ll: retorna el nombre d'elements de la llista ll.

element :i :ll: retorna l'element que ocupa la posició i de la llista ll.

posposat :obj :ll: retrona la llista que té per últim element obj i la resta de la llista és ll.

primer :ll: retorna el primer element de la llista ll.

senseprimer :ll: retrona la llista que s'obté de suprimir el primer element de la llista ll.

senseúltim :ll: retrona la llista que s'obté de suprimir l'últim element de la llista ll.

últim :ll: retorna la llista que té com a únic element l'últim de la llista ll.

 

Entrada i sortida

escriu :p: escriu en la finestra de text el contingut de p.

 

llegeixcaracter: retorna el primer caràcter que s'ha picat al teclat.

llegeixllista: retorna com una llista tots els objectes que s'han teclejat fins al primer return.

 

Control

espera :n: crea una pausa d'execució de n*1/60 segons.

 

para: retorna el control d'execució al procediment que l'ha cridat.

repeteix :n :ll: repeteix tantes vegades com indica n les instruccions de ll.

retorna :obj: para l'execució del procediment en curs retronant obj al procediment que l'ha cridat.

 

Primitives d'assignació

assigna "nom :obj: crea una variable a la que anomena nom i li assigna com a contingut obj.

 

valor "nom: retorna el valor de la variable nom

valor? :nom: retorna true o false segons si hi ha una variable anomenada nom o no.

 

Condicionals

if :cond :cons :alter: si la condició cond és certa s'executen les instruccions de cons en cas contrari les de alter.

 

igual :l1 :l2: retorna true o false segons sigui cert si els continguts de l1 i l2 són iguals o no.

llista? :ll: retorna true o false segons sigui cert si el contingut de ll és una llista o no.

nombre? :n: retorna true o false segons sigui cert si el contingut de n és un nombre o no.

paraula? :p: retorna true o false segons sigui cert si el contingut de p és una paraula o no.

pertany? :obj :ll: retorna true o false segons sigui cert si obj és un element de la llista ll o no.

primitiva? :nom: retorna true o false segons si nom correspon a la paraula assignada a un procediment o no.

procediment? :nom: retorna true o false segons si hi ha un procediment anomenat nom o no.

vuit? :ll: retorna true o false segons sigui cert si la llista ll és vuida o no.

 

Manipulació de l'àrea de treball

escriudef :obj: dóna la definició del procediment obj.

 

oblida :obj: esborra de l'àrea de treball obj.

oblidatot: esborra de l'àrea de treball tots els procediments que s'han definit.

procediments: escriu a la finestra de text el nom de tots els procediments que hi ha a l'àrea de treball.