Вы находитесь на странице: 1из 72

:: A1 :: C'est parti

Tapez dans la partie basse (je ne le prciserai plus, vous tes prvenus) de la fentre de l'diteur la phrase suivante : Display dialog "Bonjour" buttons {"Merci"} Promis, je vous explique bientt ce que je vous fais faire, mais d'abord cliquez sur le bouton "Vrifier" (le plus droite). Si vous obtenez un message "Erreur de syntaxe", relisez-vous, vous avez srement mal recopi la phrase. Les accolades se font avec la touche option (alt) enfonce puis la touche "(" ou ")". Les guillemets et les espaces sont aussi importants. Si vous les copiez partir de ce fichier, ils peuvent tre mal transcrits, je prcise donc qu'il s'agit du guillemet neutre, qui ne tourne ni droite ni gauche. Cliquez nouveau sur "Vrifier" jusqu' ce qu'il n'y ait plus de messages d'erreur. Si tout est bon, le texte que vous avez tap change de police de caractre, vous tes prt pour votre premire exprience : cliquez sur le bouton "Excuter". Que s'est-il pass ? Un message vous a dit "Bonjour", puis vous avez cliqu sur le bouton "Merci". Si vous connaissez un peu d'anglais, la ligne de commande que vous avez tape devient trs claire. Voici une dcomposition logique de cette ligne. Ne la tapez pas ainsi dans l'diteur de script, cela ne fonctionnerait pas car chaque instruction doit tre crite sur une seule ligne pour tre comprise par AppleScript. Nous verrons plus tard comment faire pour dcouper des lignes trop longues. Ici, je veux juste mettre les morceaux en vidence. display dialog "Bonjour" buttons {"Merci"} :: A2 :: Je les reprends un par un : display est une commande. C'est une instruction que l'on demande au programme d'effectuer. L'instruction display permet d'afficher en l'occurrence un message. dialog "Bonjour" et Buttons {"Merci"} sont 2 paramtres. Ils modifient l'effet produit par l'instruction. Ils sont construits tous les 2 sur le mme principe : dialog : c'est le nom du paramtre. Je l'appellerai l'identificateur. Il ne faut pas faire de faute en le tapant dans le code sinon, a ne marche pas. Notez au passage qu'AppleScript est trs tolrant sur l'usage des majuscules, mais ce n'est pas le cas de tous les langages. Le paramtre dialog sert dfinir le texte du message qui sera affich. Ce paramtre. est obligatoire et il doit venir en premier aprs l'instruction Display. "Bonjour" est le paramtre proprement dit. On peut dire aussi la valeur du paramtre "dialog". Ici, vous pouvez mettre ce que vous voulez, c'est vous qui dcidez de la valeur du paramtre. La seule contrainte concerne la faon d'crire pour qu'AppleScript sache qu'il s'agit de texte et non pas de code : il est impratif de l'crire entre guillemets. Sinon, si vous faites une faute de frappe, cela n'a pas d'effet sur le fonctionnement de votre programme. buttons {"Merci"} : c'est un autre paramtre. Il sert dfinir le ou les noms de boutons qui vont apparatre dans la fentre de message. buttons est le nom du paramtre {"Merci"} est le paramtre lui-mme, c'est--dire que c'est vous qui dcidez de sa valeur. Il est inscrit entre deux accolades parce qu'il s'agit d'une liste (Exemple : {1,2,3} est une liste qui contient les 3 chiffres 1, 2 et 3). S'il faut utiliser une liste ici (et cela mme si on ne se sert que d'un bouton) c'est parce qu'il peut y avoir jusqu' trois boutons dans un message. Comme le nom des boutons est de type texte, chaque nom est inscrit entre guillemets, tout comme "Bonjour". Pour afficher plusieurs boutons dans notre fentre de message, il suffit de mettre plusieurs textes dans la liste en les sparant par une virgule. Voici donc un autre exemple de message, testez-le, puis amusez vous crer quelques messages diffrents :

Display dialog "Quel temps fait-il ?" buttons {"Il pleut"," Il neige","Il fait beau"}

:: A3 :: Je donne la parole

L'un des paramtres les plus utiliss de l'instruction display dialog est default answer Il s'utilise comme le montre cet exemple :
Display dialog "Quelle est votre date de naissance ?" default answer ""

Testez cette ligne (n'oubliez pas les guillemets la fin), vous dcouvrez qu'une zone de texte a t incorpore dans la fentre de message. L'utilisateur peut donc entrer une rponse libre pltot que de choisir parmis 3 boutons. Default answer est l'identificateur du paramtre, "" est le paramtre lui mme. Mais qu'est-ce que c'est que ce "" ? C'est tout simplement pour dire qu'il s'agit de texte, mais sans texte. En fait on peut mettre entre les guillemets une rponse par dfaut qui s'affichera dans la zone de texte ditable. Par exemple :
Display dialog "Quelle est votre date de naissance ?" default answer "jour/mois/anne"

Dans ce cas, il s'agit d'une petite aide pour montrer l'utilisateur comment entrer sa rponse. On peut aussi prsenter une information par dfaut. Imaginons que l'on pense que l'utilisateur s'appelle Jean , on pourrait alors crire.
Display dialog "Quelle est votre prnom?" default answer "Jean"

S'il s'agit bien de Jean, il n'aura plus qu'a cliquer sur le bouton OK, si c'est quelqu'un d'autre il pourra entrer son propre prnom. Mis a part le paramtre "dialog" qui est obligatoire et qu'il faut crire en premier, les autres paramtres peuvent tre omis ou cumuls, leur ordre n'ayant pas forcment de l'importance. Par exemple, les deux lignes suivantes sont quivalentes :
display dialog "Combien font : 4 + 8 ?" buttons {"Je ne sais pas", "Je sais"} default answer "Tapez votre rponse ici" display dialog "Combien font : 4 + 8 ?" default answer "Tapez votre rponse ici" buttons {"Je ne sais pas", "Je sais"}

:: A4 ::>D'autres paramtres de l'instruction display dialog.

giving up after 2 : permet de faire disparatre le message aprs un temps de 2 secondes. giving up after est l'identificateur du paramtre 2 est le paramtre lui-mme. Bien sr, vous pouvez le remplacer par le chiffre que vous voulez. Il correspond au nombre de secondes pendant lesquelles le message s'affiche. Aprs ce dlai, la fentre du message se ferme d'elle mme. Voici un exemple :
display dialog "Ce message va bientt disparatre" buttons {"OK"} giving up after 3

default button "OK" : permet d'activer l'un des boutons prsents. Il est alors possible de rpondre au message par la touche entre ou retour chariot. default button est l'identificateur du paramtre "Ok" est un exemple de nom de bouton. Attention, il faut que ce bouton ait t dclar dans la liste des boutons. Exemple :
display dialog "Voulez-vous devenir riche ?" buttons {"Non","Oui"} default button "Oui"

Notez au passage que le paramtre buttons est entre parenthses parce qu'il y a plusieurs boutons, alors que le paramtre default buttons n'en a pas, puis qu'il n'y a qu'un bouton par dfaut. with icon 1 : permet d'afficher une icne dans la fentre de dialogue. with : pas tout fait un identificateur de paramtre. En fait with est utilis pour introduire certains objets en tant que paramtres. Si vous ne voyez pas la subtilit, a n'a aucune importance. Retenez

juste qu'il faut associer with et icon Icon : vous savez ? Les petits dessins comme ceux des dossiers des fichiers grce with, ils peuvent devenir paramtres de l'instruction display dialog. 1 le paramtre lui-mme. Vous pouvez mettre le chiffre que vous-voulez, mais je vous prviens quand mme : il n'y a que trois icnes de disponibles. Ces trois icnes sont : 0 = Icon stop, 1 = icon message, 2 = icon attention. Exemple :
display dialog "Cette action est interdite." buttons {"J'ai compris"} with icon 0

AppleScript, toujours trs tolrant permet d'utiliser le nom des icnes la place du numro. Ces noms sont en anglais, ce qui ne nous avantage pas trop, nous les francophones. Je n'ai jamais russi a m'en rappeler par cur et je n'utilise que les numros, mais voici la liste si vous prfrez les apprendre par cur : 0=stop, 1=note, 2=caution. Exemple :
display dialog "Cette action est interdite." buttons {"J'ai compris"} with icon stop

:: B1 :: Avoir de la mmoire
Parler l'utilisateur, c'est trs directif. Le but de la programmation, c'est le contraire : couter l'utilisateur et faire ce qu'il dsire. Au fil de vos essais vous avez peut-tre vu s'ouvrir la fentre rsultat. Sinon, ouvrez cette fentre (elle se trouve dans le menu Commande, choisissez Afficher le rsultat ) et faites quelques essais d'instructions display dialog en utilisant les diffrents paramtres que nous avons vus au chapitre prcdent. Vous allez voir passer dans la fentre ce que votre programme entend a chaque fois qu'un message display dialog est affich. C'est bien ! Vous avez donc entendu l'utilisateur. Mais votre oreille, ou plutt celle de votre programme, reste distraite. Aussitt une nouvelle instruction lance, le rsultat prcdent est irrmdiablement perdu. Zut, votre ordinateur a la mmoire courte, il va falloir lui apprendre retenir. Pour cela, nous avons besoin d'un morceau de mmoire vive. Dans certains langages, je pense surtout au C, la gestion de la mmoire est difficile car trs rglemente. L'avantage, c'est que l'on en gaspille moins, ce qui permet la plupart du temps d'obtenir un programme plus rapide. En AppleScript, c'est transparent pour le programmeur : l'avantage, c'est que vous allez vous y retrouver trs vite. :: B2 :: Un petit bout de mmoire SVP Pour tre capable d'crire quelque chose dans la mmoire de l'ordinateur, c'est trs facile. Il suffit de choisir un nom et de mettre quelque chose dedans. AppleScript devine que vous voulez un morceau de mmoire, et vous permettra de retrouver son contenu par la suite en appelant son nom. Cette instruction s'appelle set . Tapez donc l'exemple suivant et testez-le, nous allons le dcortiquer ensuite. J'crirai partir de maintenant les variables en bleu. set texteEnMemoire to "Bonjour" display dialog texteEnMemoire La premire ligne : set texteEnMemoire to "bonjour" permet d'obtenir un morceau de mmoire qui s'appellera texteEnMemoire et place dedans le texte "Bonjour". La deuxime ligne : display dialog texteEnMemoire Nous la connaissons, mais cette fois, au lieu de taper nous-mmes le texte entre guillemets nous passons le nom du morceau de mmoire comme paramtre principal de la fonction. L'instruction display dialog se dbrouillera toute seule pour aller chercher le texte qui se trouve dans le morceau de mmoire que nous avons appel texteEnMemoire. Pour tre sr que vous ayez bien compris, voici un tout petit pige. tapez ces 2 lignes de code et essayez de deviner ce qui va s'afficher avant de le tester. set Bonjour to "Au revoir" display dialog "Bonjour" buttons {Bonjour} Vous avez suivi ?

Trs bien. Pour utiliser le mme vocabulaire que tous les programmeurs, sachez que ce genre de petit bout de mmoire s'appelle une variable. Elle peut contenir du texte, des chiffres, des listes... tout ce qui peut tre mis dans un morceau de mmoire vive et mme d'avantage. Les rgles pour choisir un nom une variable sont simples : ne pas commencer par un chiffre et ne pas mettre d'espaces, d'accents, ou de signes particuliers. Une autre rgle restrictive : vous ne pouvez pas utiliser les mots utiliss par AppleScript. Par exemple, vous ne pourrez pas crer une variable qui s'appellerait set, display, dialog ou giving. Evidemment vous ne connaissez pas encore tous les mots utiliss par AppleScript, mais en choisissant des noms en franais et en leur ajoutant un article devant, vous ne devriez pas rencontrer de problmes. :: B3 :: Et notre message dans tout a ? Maintenant que nous savons comment conserver quelque chose en mmoire, rien de plus facile que de retenir la rponse d'un utilisateur face a un message. Exemple : display dialog "Choisissez une lettre :" buttons {"A", "B", "C"} set laReponse to the result La premire ligne, vous devriez la comprendre tout seul maintenant, sinon, repartez du dbut et faites un maximum d'efforts pour comprendre. Si cela ne vient pas... Mmmmh, finalement, je ne peux pas grand-chose pour vous. Tentez les cours particuliers ? La deuxime ligne contient trs peu de neuf : Set laReponse to the result : on met dans un morceau de mmoire (une variable) qui s'appellera laReponse le rsultat de notre message. Tant que nous ne changerons pas le contenu du morceau de mmoire laReponse nous pourrons donc retrouver la rponse de l'utilisateur et agir en consquence. The result est aussi une sorte de variable, rserve AppleScript pour renseigner le programmeur sur le rsultat de beaucoup d'instructions. cause de cela, elle peut avoir des contenus trs varis. Nous allons bientt dcouvrir tous les rsultats possibles de l'instruction display dialog. Mais avant, ajoutons une troisime ligne notre programme pour vrifier que nous tenons bien en mmoire le rsultat. Attention, ne paniquez pas, cette ligne provoque un message d'erreur, c'est voulu. Je vous conseille de procder ainsi quand vous ne connaissez pas quelquechose. En essayant de l'afficher dans un message d'alerte, parfois a peut marcher, et sinon, le message d'erreur est souvent trs instructif. display dialog "Choisissez une lettre :" buttons {"A", "B", "C"} set laReponse to the result display dialog laReponse Impossible de dsigner {button returned :"?"} comme string Voil ce que vous obtenez comme message d'erreur, avec la lettre du bouton que vous avez choisi au lieu du "?". Notez, que l'on progresse : le bouton choisi apparat bien dans le message d'erreur. Ce que nous ne savons pas faire, c'est rcuprer seulement cette lettre. Ce que l'on devine dans ce message d'erreur, c'est que notre variable s'crit en AppleScript : {button returned :"?"} Voici comment a fonctionne... :: B4 :: Exploiter le rsultat Je vous l'ai dit, dans un rsultat, il peut y avoir beaucoup de choses, car le rsultat sert d'autres instructions et rapporte toutes les actions faites par l'utilisateur. C'est pourquoi le rsultat est construit comme une liste, (vous savez, celle que l'on utilise pour dfinir les boutons de l'instruction display dialog) : des lments spars par des virgules, encadrs par des parenthses. Dans notre rsultat, nous avons donc seulement 1 lment, puis qu'il n'y a pas de virgules. Ce que nous avons en plus c'est un : . Ce ":" est l pour nous montrer qu'AppleScript a dj pris soin de nous et a demand un morceau de mmoire pour chaque information contenue dans le rsultat. Comme son nom l'indique ceux qui parlent anglais, le morceau de mmoire qui nous intresse s'appelle button returned (oui, AppleScript se permet de nommer des morceaux de mmoire avec des espaces dedans, mais ne soyez pas jaloux. Je vous

expliquerai peut-tre un jour pourquoi). Pour accder au bouton retourn par l'utilisateur dans notre message il faut donc demander le returned button du rsultat. En anglais : display dialog "Choisissez une lettre :" buttons {"A", "B", "C"} set laReponse to the result display dialog button returned of laReponse Voil. Nous savons parler l'utilisateur et nous savons galement l'couter. Notez au passage (si vous tes l'aise, sinon ne vous encombrez pas) que ceci fonctionne aussi : display dialog "Choisissez une lettre :" buttons {"A", "B", "C"} display dialog button returned of the result car the result n'a pas encore t modifi par l'utilisation d'une autre instruction. Mais il est plus sage d'utiliser une variable pour stocker un rsultat aussi longtemps que vous en aurez besoin. Notez aussi (si vous insistez vraiment) que l'on peut crire ces deux lignes sur une seule : display dialog button returned of (display dialog "Choisissez une lettre :" buttons {"A", "B", "C"}) Cela fonctionne car AppleScript value en premier ce qui se trouve entre parenthse. Mais travailler ainsi donne mal la tte quand il faut se relire quelques jours plus tard. Croyez-moi, il vaut mieux parfois deux lignes videntes qu'une ligne douteuse. Pensez surtout qu'un vrai programme contient beaucoup de lignes et qu'il faut retrouver facilement chaque action quand on veut la modifier. Toutefois si vous vous sentez l'aise, vous pouvez affecter le rsultat d'un display dialog une variable dans la mme ligne sans trop perdre en lisibilit : set laReponse to (display dialog "Choisissez une lettre :" buttons {"A", "B", "C"}) Le display dialog se trouvant entre parenthse, il est valu d'abord par AppleScript, et la valeur retourne (dans notre cas le rsultat) est range dans un morceau de mmoire qui s'appellera laReponse. :: B5 :: De la comprhension dans l'coute Il vous manque un peu de vocabulaire pour bien savoir couter la rponse d'un display dialog. Vous avez dj vu que la rponse est une liste un peu particulire car chaque lment de la liste est dj stock dans une variable qui porte un nom prcis. Cette sorte de liste s'appelle un enregistrement, et chaque lment s'appelle une proprit. Retenez juste qu'il s'agit d'une variable qui porte un nom, sauf que c'est AppleScript qui choisit ce nom et non pas vous. Voici un rcapitulatif des noms de ces variables et quoi elles correspondent : Button returned : c'est le nom du bouton qui a t slectionn par l'utilisateur. Il y a toujours cette variable, mme si l'utilisateur n'a pas cliqu sur un bouton (voir plus loin " gave up " ). Dans ce cas, button returned vaudra "" c'est--dire rien. Text returned : le texte que l'utilisateur a tap dans la zone de saisie. Si vous n'avez pas demand de zone de saisie (le paramtre default answer), cette variable n'existe pas dans la rponse. Gave up : cette variable n'apparat que si vous avez utilis le paramtre "giving up after". La valeur de gave up peut tre "false" ou "true". False et true veulent dire respectivement faux et vrai. Si gave up vaut false, cela veut dire que l'utilisateur a eu le temps de cliquer sur un bouton. Si gave up vaut true, c'est le contraire. Le temps accord par le paramtre "giving up after" a t dpass et la fentre du message s'est referme d'elle mme. Dans ce cas la valeur de "button returned" sera de "". Par contre, la valeur de "text returned" correspondra a ce que l'utilisateur aura eu le temps de taper. Pour un programmeur, quelque chose qui peut tre vrai ou faux s'appelle un boolen. Un cas particulier : annuler. Vous avez peut-tre remarqu que si vous ne prcisez pas le paramtre "buttons" d'un display dialog, il s'affiche en standard deux boutons : "OK" et "Annuler". OK est le bouton par dfaut, le bouton "Annuler", lui, semble sans intrt. Dtrompez-vous car ce bouton possde une particularit qui peut tre la fois une aide ou une source d'embtement. Il est pratiquement aussi puissant qu'une

instruction quitter : il fait totalement oublier au programme la commande display dialog, ce qui veut dire qu'il n'y a pas de rponse, et de plus il arrte le fonctionnement du programme, si l'on ne le maitrise pas. Comme ce n'est pas encore du niveau de ce cours, nous attendrons un peu avant de l'utiliser, sauf dans des essais sans importance. :: Bientt :: Discutons, donc... Puisque nous savons parler et couter, en conjuguant les deux nous devrions russir discuter avec l'utilisateur. J'ai beaucoup parl dernirement, mais c'est promis, la prochaine fois je reviendrai vers vous avec quelques exemples pratiques. Vous verrez, nous travaillerons sur un code d'au moins 10 lignes de long et vous allez tout comprendre... Si , si. J'ai confiance en vous

:: C1 :: Exerons nous au dialogue


Commenons par de la pratique : le propos du code qui suit est de demander l'utilisateur de parier sur un chiffre compris entre 1 et 8, puis sur la valeur paire ou impaire du numro sortant : -- Dbut du code -- Demandons son nom l'utilisateur -- Le rsultat est stock dans la variable prenomUtilisateur display dialog "Quel est votre prnom ?" default answer "" set prenomUtilisateur to text returned of the result -- fabriquons le texte de la prochaine question en incluant le prnom de l'utilisateur : set nouveauTexte to prenomUtilisateur & ", choisissez un nombre entre 1 et 8" -- posons la question -- et stockons la dans une variable choix1Utilisateur display dialog nouveauTexte default answer "" set choix1Utilisateur to text returned of the result -- demandons maintenant le pari pair/impair de la personne -- de la mme faon, prparons la question puis posons-la, pour enfin la stocker : set nouveauTexte to prenomUtilisateur & ", choisissez entre pair et impair :" display dialog nouveauTexte buttons {"Pair", "Impair"} set choix2Utilisateur to button returned of the result -- voici le moment d'afficher les informations recueillies -- construisons le texte de notre message, puis affichons-le set ligneA to prenomUtilisateur & ", voici vos paris :" & return set ligneB to "Premier pari : " & choix1Utilisateur & return set ligneC to "Deuxime pari : " & choix2Utilisateur & return display dialog ligneA & ligneB & ligneC buttons {"Rectifier", "Valider"} default button "Valider" -- Fin du code Voil. J'espre que vous ne trouvez pas cela trop long, je vous assure qu'il n'y a rien d'effrayant. Il y a dans ce qui prcde 12 lignes de code et 10 lignes de commentaires. Qu'est-ce qu'un commentaire ? Comme son nom l'indique, c'est juste du texte, en langage courant qui est introduit dans le code pour l'expliquer au fur et mesure. Pour qu'AppleScript ne cherche pas interprter un commentaire comme du code, il faut simplement commencer par crire deux tirets avant le commentaire. Tout le texte qui suivra les "-" jusqu' la fin de la ligne sera ignor pendant le droulement du script. videmment, les commentaires sont trs utiles pendant une formation, pour expliquer du code, mettre en valeur une ligne. Mais les "bons" dveloppeurs utilisent aussi les commentaires, souvent avec abondance. Les commentaires permettent de revenir lire son code, des semaines, des mois plus tard. Sans commentaires, un code complexe devient trs difficile relire ou adapter de nouveaux besoins par exemple. Il y a dans ces lignes de code, trs peu de choses nouvelles. Faites l'effort de bien les lire. En vous aidant des

commentaires, je pense que vous vous y retrouverez. Je dtaille les points nouveaux tout de suite aprs. :: C2 :: Un peu de dtails en plus Voici quelques explications supplmentaires. Les deux premires lignes (je ne compterai pas les lignes de commentaires, seulement les lignes de code) n'ont aucun mystre pour vous. C'est l'affichage d'un message dornavant familier, le texte tap par l'utilisateur tant stock dans une variable que j'ai choisi d'appeler prenomUtilisateur. La troisime ligne contient du nouveau : l'oprateur &. Il permet de "coller" deux textes bout bout. Le nom barbare utilis en programmation est "concatnation", je ne suis mme pas sr de l'orthographe exacte. Si j'entre "Didier" comme rponse la premire question, l'effet produit par cette ligne est de crer une variable nouveauTexte qui contient le texte "Didier, choisissez un nombre entre 1 et 8". L'oprateur "&" permet donc de crer des phrases en associant des morceaux de textes, que ce soit des textes statiques (taps entre guillemets dans le code) ou des variables de type texte. Les lignes 4 et 5 sont, dans leur principe, identiques aux lignes 1 et 2. Remarquez au passage, que j'utilise chaque fois la mme variable "nouveauTexte" pour prparer le texte du message d'alerte. C'est une faon d'conomiser les morceaux de mmoire. Notre script est trs simple, et demander une nouvelle variable pour chaque texte ne causerait pas de souci de fonctionnement. Mais je vous conseille de vous habituer trs vite penser "conomie de mmoire". La vitesse des applications en dpend parfois, et jusqu' Mac OS 9, le mauvais partage de la mmoire par le macintosh est assez pnalisant pour que l'utilisateur attende cet effort de votre part. Les lignes 6, 7 et 8 sont identiques aux lignes prcdentes, sauf que l'on stocke le nom du bouton cliqu au lieu du texte saisi par l'utilisateur. Mais a, vous l'aviez retenu de la leon prcdente, n'est-ce pas ? ;-) Arrivent ensuite 3 lignes qui sont construites sur la mme structure. On y retrouve des morceaux de texte statiques, les noms des variables que nous avons utilis, plus un mot du vocabulaire d'AppleScript : "return". Return, c'est le nom AppleScript d'un retour la ligne. En plaant un "return" aprs un texte, on va tout simplement a la ligne. Dans ces 3 lignes, nous construisons les lignes de notre futur message, ce que l'on affiche la ligne 12. Voyez, vous aviez presque tout compris tout seul... :: C3 :: La mme chose, mais dite autrement Les lignes qui commencent par "set ligne1..." "set ligne2" etc. pourraient tre crites autrement. Par exemple, sur une seule ligne : display dialog prenomUtilisateur & ", voici vos paris :" & return & etc. Je vous laisse essayer tout seul. La longueur de la ligne entrane une difficult de relecture. Il est toutefois possible d'crire une seule ligne (de code) sur plusieurs lignes de l'diteur. Cela ncessite un peu d'explications. Rappelez-vous, je vous en ai dj parl : AppleScript considre tout ce qui est entre deux retours chariot (une ligne de code, quoi) comme une seule et mme action raliser. Pour crire une commande sur 2 lignes, ou plus, il faut utiliser le caractre que vous obtiendrez en appuyant simultanment sur les touches option (alt) et retour chariot. Ce caractre est un retour chariot un peu diffrent, que l'on appelle juste "une fin de ligne". Grce ce caractre, on peut crire indiffremment : Set maVariable to "Mon texte" -- ou : set maVariable to "Mon texte" Essayons d'crire la fin du code prcdent de cette faon : set nouveauTexte to prenomUtilisateur & ", voici vos paris :" & return & "Premier pari : " & choix1Utilisateur & return & "Deuxime pari : " & choix2Utilisateur & return display dialog nouveauTexte buttons {"Rectifier", "Valider"} default button "Valider"

Vous avez remarqu peut-tre (je l'espre mme) que j'ai plac les "" juste aprs les "return". Cela n'a rien d'obligatoire, mais cela permet de bien visualiser les passages la ligne et donc de faciliter la relecture. On peut galement "tricher" ainsi : set nouveauTexte to prenomUtilisateur & ", voici vos paris : Premier pari : " & choix1Utilisateur & " Deuxime pari : " & choix2Utilisateur display dialog nouveauTexte buttons {"Rectifier", "Valider"} default button "Valider" Je dis tricher, parce que cela ne me semble pas trs orthodoxe, mais certains le font et cela fonctionne, alors je vous le donne. Le principe est facile comprendre, la relecture est plus difficile. Puisqu'AppleScript considre tout ce qui se trouve entre guillemets comme du texte (c'est ce que l'on appelle du texte statique), il suffit d'aller la ligne "entre" les guillemets. Vous remarquerez donc qu'il n'y a pas de guillemets la fin de la premire ligne et que le texte se poursuit sur la ligne suivante. Par contre, on trouve un guillemet en fin de la ligne 2. Ce qui est trompeur, c'est qu'il s'agit du dbut du texte de la ligne suivante. Perturbant, non ? A l'inverse, et pour la mme raison, le caractre "" ne peut pas tre plac l'intrieur d'un texte statique, AppleScript le reconnatrait alors comme du texte et l'afficherait dans la fentre d'alerte, ce qui n'est pas l'effet recherch. Essayez ce code pour voir de vos yeux ce qui se passe. set maVariable to "Mon texte" display dialog maVariable A vous de choisir votre mthode prfre... la premire est plus simple, mais gourmande en variables (ligne1, ligne2, ligne3). La troisime est perturbante. Vous l'aurez compris, mon choix va vers la deuxime. :: Bientt :: Je pose mes conditions... Certes, nous savons maintenant discuter. Mais notre code laisse l'utilisateur beaucoup de possibilits d'entrer des valeurs qui pourraient gnrer ensuite des erreurs. Par exemple si l'utilisateur entre du texte au lieu du chiffre entre 1 et 8 ou mme un chiffre en dehors des limites que l'on veut fixer... Il nous faudra poser des conditions pour accepter ou refuser une valeur. Nous allons passer plusieurs leons peaufiner ce code. Puis il faudra bien le rendre jouable :-) ... Cet exercice nous permettra de dcouvrir les instructions parmis les plus fondamentales en programmation : le "if" et le "repeat". De quoi nous occuper pendant plusieurs articles...

:: D1 :: Refuser l'inconnu
Dans notre script en cours de ralisation, nous aurions besoin de surveiller ce que fait l'utilisateur affin d'agir en consquence et surtout, de refuser l'inconnu. Ce dont nous avons besoin, c'est de poser nos conditions. "Si l'utilisateur ne fait pas ce que j'attends, alors... par exemple, je le lui dis." Le si informatique s'appelle dans la plupart des langages informatiques un "if". C'est une instruction compose, ce qui veut dire qu'elle peut contenir plusieurs autres instructions. Il faut donc prciser quand commence le if et quand il se termine. Pour commencer un if, l'instruction est : if (leTest) then Pour le finir : end if Voici un exemple, vous connaissez maintenant ma mthode, je dcortiquerai une fois que vous aurez tap, test et rflchi. display dialog "Bonjour. Comment allez-vous ?" buttons {"Pas trs fort","Pas mal","Bien, merci"} set laReponse to button returned of the result -- le if commence ici : if (laReponse="Pas trs fort") then display dialog "Puis-je vous aider ?" buttons {"Non","Oui"} end if -- le if vient de se terminer. ;-) J'espre que vous, vous allez bien. Mais pour voir l'intrt de ce "if", vous devriez tout de mme cliquer sur le bouton "Pas trs fort". En effet, ce code teste si le bouton cliqu est le bouton "Pas trs fort". Si c'est le cas, il affiche un second message.

:: D2 :: Quelques explications

Le dbut est classique : question l'utilisateur et mise en mmoire de la rponse dans la variable laReponse. Ligne 3, voici apparatre le if. Il est suivi entre les parenthses d'un test boolen (je vais y revenir) puis par un argument de l'instruction if : le then qui veut dire "alors...". Ligne 4, ici le message que l'on voit apparatre si l'on a cliqu sur le bouton "Pas trs fort" Ligne 5, un "end if" qui est l pour clturer le if. Le principe est donc le suivant : AppleScript regarde ce qu'il y a entre les parenthses aussitt le "if". Si ce qui s'y trouve est vrai au sens logique, le programme passe par les lignes de code qui suivent le then. Ici nous n'en avons qu'une, mais on peut en mettre autant que l'on veut. Si c'est faux, il ignore toutes les lignes jusqu' ce qu'il rencontreun end if, ou l'un des autres arguments du "if" que nous allons voir trs bientt. Un cas de "if" plus simple : si l'on a une seule instruction raliser, on peut ne pas aller la ligne aprs le then, on place l'instruction et pas besoin de clturer le if. Par exemple, ces deux versions sont quivalentes. (NB : l'instruction Beep provoque un bip, je l'utilise assez souvent avec un if pour voir si le test que je fais est vrai ou faux, vous allez comprendre) -- version 1 : if (2 = 2) then beep -- provoque un bip end if -- version 2 : if (2 = 2) then beep -- provoque le mme bip

:: D3 :: Vous avez dit Boolen ?

Je vous l'ai dj dit : pour un programmeur, ce qui est vrai ou faux est un boolen. Je prcise un peu la question. Un boolen, c'est un type de variable, comme le texte est un autre type, les nombres un autre type galement. L'intrt du boolen, c'est qu'il n'a que deux valeurs : vrai ou faux. En AppleScript : True et False. On peut donc ranger du vrai ou du faux dans une variable boolenne. Par exemple : set maVariable to False. Le plus souvent, on fait plutt un test boolen. On pose par exemple une galit : 3 = 4, ou 3 = 3, et l'on obtient d'AppleScript la valeur VRAI ou FAUX. 3 = 3, 3 = 4, ca semble un peu bte comme ca. Mais la plupart du temps, vous travaillerez avec des variables dont vous ne connatrez pas le contenu. Le test sera donc plutt : maVariable = 3 ou encore maVariable = 4. L, a a plus de sens. "=" est l'oprateur le plus utilis pour obtenir un boolen, mais il y en a d'autres, les ">" et "<" par exemples qui veulent dire infrieur ou suprieur. Voici quelques exemples de tests boolens. A la fin de la ligne, je mets un commentaire pour vous dire la valeur affecte la variable. Ce n'est pas exhaustif, il y a des faons tordues et tonnantes d'obtenir vrai ou faux. set maVariable to 5 -- pour avoir une variable a comparer par la suite set monTestBooleen to (3 = 3) -- monTestBooleen vaut VRAI set monTestBooleen to (maVariable = 6) -- vaut FAUX set monTestBooleen to (maVariable < 8) -- vaut VRAI set monTestBooleen to ("Je suis beau" = true) -- vaut FAUX set monTestBooleen to ("Je suis beau" = false) -- vaut FAUX galement Le dernier exemple vous montre la limite de la notion de VRAI et FAUX pour un ordinateur. Car videmment, dire que je suis beau est vrai. Pourquoi l'ordinateur pense-t-il le contraire ? Ce n'est pas pour lui une question de got, c'est juste qu'il ne regarde jamais le sens contenu dans le texte. Il voit juste un texte, et sait qu'un texte est de type texte alors que true est de type boolen. Pas le mme type ? Cela lui suffit : ces deux lments ne peuvent pas tre gaux. En fait je ne peux pas non plus lui faire dire que "Je suis beau" est gal a false. Dans un cas comme dans l'autre, un texte ne peut pas tre un boolen., la valeur retourne par AppleScript a ce test est donc toujours FAUX. "Je" n'est ni "beau", ni "laid", mais ne riez pas a vaut aussi pour "vous".

:: D4 :: Cas particulier : les nombres et les textes

Avec les explications qui prcdent, vous comprendrez aussi pourquoi : set monTestBooleen to (2 = "2") -- vaut FAUX Nous sommes dans le mme cas de figure, nous comparons deux choses de types diffrents. 2 est un nombre,

alors que "2" est un texte. C'est suffisant pour dire qu'ils ne sont pas gaux. Cela fonctionne pareil avec des variables. set monTexte to "2" -- monTexte est donc de type texte set monNombre to 2 -- mon nombre est de type nombre if (monTexte = monNombre) then beep a ne bip pas donc (monTexte = monNombre) est faux. Voici maintenant le cas particulier, je reprends le mme exemple : set monTexte to "2" -- monTexte est donc de type texte set monNombre to 2 -- monNombre est de type nombre if (monTexte - monNombre = 0) then beep L, il y a un bip. Etonnant ! MonTexte et monNombre ne sont pas gaux, mais ils n'ont pas de diffrence ? Que se passe-t'il dans ce monde de logique qu'est la programmation ? AppleScript vient de tricher sous nos yeux. Bien sr, il le fait pour nous aider, mais tout de mme. En fait, en rencontrant le signe de la soustraction, AppleScript regarde si notre texte ne serait pas un nombre, et si c'est le cas, il passe outre la diffrence de type pour faire l'opration demande. C'est ce que l'on appelle un changement de type, une conversion de type, un transtypage, le vocabulaire des programmeurs n'est pas toujours le mme en fonction des langages.

:: D5 :: Si AppleScript peut le faire, pourquoi pas nous ?

Bien sr, si AppleScript se le permet, nous devrions pouvoir faire de mme. Voici comment. Il existe un mot rserv "as" (on pourrait le traduire par "comme", ou plutt "sous la forme de..." en franais). Il existe mme plusieurs "as" : "as number", "as text"... On l'utilise ainsi : set maVariable to "2" -- ma variable est donc de type texte if (maVariable as number = 2) then beep -- crit ainsi, a bip "maVariable as number" est donc le contenu de maVariable, transform en nombre (si cela est possible). Le contraire fonctionne l'identique : set maVariable to 2 -- maVariable est donc de type nombre if (maVariable as text = "2") then beep -- a bip aussi "maVariable as text" est donc le contenu de maVariable, mais transform en texte

:: E1 :: "Else if" : Non ? Mais si...


"else if" est un argument du if classique que nous avons vu. J'appelle "argument" tout ce qui peut modifier le fonctionnement d'une instruction pendant qu'elle se droule. Le else if possde son propre "then" pour effectuer de nouvelles lignes de code si une nouvelle condition propose dans le else if est vraie. Un exemple simple : if (1 + 1 = 3) then beep else if (1 + 1 = 2) then display dialog "Bravo" end if Ce code ne "bip" pas car (1 + 1 = 3) est FAUX, mais il dit "Bravo" car (1 + 1 = 2) est VRAI Ce qu'il faut bien comprendre avec le "else if", c'est qu'il ne sert que si le premier "if" n'a pas fonctionn. Sinon, le code qu'il propose n'est pas utilis par le programme. En fait, si l'on crit if (1 + 1 = 2) then beep else if (1 + 2 = 3) then display dialog "Bravo" end if Puisque le premier test est vrai (1 + 1 = 2), le test (1 + 2 = 3) ne sera jamais vrifi, le programme ne cherchera pas savoir s'il est VRAI ou FAUX. Ce code ne flicitera donc jamais le (1 + 2 = 3) qui est pourtant VRAI. Quand on a compris a, on peut aligner autant de "else if" que l'on veut. Chaque nouveau "else if" ne sera test par le programme que si tous les autres tests du if et des else if prcdents ont tous t FAUX. Faisons le pour notre petit code de salutations du chapitre prcdent :

display dialog "Bonjour. Comment allez-vous ?" buttons {"Pas trs fort","Pas mal","Bien, merci"} set laReponse to button returned of the result if (laReponse="Pas trs fort") then display dialog "Puis-je vous aider ?" buttons {"Non","Oui"} else if (laReponse="Pas mal") then display dialog "Alors, bonne journe" buttons {"Merci"} else if (laReponse="Bien, merci") display dialog "Je vous en prie" buttons {"A bientt"} end if Avez-vous vraiment besoin de commentaires supplmentaires ? Pour chaque bouton de notre premier message, nous avons maintenant un message de rponse diffrent.

:: E2 :: Non ? Bon, alors...

Nous savons maintenant multiplier les tests grce au "else if", ce qui est trs bien. Mais on n'est pas toujours capable de deviner toutes les valeurs saisies par un utilisateur distrait, inexpriment, voire vicieux. Et mme si on les devinait toutes, il serait difficile de crer autant de "else if" que de cas de figure imaginables. Il nous faut donc un argument pour dire : dans tous les autres cas, alors, faisons cela... Cet argument est le "else". Il s'utilise forcment en dernier (avant le end if, mais aprs les "else if") et les instructions qui le suivent sont effectues si tous les autres "if" et "else if" qui le prcdent taient faux, sans qu'il y ait besoin d'un test VRAI/ FAUX. if (monTest) then display dialog "le test est bon" else beep display dialog "Le test n'est pas bon" end if On pourrait maintenant imaginer crire notre code de salutation avec un "else" pour remplacer le dernier "else if". En effet, on peut supposer que notre variable contient obligatoirement le nom du troisime bouton, si il ne contient pas le nom du premier ou du deuxime. Cela nous vite d'crire le test d'une part, mais galement de faire travailler l'ordinateur pour rien. Pour rien ? Pas si sr. C'est vrai qu'il n'y a pas trop de danger, ce que je vais dire maintenant est de la paranoa dans notre exemple aussi simple. Mais il est vraiment plus sage d'utiliser un "else" pour assurer la scurit d'une application, plutt que pour orienter le code, partir d'une supposition aussi fonde soit-elle. display dialog "Bonjour. Comment allez-vous ?" buttons {"Pas trs fort","Pas mal","Bien, merci"} set laReponse to button returned of the result if (laReponse="Pas trs fort") then display dialog "Puis-je vous aider ?" buttons {"Non","Oui"} else if (laReponse="Pas mal") then display dialog "Alors, bonne journe" buttons {"Merci"} else if (laReponse="Bien, merci") display dialog "Je vous en prie" buttons {"A bientt"} else display dialog "Ce programme va devoir quitter car il ne comprend pas votre rponse." with icon 0 end if Il y a vraiment trs peu de chance qu'un utilisateur voit un jour le dernier message, mais au moins, nous avons la conscience tranquille.

:: E3 :: Avec des si... Revenons notre jeu

Ouvrez le script du jeu de roulette si vous l'avez enregistr, nous allons y incorporer quelques "if". Dans notre code, nous avons besoin de vrifier que le prnom entr par l'utilisateur ne soit pas vide. Nous devons tester galement que le nombre choisi soit valide. Pour le choix pair ou impaire, il se fait sur la slection des boutons, donc il ne devrait pas nous causer de

soucis. Ces tests sont des tests simples. Au cas o il y aurait problme, nous allons juste le notifier dans la variable concerne en y inscrivant "<>" au lieu du texte saisi par l'utilisateur. On pourrait redemander chaque fois l'utilisateur de changer sa rponse, mais en poursuivant la saisie, nous pouvons regrouper tous les "if" vers la fin, ce qui va tre plus clair pour l'instant. Nous prviendrons l'utilisateur grce au rcapitulatif et uniquement "si" une des variables est invalide. Si il n'y a pas d'erreurs, donc pas de variable contenant <>, nous pourrons continuer avancer dans le droulement du jeu. Je recopie ici tout l'ancien code, en supprimant quelques commentaires. Les lignes que j'ai ajoutes se trouvent vers la fin, juste avant le message rcapitulatif. Vous devriez vous y retrouver. -- Dbut du code -- Demandons son nom l'utilisateur / rien de nouveau ici display dialog "Quel est votre prnom ?" default answer "" set prenomUtilisateur to text returned of the result -- Demandons son pari entre 1 et 8 / rien de nouveau ici set nouveauTexte to prenomUtilisateur & ", choisissez un nombre entre 1 et 8" display dialog nouveauTexte default answer "" set choix1Utilisateur to text returned of the result -- Demandons le pari pair/impair / rien de nouveau ici set nouveauTexte to prenomUtilisateur & ", que choisissez-vous ?" display dialog nouveauTexte buttons {"Pair", "Impair"} set choix2Utilisateur to button returned of the result -- vrifions nos variables : ca c'est nouveau -- Si il n'y a pas eu de prnom de tap : if (prenomUtilisateur = "") then set prenomUtilisateur to "<>" -- Si le chiffre n'est pas accept : if (choix1Utilisateur is not in {"1", "2", "3", "4", "5", "6", "7", "8"}) then set choix1Utilisateur to "<>" end if -- Si l'une ou l'autre des variables est invalide : l'ancien message est inclus dans un "if" if choix1Utilisateur = "<>" or choix2Utilisateur = "<>" then -- construisons le texte de notre message d'alerte, puis affichons-le set ligneA to "Attention : certains choix sont invalides :" & return set ligneB to "Prnom :" & prenomUtilisateur & return set ligneC to "Premier pari : " & choix1Utilisateur & return set ligneD to "Deuxime pari : " & choix2Utilisateur & return display dialog ligneA & ligneB & ligneC & ligneD buttons {"Pari refus"} default button "Pari refus" else display dialog "Votre pari est valid." buttons {"OK"} end if -- Fin du code Ne soyez pas effrays par la longueur, j'ai en fait rajout trs peu de lignes par rapport au prcdent.

:: E4 :: Les commentaires

Le premier "if" insr, est de nature connue. Il teste l'galit du prnom saisi "", c'est--dire rien. Si rien n'est saisi, on ne peut pas accepter "rien" comme prnom donc on remplace "rien" par <>. Le deuxime test vous est inconnu. Il y a dedans une liste : {1,2,3,4,5,6,7,8} se sont toutes les valeurs acceptes par notre jeu. Le test est "is not in", ce qui, traduit en franais, donnerait : "la valeur donne n'est pas dans la liste des valeurs acceptes".

Cette affirmation est bien VRAIE si la valeur saisie n'est pas dans la liste, comme quoi il faut bien rflchir aux sens d'une affirmation avant d'en faire un test boolen. Dire d'une affirmation fausse qu'elle est fausse, c'est dire quelque chose de vrai. Mais non, ce n'est pas si compliqu : quand je dis "2 + 2 ne font pas 6", je dis quelque chose de vrai, n'est-ce pas ? Le troisime if encadre l'affichage du message final (que j'ai transform en message d'erreur en passant). Le message n'est affich que si l'une des variable est invalide. Ce test doit donc tre double et pour cela utilise un autre "oprateur boolen" : le "or" qui permet de cumuler les tests. "Or" c'est notre "ou bien" en franais. Il n'est pas trs exigeant : pour prendre une valeur vraie, il suffit que l'une des conditions, sa droite ou a sa gauche soit vraie. Un autre oprateur fonctionne sur le mme principe mais est, lui, beaucoup plus exigeant : le "and". Une expression contenant un "and" prend la valeur VRAI si la partie sa droite et celle sa gauche sont vraies toutes les deux. On peut le comparer au "et" en franais. Par exemple : "(2 = 2) or (5=4)" est VRAI alors que : "(2 = 2) and (5=4)" est FAUX Enfin, j'ai rajout un else dans le dernier "if" qui affiche un message comme quoi tout c'est bien pass. Si vous avez compris le fonctionnement du "if", vous devez comprendre que ce message s'affiche uniquement quand toutes les informations entres par l'utilisateur ont acceptables selon nos conditions. Retenez bien cette notion de boolens, du test de l'instruction "if". Revenez-y rgulirement si vous n'tes pas l'aise. C'est la seule chose complexe concernant le "if". L'enchanement "if", "else if " et "else" ne vous causera plus de soucis ds que vous aurez invents et tests quelques exemples de "if" par vous-mme.

: F1 :: Quand on se rpte, le plus dur c'est de s'arrter...


En effet, se rpter une fois que l'on connat l'instruction est trs facile. Mais si l'on dit un ordinateur de rpter quelque chose, il n'a qu'une oreille. Il va continuer la rptition perptuellement et n'ira pas voir plus loin. Une rptition sans une condition d'arrt tourne jusqu' ce que l'ordinateur plante par manque de mmoire , dbordement, ou si l'on dbranche la prise. Il y a tout de mme une faon plus lgante d'arrter un programme si vous vous trouvez bloqus pendant un script : frappez le raccourci classique sur mac pour annuler une commande : pomme-majuscule-point. Ce raccourci suffit arrter le droulement d'un script. Puisque vous tes maintenant prvenus, voici comment crire une rptition. La rptition, comme l'instruction if, est une instruction structure qui peut contenir une ou plusieurs lignes de code. Il y a donc un dbut de rptition et une fin de rptition. Le dbut de la rptition s'crit : repeat la fin s'crit : end repeat Entre ces deux lignes, on crit le code que l'on veut rpter. C'est presque simple. ATTENTION : prparez-vous utiliser le raccourci pomme-majuscule-point, le code suivant boucle ternellement. Il vous faudra interrompre son droulement. N'ayez pas peur, faites-le. De toute faon cela vous arrivera bien un jour, il vaut mieux vous familiariser avec la manipulation maintenant que vous vous y attendez. Et puis, cela n'a rien de dangereux : pas de dcharge lectrique ni rien de dsagrable. repeat beep -- attention, a va faire un peu de bruit ;-) end repeat Maintenant, je suis sr que vous avez compris l'importance de prvoir un arrt dans une instruction "repeat". Pour arrter un script par le code, il faut utiliser l'instruction "exit repeat". Cette fois-ci le code ne tourne plus indfiniment : repeat beep exit repeat

end repeat D'ailleurs, il ne tourne plus du tout, notre code. Ds le premier passage (on appelle aussi a une boucle), le programme rencontre l'instruction "exit repeat" et ne revient pas au dbut de la boucle. Pas beaucoup d'intrt, la ligne "beep" toute seule fait le mme effet que les 4 lignes runies. Maintenant, je suis sr que vous avez compris l'importance de la condition d'arrt.

:: F2 :: Je m'arrte, mais une condition...

Pour arrter un script par le code, il faut utiliser l'instruction "exit repeat" avec une condition. C'est--dire, ce que nous avons vu aux chapitres prcdents, une instruction "if". Toute la difficult est donc de construire un test boolen en fonction de ce que l'on veut faire. Cela demande une petite mise en scne. Par exemple : set unCompteur to 0 repeat set unCompteur to (unCompteur + 1) beep if unCompteur = 10 then exit repeat end repeat Comprenez-vous le pourquoi des trois lignes supplmentaires ? Avant le "repeat", nous donnons la valeur zro une variable qui nous sert de compteur kilomtrique en quelque sorte. chaque passage dans la boucle "repeat" nous ajoutons 1 notre compteur. Ensuite vient le bip, puis un test sur la valeur du compteur. Quand celui-ci est gal 10, le programme rencontre l'instruction "exit repeat" et il sort de la boucle. Notre bip se rpte 10 fois. Si vous n'en entendez qu'un, c'est que votre mac est trop rapide. Essayez avec 100, puis 1000... Si vous voulez entendre distinctement tous les bips, ajoutez l'instruction "delay 1" entre le "beep" et le "if". L'instruction delay oblige votre ordinateur attendre, le chiffre qui suit est son paramtre. Il vous permet d'indiquer le nombre de secondes de pause que vous dsirez. Attention, notre test "if unCompteur = 10 then exit repeat" est relativement sans risque sur notre exemple. Mais il faut se mfier avec la condition d'arrt d'une boucle. Pour tre bien sr de vous arrter, je vous conseillerais plutt de vous habituer crire : if unCompteur > 9 then exit repeat C'est une question de scurit. Vous n'tes pas obligs de me croire sur parole, mais je pense que ce bon conseil vous reviendra en mmoire le jour o vous aurez cherch pendant des heures pourquoi l'un de vos repeat est ternel. Il est vite fait de passer ct d'une valeur exacte, par contre quand on dpasse, on dpasse.

:: F3 :: Un exercice de patience...

Pour la premire fois, je vais vous demander de rflchir un peu par vous-mme. Cela s'appelle un exercice l'cole, j'espre que vous le prendrez plutt comme un plaisir. Tout comme un exercice, il va y avoir un nonc, quelques conseils, puis une solution. Ce n'est vraiment pas un exercice difficile, mon but est juste de vous obliger prendre un peu d'autonomie, ne pas croire par avance que le code que j'cris est le seul valable ou le plus performant. Chacun sa personnalit et vous avez maintenant assez de connaissances pour afficher la vtre. Voici l'nonc du problme : Vous devez crire le code pour tester la patience de l'utilisateur. Pour cela, posez-lui sans arrt une question, par exemple "Vous reste t-il encore un peu de patience ?" jusqu' ce qu'il cde et veuille arrter le test. Donnez-lui alors une apprciation de sa patience. Quelques conseils : Bien sr cet exercice est l'occasion d'utiliser des "repeat" et des "if".

Ne vous concentrez pas que sur la boucle "repeat" principale, pensez rendre le dbut et la fin de votre test agrable ou fantaisiste. C'est souvent ce qui permet de rendre un programme, mme simple, sympathique. Pour l'apprciation de la patience de votre utilisateur, servez-vous d'un compteur. Ma solution ? Non, non, je ne vous la donne pas tout de suite. Cherchez encore un peu. En attendant, je vous propose de continuer le code de notre jeu de roulette.

:: F4 :: Retour sur le pari...

Le code de notre jeu de roulette est pour l'instant inefficace. Il vrifie bien la validit de ce qu'a saisi l'utilisateur, mais il ne relance pas une nouvelle saisie. Avec un "repeat", nous savons maintenant comment faire. -- Dbut du code -- Un petit message de bienvenue display dialog "Bonjour et bienvenue au jeu de la mini-roulette" buttons {"Je veux jouer"} -- en avant pour un repeat repeat -- Ce repeat recommence la saisie tant qu'il y a une saisie inacceptable -- Demandons son nom l'utilisateur display dialog "Quel est votre prnom ?" default answer "" set prenomUtilisateur to text returned of the result -- Demandons son pari entre 1 et 8 set nouveauTexte to prenomUtilisateur & ", choisissez un nombre entre 1 et 8" display dialog nouveauTexte default answer "" set choix1Utilisateur to text returned of the result -- Demandons le pari pair/impair set nouveauTexte to prenomUtilisateur & ", que choisissez-vous ?" display dialog nouveauTexte buttons {"Pair", "Impair"} set choix2Utilisateur to button returned of the result -- Vrification des valeurs saisies par l'utilisateur if (prenomUtilisateur = "") then set prenomUtilisateur to "<>" if (choix1Utilisateur is not in {"1", "2", "3", "4", "5", "6", "7", "8"}) then set choix1Utilisateur to "<>" end if if prenomUtilisateur = "<>" or choix1Utilisateur = "<>" then -- Si l'une ou l'autre des variables est invalide, on prvient l'utilisateur -- construisons le texte de notre message d'alerte, puis affichons-le set ligneA to "Attention : certains choix sont invalides :" & return set ligneB to "Prnom :" & prenomUtilisateur & return set ligneC to "Premier pari : " & choix1Utilisateur & return set ligneD to "Deuxime pari : " & choix2Utilisateur & return display dialog ligneA & ligneB & ligneC & ligneD buttons {"Pari refus"} default button "Pari refus" else display dialog "Votre pari est valid." buttons {"OK"} -- C'est ici que l'on peut sortir de la boucle repeat de vrification exit repeat end if end repeat -- Fin du code

L encore, ne soyez pas effrays. Ce n'est pas trs compliqu. J'en ai donc profit pour modifier les textes des messages, histoire de vous obliger tout relire. Au dbut, un petit message d'accueil. Ensuite, on lance une boucle qui tournera tant que l'utilisateur n'aura pas entr des valeurs correctes. L'instruction pour sortir de la boucle "repeat" se trouve dans le "else" du "if" final. C'est--dire quand l'utilisateur a entr des rponses valides.

:: F5 :: Corrig de l'exercice

J'espre que vous avez russi faire l'exercice en F - 3. Si oui, c'est bon signe, "la programmation est en toi ". Enfin partiellement. c'est dj a. Sinon, je ne sais pas quoi vous dire. Posez des questions sur le forum ? N'allez pas trop vite, reprenez la lecture au chapitre C. Ces notions sont importantes, c'est vrai qu'elles ne sont pas simples, mais ce n'est pas insurmontable, je vous le garanti. Voici ce que je propose de mon ct, en vous rappelant que ce n'est pas forcment ce qui se fait de mieux. Le fait que je sois jeune papa a peut-tre influenc lgrement cet exercice quelque-part, mais franchement, je ne vois pas trop o ;-) --j'initialise un compteur pour mesurer la patience set maPatience to 0 -- introduction display dialog "Papa, pourquoi les feuilles des arbres elles bougent ?" buttons {"Je ne sais pas", "Le vent les chatouille"} set laReponse to button returned of the result -- si l'utilisateur termine le test ds la premire question, -- rservons-lui son message : if laReponse = "Je ne sais pas" then set monMessage to "Psychologie : 0. Imagination : 0" & return & "Vous n'avez pas fait preuve de patience." else -- sinon, lanons une boucle pour le tester repeat -- le message pour tester la patience display dialog "Oui, mais pourquoi ?" buttons {"Arrte !", "Parce-que"} -- la condition pour sortir du repeat if button returned of the result = "Arrte !" then exit repeat -- on augmente le compteur de patience, -- puisqu'on n'est pas sorti de la boucle set maPatience to (maPatience + 1) end repeat -- en fonction du niveau de patience obtenu, -- j'attribue un message diffrent if (maPatience < 5) then set monMessage to "Votre patience est faible" else if (maPatience < 10) then set monMessage to "Votre patience est mritoire" else -- au-del de 10 questions set monMessage to "Mais comment faites-vous ? Moi, je n'y arrive pas." end if end if display dialog "Niveau " & maPatience & return & monMessage buttons {"OK"} Testez, et regardez bien ce qui se passe. Je n'ai rien utilis que vous ne connaissiez dj, et je pense que les commentaires sont suffisants pour que vous compreniez ce qui se passe dans ce code. Sinon, peut-tre que l'explication, c'est que vous n'avez pas d'enfant ? ;-)

:: G1 :: Rpte 4 fois...
Vous voulez une explication ? Allons, un peu de bon sens et le rveil de quelques cellules grises devraient vous suffire pour comprendre cet exemple : repeat 4 display dialog "Coucou" end repeat display dialog "Il est 4 heures" Je vois que vous avez compris. Bien videmment, vous n'tes pas oblig de toujours utiliser "4" avec ce type de repeat. 7, 15, 32 ou une variable de type nombre entier fera trs bien l'affaire. ;-) Passons la suite.

:: G2 :: Rpte jusqu' ce que tu trouves 6

Voil o a se complique un peu. Dans l'article prcdent, nous avons utiliser un "if" pour tester une variable et sortir d'un repeat ternel. Ici, la condition de sortie est incluse dans l'ouverture du repeat. Par exemple : set maVariable to 1 repeat until (maVariable = 6) display dialog "Je sais compter jusqu' " & maVariable set maVariable to maVariable + 1 end repeat display dialog "Je ne sais pas compter jusqu'a " & maVariable Regardez la ligne "repeat until (maVariable = 6)". (maVariable = 6) est un boolen. Je vous avais bien dit de vous familiariser avec ce truc-l ! (maVariable = 6) prends donc la valeur VRAI ou FAUSSE selon que maVariable est gale ou non 6. Un repeat UNTIL continue donc de boucler tant que le test boolen qui le suit est FAUX. Quand le test est vrai, il s'arrte. Je passe au suivant, parce qu'il est trs semblable.

:: G3 :: Rpte tant que tu ne trouves pas 6

Voici un code qui ressemble trangement au prcdent : set maVariable to 1 repeat while (maVariable is not 6) display dialog "Je sais compter jusqu' " & maVariable set maVariable to maVariable + 1 end repeat display dialog "Je ne sais pas compter jusqu'a " & maVariable Le test ici est le contraire du prcdent : on teste si la variable est diffrente de 6. Le repeat WHILE boucle tant que le test est VRAI, et s'arrte quand il est VRAI. Ces deux repeat sont trs proches : un test boolen qui arrte la boucle repeat si, dans un cas il est vrai, dans l'autre s'il est faux. Pour AppleScript, la diffrence s'arrte l. dans d'autres langages, il y a une petite subtilit : le repeat while fait son test en fin de boucle, ce qui veut dire que le code est appliqu au moins une fois et cette diffrence peut avoir de l'intrt dans certains cas. Alors retenez juste ceci : si, en sortant d'une boucle repeat, vous tes oblig de soustraire 1 votre compteur pour qu'il soit la valeur dont vous aez besoin, c'est certainement que vous auriez p utiliser cette subtile diffrence... mais dans un autre langage... La simplicit se paye parfois.

:: G4 :: Rpte en comptant de 1 10

Voil une formule qui semble claire, qu'en pensez-vous ? Elle doit se rpter 10 fois, et apparemment peut nous dire qu'elle boucle elle est rendue. Effectivement, vous avez bien suivi. La seule chose qui nous manque, c'est de choisir une variable dans laquelle nous pourrons lire le numro de la boucle en cours. C'est nous de choisir le nom de cette variable, par exemple monCompteur. C'est tout simple et c'est ainsi : repeat with monCompteur from 1 to 10 display dialog "Ceci est la boucle :" & monCompteur end repeat Ce genre de repeat est particulirement adapt et clair. Le repeat WITH reoit la variable monCompteur pour y mettre lui-mme son dcompte de boucle, plus besoin d'crire la ligne monCompteur=monCompteur +1. De plus, on prcise aprs le nom de la variable, les valeurs de dpart (paramtre "from") et d'arrive (paramtre "to"). Dans mon exemple, de 1 10, mais cela pourrait tre de 7 40 tout aussi simplement :

"repeat with monCompteur from 7 to 40". Et si l'on veut compter de deux en deux ? La formule du repeat with est peine diffrente, il vous faut juste apprendre un troisime paramtre : le "by". Le "by", c'est le "par" franais, une sorte de "par pas de :" Puisque ce n'est pas compliqu en soit, j'ai enrichi le code suivant d'un premier dialogue. Rien qui puisse vous perturber. display dialog "Deux et deux font 4" repeat with monCompteur from 6 to 10 by 2 display dialog "Et deux " & monCompteur end repeat Puisque l'on peut maintenant compter de deux en deux ou de 3 en 3, avec un peu d'efforts, nous pouvons dcompter au lieu de compter. Pour cela, mme pas besoin d'apprendre un nouveau paramtre, c'est juste une question de logique : dcompter, c'est compter de -1 en -1. C'est tellement simple que j'en profite pour complexifier le code d'exemple. display dialog "Dpart d'Ariane" buttons {"GO"} default button "GO" repeat with monCompteur from 10 to 0 by -1 if monCompteur > 3 then beep display dialog "Dpart dans " & return & monCompteur & " secondes" giving up after 1 buttons {""} else display dialog monCompteur giving up after 1 end if end repeat repeat beep -- relisez bien l'article prcdent ! end repeat Rien de bien mchant pour ceux qui ont suivi la leon prcdente, n'est-ce pas ?

:: G5 :: Rpte avec chaque lment

Bien que nous ne connaissions pas encore trs bien ( a va venir) les listes, il existe une forme ultime du repeat : le repeat numrateur. Le nom n'est pas trs clair, mais le titre de ce paragraphe a dj d vous clairer sur l'intrt de cette forme du repeat. Le but est simple. partir d'une liste, une boucle repeat numrateur nous permet d'agir sur chaque lment de la liste. On pourrait faire la mme chose avec un repeat with comme nous l'avons vu dans le paragraphe prcdent. Je vous montre comment avant de vous montrer le repeat numrateur. set maListe to {10, 20, 30, 40} -- ceci est une liste de nombres repeat with monCompteur from 1 to (count of maListe) set item monCompteur of maListe to (item monCompteur of maListe) + 1 end repeat maListe Ce code permet d'ajouter 1 chaque lment de la liste. Je prcise, ligne par ligne : La premire dfinit une variable qui contient la liste de 4 nombres. Ensuite, on ouvre le repeat, avec un compteur qui ira de la valeur 1 jusqu'au nombre d'lments dans la liste (c'est le "count of maListe" qui permet de connatre le nombre d'lments d'une liste). Ensuite, le mot "item" sert dsigner un lment. Juste aprs item, on place le rang de l'lment. Par exemple "item 1", c'est l'lment 1. Item 2, l'lment 2 de la liste etc. Item monCompteur permettra d'accder l'lment 1, puis 2 puis 3 et enfin 4 de la liste. La ligne "set item etc." permet donc de remplacer chaque valeur de la liste par sa propre valeur + 1. On referme le repeat. Ensuite, le "maListe" permet tout simplement d'appeler la liste. Cela ne provoque rien en apparence, mais si vous ouvrez la fentre "rsultat", vous pourrez voir la variable maListe et vrifier que le code a bien fonctionn. Complexe ? Un peu. Mais il fallait bien que je vous le montre pour que vous compreniez l'intrt maintenant du

repeat numrateur. Le voici en action, le code qui suit ralise la mme opration que le code prcdent. set maListe to {10, 20, 30, 40} -- ceci est une liste de nombres repeat with chaqueElement in maListe set contents of chaqueElement to (contents of chaqueElement) + 1 end repeat maListe Est-ce plus clair ? Cela devrait. Juste quelques prcisions : La dclaration du repeat numrateur commence comme celle du repeat with : dclaration d'une variable qui servira de conteneur pour que le repeat mette dedans chaque lment de la liste. Ce qui change c'est le paramtre : son identifiant est "in" et on lui passe la liste sur laquelle on veut travailler. Si, si, cette dclaration est simple, ne vous creusez pas la tte : il s'agit bien d'une traduction anglaise de notre "rpte avec chaque lment dans la liste". Le choix du nom de la variable , "chaqueElement" permet de le mettre en vidence. Tant que l'on est ensuite dans la boucle "repeat", on peut appeler l'lment courant de la liste en se servant du nom de la variable (chaqueElement dans l'exemple). Attention, vous l'avez remarqu, il faut demander le "contents" (le contenu) de cette variable pour obtenir la valeur de l'lment (dans l'exemple, les nombres 10, 20 etc.). L'explication fournie par Apple : le repeat numre uniquement la rfrence chaque lment. C'est peut tre plus clair si je fais parler le repeat lui-mme : Il dit chaque passage de la boucle : "Je tiens dans mes mains le premier lment de la liste", "Je tiens dans mes mains le deuxime lment de la liste", etc. Au programmeur d'aller regarder ce que le repeat tient dans les mains : le contents de l'lment. Ce n'est pas compliqu. C'est juste un peu surprenant et il n'est pas rare de l'oublier quand on dbute. Si ce n'est pas totalement clair, attendez l'article qui va suivre sur la manipulation des listes, lisez-le puis revenez voir ce qu'il en est de ce repeat numrateur qui vous sera bien utile srement. Il y aurait d'autres choses dire encore sur les variantes et subtilits des repeat. Nous en rencontrerons peuttre au fil des leons, sinon, reportez vous la documentation d'AppleScript. Elle est plus complte dfaut d'tre pdagogue, mais avec les bases que vous avez trouv ici, je pense que vous pouvez y aller de bon coeur.

: H1 :: Discours sur les donnes


If, repeat, display dialog, tout cela, ce sont des instructions. Nous ne les connaissons pas toutes encore, mais leur nombre est limit, vous avez maintenant quelques bases et ne devriez pas avoir peur d'en dcouvrir d'autres au hasard d'un code d'exemple. Par contre, quoi servent les instructions, s'il n'y a pas quelque chose, une matire premire que vous voulez travailler ? C'est cela, les donnes : la matire premire sur laquelle on utilise les instructions, affin de les classer, de les dformer, d'en sortir autre chose. Celui qui dveloppe un programme de traitement de texte aura comme donnes... du texte. Celui qui travaille l'image aura comme donnes des pixels... Quoi qu'il en soit pour tous, ce sont "des" donnes qu'il faut ranger et organiser car, trs vite, "des" donnes, on en a normment. Les ranger est indispensable, car il faut pouvoir les atteindre quand on en a besoin, et a, ce n'est pas si simple. D'autres langages sont plus riches qu'AppleScript pour cela, mais aussi plus complexes. Pour AppleScript, on range les donnes dans des "listes". Mme si cela semble simple, mme si AppleScript ne fait pas de diffrence entre les listes, je vous conseille de faire attention au genre de listes que vous crez.

:: H2 :: >Des listes, en veux-tu en voil....

Nous avons dj vu quelques bases sur les listes, mais je prfre les rappeler ici : Une liste s'crit entre deux accolades, ses lments (qu'on appelle des items) sont spars par des virgules. Ici s'arrte la description d'une liste pour AppleScript. La liste vide : La plus simple, la plus frquente, la plus dangereuse mais aussi parfois la plus utile des listes est la liste vide : {} Cette liste ne contient rien, et ne croyez pas qu' cause de cela elle soit pauvre. Il vous faudra y penser

souvent pour viter les bugs, sortir d'une boucle repeat avant qu'il ne soit trop tard... Ce vide est tellement important que vous devez y rester attentif ds que vous manipulez des listes. La liste 1 lment : {"Bonjour"} Cette liste contient un mot, une donne. Cette donne est "type", comme disent les programmeurs : une donne de type "texte", ne pas confondre avec un type "entier", ou d'autres types que nous n'avons pas encore vus : date, path.. Je vous parle de la liste un lment, parce qu'elle est trompeuse pour le dbutant. Difficile de faire la diffrence entre {"Bonjour"} et "Bonjour" quand ils ne sont plus en clair dans le texte du code, mais cachs l'intrieur d'une variable. Si vous tes comme moi, vous verrez souvent apparatre des erreurs cause de ce genre de liste. Des listes types Ds qu'il y a plus d'un lment dans une liste, sachez faire la diffrence entre une liste type et une liste qui ne l'est pas. En fait, puisque c'est vous qui construisez les listes, c'est vous qui dcidez d'organiser vos donnes par des listes o tous les lments sont de mme type ou non. Comme cela ne fait pas de diffrence pour AppleScript, la distinction que je fais entre les listes types et celle qui ne le sont pas est purement thorique. Toutefois, vous verrez avec un peu de pratique qu'il est beaucoup plus facile de manipuler des listes types que les autres. Un exemple de liste qui ne contient que des lments de type texte : {"Je suis","une liste","type"} Elle pourrait servir de paramtre une instruction display dialog comme liste des boutons. {5,8,15,24} est une liste d'entiers, et pourra facilement tre utilise pour des calculs.... Bien videmment, une variable est du mme type que ce que l'on a mis dedans, et les variables s'insrent sans souci dans une liste type. set unNombre to 8 -- unNombre est une variable de type entier set maListeTypee to {5,unNombre,15,18} -- est une liste type Une liste non type, c'est par exemple : {1965, "Didier", false, 024000000} Bien sr, si vous savez que vous avez rang les donnes dans l'ordre suivant : date de naissance, prnom, clibataire ou mari, numro de tlphone, vous pourrez pendant un temps vous en sortir. Mais pour ce genre de liste, il existe une autre forme que l'on appelle un enregistrement. Nous en parlerons plus tard. Dernier petit pige : une liste peut contenir... des listes. Oui, pourquoi pas ? {1,2,3,{6,7,8}} Cette liste ne contient que 4 lments et non pas 6 : 3 nombres entiers et 1 liste (qui elle contient 3 lments). Pour le vrifier, nous avons l'instruction "count" qui permet de connatre le nombre d'lments dans une liste : Set maVariable to count of {1,2,3,{6,7,8}} -- maVariable vaut 4

:: H3 :: >Parler des lments d'une liste

Maintenant que je vous ai mis en garde, voyons comment travailler avec des listes. Je vais en dclarer deux, une fois pour toutes (jusqu' la fin de la leon), pour nous permettre d'crire des exemples. set listePrenoms to {"Alice","Bernard","Corinne","Didier"} set listeChiffres to {10,20,30,40,50} Pour atteindre un lment d'une liste (rappelez-vous que cela s'appelle un item) il suffit de l'appeler par son rang. item 2 of listePrenoms -- permet d'atteindre "Bernard" Utilisez-le de la mme faon dans une instruction, inscrit entre parenthses (si cela vous aide, mais ce n'est pas obligatoire), la valeur de l'lment est aussitt exploitable par AppleScript, par exemple pour une addition : set leTotal to (item 1 of listeChiffres) + 5 -- leTotal est gal 15 (10 + 5)

Ceux qui matrisent la langue de Shakespeare peuvent utiliser "first item", "second item", "third..." Bien sr cela facilite pour eux la relecture, mais pour nous, item 1, 2, ou 3 reste plus parlant. En utilisant un nombre entier ngatif, on peut atteindre les lments d'une liste en partant de la fin. Par exemple : item -1 of listePrenoms -- fait rfrence "Didier" item -2 of listePrenoms -- fait rfrence "Corinne" Cela me semble une rgle simple et facile retenir autant qu' mettre en pratique. On peut mme atteindre plusieurs lments d'une liste en une seule instruction en utilisant l'expression "thru" qui veut dire en franais "jusqu'". Notez que pour cela, il faut parler d'items (au pluriel), et que le rsultat d'une slection de plusieurs lments d'une liste est forcment... une liste. items 1 thru 2 of listePrenoms -- permet de parler de {"Alice","Bernard"} Bien sr on peut mixer ici la notation positive et la ngative : items 2 thru -2 of listePrenoms -- vaut {"Bernard","Corinne"} Note : Si la deuxime valeur se trouve avant la premire, la liste est la mme, alors que l'on pourrait s'attendre ce qu'elle soit inverse. Items -2 thru 2 of listePrenoms -- vaut {"Bernard","Corinne"} -- et non pas {"Corinne","Bernard"} "Some" est un slecteur alatoire. Cela veut dire qu'il prend un lment de la liste au hasard. Son usage le rserve surtout aux jeux, ce qui nous intresse: set laChance to some item of listePrenoms -- renvoie un des prnoms au hasard "middle" est un slecteur qui permet d'obtenir l'lment central d'une liste. Si la liste contient un nombre impair d'lments le centre est vident trouver : middle item of listeChiffres -- fait rfrence 30 Si la liste contient un nombre pair d'lments, l'lment central est le dernier de la premire moiti. Par exemple : middle item of listePrenoms -- fait rfrence "Bernard"

:: H4 ::> Modifier des listes...

Puisque nous savons atteindre un lment dans une liste, on peut tout aussi facilement le redfinir avec l'instruction "set": set item 3 of ListePrenoms to "Cathy" -- remplace "Corinne" par "Cathy" Ajouter un lment une liste, on peut le faire au dbut ou la fin en utilisant les mots rservs d'AppleScript "beginning" et "end". Mais il faut alors utiliser l'instruction "copy" qui s'crit ainsi : copy "Aaron" to the beginning of listePrenoms -- pour insrer au dbut copy "Zbulon" to the end of listePrenoms -- pour insrer la fin A l'inverse, ter le premier lment d'une liste peut se faire simplement l'aide du mot "rest". Cette instruction renvoie les lments qui suivent le premier item de la liste qui lui est passe en argument : set resteListe to rest of listePrenoms -- donne {"Bernard","Corinne","Didier"} Pour inverser les lments d'une liste, l'instruction est "reverse" : set listeInverse to reverse of listeChiffres -- donne {50,40,30,20,10} Rassembler les lments de deux listes, c'est trs facile : set listeEnVrac to listePrenoms & listeChiffres Il y a aussi "every", qui est un slecteur d'items puissant, mais dont je ne peux pas montrer l'intrt sans sortir de l'diteur de scripts. Dans le cadre de ces articles, son intrt est donc limit mme s'il peut nous servir retrouver une liste type partir d'une liste qui ne l'est pas, en demandant tous les lments d'un type donn. -- je cre une liste nom type en associant nos deux listes set listeEnVrac to listePrenoms & listeChiffres -- je retrouve les prnoms en demandant tous les items de type text set lesPrenoms to every text of listeEnVrac -- et les nombres en demandant tous les items de type number set lesNombres to every number of listeEnVrac Mais c'est une dmonstration bien pauvre de son intrt. Il y a tant de choses dire sur les listes que ce cours dure dj depuis trop longtemps. Nous avons dcouvert le slecteur alatoire "some", profitons-en pour rendre notre jeu de mini-roulette jouable.

:: H5 ::> Un petit tour de roulette ?

Nous nous tions arrts aprs l'inscription des paris. Nous voudrions maintenant choisir au hasard un chiffre entre 0 et 8 (oui, "zro", car si vous ne le saviez pas, il y a un zro la roulette qui n'est d'ailleurs ni pair ni impair et rapporte tous les gains la banque). Nous savons comment faire. Quelques lignes de plus permettent de prvenir le joueur de son gain. Ce code est rajouter celui de l'article "F", moins que vous ne l'ayez fait progress vous-mmes. -- voici la ligne qui nous manquait : set laBoule to some item of {"0","1","2","3","4","5","6","7","8"} -- on teste si le numro choisit est le 0 if laBoule is "0" then -- si oui, on prpare un message set message to "Tous les gains vont la banque" set boutons to {"Zut!"} -- et l'on donne une valeur perdante pour le deuxime pari set pariPair to "perdu" else -- sinon, on cherche savoir si le numro est pair ou impair if laBoule is in {"1", "3", "5", "7"} then set pariPair to "Impair" else set pariPair to "Pair" end if if laBoule = choix1Utilisateur then -- si l'utilisateur a fait le bon choix, on prpare un message gai set message to "Bravo ! Vous gagnez 8 fois votre mise." set boutons to {"Youpi"} else -- sinon, un message triste set message to "Perdu, vous aviez pari " & choix1Utilisateur set boutons to {"Je ferai mieux la prochaine fois"} end if end if if pariPair = choix2Utilisateur then -- pour le pari pair-impair on ne prvient que le gagnant -- en rallongeant le message qui est dj prpar set message to message & return & pariPair & " : vous rcuprez votre mise" end if -- pour finir, on affiche le message display dialog laBoule & return & message buttons boutons Voil. Notre script fonctionne maintenant pour un joueur. Si vous en avez le courage, essayez donc de le transformer pour qu'il accepte plusieurs joueurs. La solution passe mon avis, par des listes... bien sr.

:: I1 :: La liste a du caractre
Vous voyez, je pense, ce qu'est un texte. Par exemple, la liste des commissions de la semaine : "Radis : 2 bottes, beurre : 1 plaquette, lessive : 1 baril". Ce n'est pas une liste trs complte, mais pour la comprhension de cette leon, cela devrait suffire. Mais surtout pour un programmeur, cette "liste" n'en est pas une. Ce n'est qu'un seul et mme texte. Il faudrait comprendre son sens pour dire qu'il s'agit d'une liste. AppleScript, mme s'il ne sait pas lire, nous mche le travail en nous permettant d'utiliser le vocabulaire des listes pour travailler sur notre texte. La petite diffrence est que l'on parle de "text item" au lieu d'item, sinon, tout le vocabulaire que nous avons appris dans la leon prcdente reste d'actualit. Regardons tout de suite ce que cela donne avec notre liste de commissions au format texte, en crant une vraie liste contenant tous ses "text item" :

-- Nos commissions dans une variable texte : set monTexte to "Radis : 2 bottes, beurre : 1 plaquette, lessive : 1 baril" -- tous les items de notre texte dans une liste : set maListe to text items of monTexte -- pour vrifier dans la fentre rsultat : maListe Avez-vous t curieux ? Vous avez normalement trouv ceci dans la variable maListe : {"R", "a", "d", "i", "s", " ", ":", " ", "2", " ", "b", "o", "t", "t", "e", "s", ",", " ", "b", "e", "u", "r", "r", "e", " ", ":", " ", "1", " ", "p", "l", "a", "q", "u", "e", "t", "t", "e", ",", " ", "l", "e", "s", "s", "i", "v", "e", " ", ":", " ", "1", " ", "b", "a", "r", "i", "l"} Un peu effrayant ? En y regardant de plus prs vous voyez qu'il s'agit simplement des lettres qui composent notre variable monTexte, entoures de guillemets et spares par des virgules : une liste de caractres. Si vous ne trouvez pas cela pratique, c'est que vous regardez le rsultat alors que je vous parlais de la similitude entre un texte et une liste ce qui rend l'apprentissage de la manipulation du texte plus facile.

:: I2 ::> De texte en liste, il n'y a qu'un dlimiteur.

Pour le cot pratique appliqu notre liste de courses, essayez ceci pour vous en convaincre : set text item delimiters to "," -- nos commissions dans une variable texte : set monTexte to "Radis : 2 bottes, beurre : 1 plaquette, lessive : 1 baril" -- tous les items de notre texte dans une liste : set maListe to text items of monTexte -- pour vrifier dans la fentre rsultat : maListe Cette fois-ci, le rsultat doit vous plaire davantage : {"Radis : 2 bottes", " beurre : 1 plaquette", " lessive : 1 baril"} On reconnat les accolades qui ouvrent et ferment une liste, puis, entre guillemets et spars par des virgules, trois textes cette fois : 1 pour chacune de nos commissions. Merci qui ? Merci le "text item delimiters" qui a apparu la premire ligne de code. Comme son nom l'indique en franais ;-), le "sparateur de texte" permet de dfinir quel endroit AppleScript doit donner des coups de ciseaux dans le texte (quand on lui demande de dcouper des morceaux). Ainsi, en dfinissant la virgule comme sparateur, l'appel aux items de notre texte a donn deux coup de ciseaux, aux endroits o se trouvaient les virgules, et nous a retourn les morceaux dans une liste. Notez que la ligne "set text item delimiters to ..." se place indiffremment aprs ou avant la dfinition des textes concerns mais avant de commencer travailler sur leurs "text item". Cette instruction n'a pas d'effet direct sur les variables de type texte. Elle change seulement une valeur (une proprit) qu'AppleScript conserve quelque part en attendant de servir. C'est par exemple l'instruction "set maListe to text items of monTexte" qui ira regarder la valeur du text item delimiters puis agira en consquence. Ce que nous avions obtenu lors de notre premier essai correspondait un sparateur de texte vide, un "". C'est la valeur par dfaut du "text item delimiters" l'ouverture d'AppleScript. En fait, en demandant directement les "items" d'un texte, on obtient la mme chose qu'avec les "text items" quand le sparateur est vide, car les seuls vrais "items" d'un texte restent toujours les caractres. Pour le vrifier, comparons le "count of" d'un texte et son "count text items of" avec l'exemple de notre liste : set monTexte to "Radis : 2 bottes, beurre : 1 plaquette, lessive : 1 baril" set text item delimiters to "," -- comptons les "items" : set nombreItems to count of monTexte -- comptons les "text items" : set nombreTextItems to count of text items of monTexte -- affichons le rsultat : display dialog "Dans : " & monTexte & return & "il y a " & nombreItems & " caractres" & return & "mais seulement " & nombreTextItems & " items spars par des virgules." On peut donner la valeur que l'on veut au sparateur de texte. Le vide pour travailler sur la liste des

caractres ; un caractre particulier comme le point, la virgule ou le retour chariot ; mais aussi un mot ou pourquoi pas toute une phrase. Voici quelques exemples pratiques, dans lesquels on suppose que la variable leTexte contient un texte trs long, par exemple ce cours d'AppleScript ;-) N'hsitez pas revenir au cours prcdent si vous n'avez pas encore mmoris toutes les instructions qui se rapportent la gestion des listes, sinon, les commentaires devraient vous suffire. -- avec le texte "la variable" comme item delimiter : set text item delimiters to "la variable" set nombre to count of text items of leTexte - 1 -- permet de compter le nombre de fois -- ou le texte "la variable" est rpt dans le texte -- NB : "-1" parce qu'il y a toujours 1 item de plus que de sparateurs -- donc si on veut compter les sparateurs, il faut enlever 1 -- si on veut compter les items, pas besoin. -- le point comme dlimiteur set text item delimiters to "." -- rcuprer une liste contenant les phrases du texte : set laListe to text items of leTexte -- compter le nombre de phrases : set nombrePhrases to count of laListe -- on aurait pu le faire en une seule ligne : set nombrePhrases to count of text items of leTexte -- rcuprer la troisime phrase du texte, trs simple : set phrase3 to text item 3 of leTexte -- avec "return" (=fin de paragraphe) comme text item delimiters set text item delimiters to return set laListe to text items of letexte set nouveauTexte to rest of laListe --permet de rcuprer le texte, moins le premier paragraphe

:: I3 ::> De liste en texte, c'est pareil.

Quand on sait transformer un texte en liste, on a trs vite besoin de faire l'inverse : transformer une liste en texte. Pour cela, on utilise la mthode du "transtypage" grce la formule de transformation "as string". Elle nous a dj servi transformer un nombre entier en texte et l'inverse avec "as number", elle va nous servir transformer des listes en textes. set maListe to {"Radis : 2 bottes", "Beurre : 1 plaquette", "Lessive : 1 baril"} set monTexte to maListe as string display dialog monTexte Ae... a marche probablement pour certains et a donne des choses curieuses pour d'autres ? Oui, en fonction de ce que vous avez utilis juste avant comme sparateur de texte, le rsultat peut tre surprenant car la valeur du sparateur est rest, et elle s'applique aussi dans ce sens en venant s'intercaler entre chacun des lments de la liste. Il aurait mieux valu crire : set maListe to {"Radis : 2 bottes", "Beurre : 1 plaquette", "Lessive : 1 baril"} set text item delimiters to ", " set monTexte to maListe as string display dialog monTexte Avec ces exemples, vous aurez compris que l'on peut trs facilement changer la forme d'un texte. Transformons notre liste de textes spars par des virgules en une autre ou les articles seront spars par des retours la ligne : set monTexte to "Radis : 2 bottes,Beurre : 1 plaquette,Lessive : 1 baril" -- tous les items de notre texte dans une liste : set text item delimiters to "," set maListe to text items of monTexte -- reformons un texte, mais spar par des retours chariot : set text item delimiters to return set nouveauTexte to maListe as string display dialog nouveauTexte

Notez au passage que l'inverse ne fonctionne pas : on ne passe pas d'un texte vers une liste en utilisant un "as list". Bien que l'expression fonctionne, elle ne donne pas le rsultat espr mais juste une liste contenant le texte intgral pour seul lment : set monTexte to "Radis : 2 bottes,Beurre : 1 plaquette,Lessive : 1 baril" set text item delimiters to "," set maListe to monTexte as list -- maListe = {"Radis : 2 bottes,Beurre : 1 plaquette,Lessive : 1 baril"}

:: I4 ::> De liste en liste, restons polis.

Nous venons de le voir, l'usage du text item delimiters est trs pratique. Certains prfrent travailler avec un sparateur ".", d'autres avec "," ou mme un "return". J'insiste parce que nous l'avons vu galement : l'usage du text item delimiters peut donner des rsultats trs surprenants si le sparateur n'est pas celui auquel on s'attend. Voici donc deux rgles simples : 1 - Tu dfiniras toujours ton text item delimiters avant de travailler sur des text items 2 - Tu remettras en partant, le dlimiteur que tu as trouv en arrivant. La rgle numro 2 est trs importante. Elle est vraie pour beaucoup d'autres proprits, pas seulement le "text item delimiters". Il s'agit d'un principe de scurit mettre en place souvent. Ne croyez pas qu'il s'agit seulement d'une politesse envers les autres programmeurs. "La rgle 1 est suffisante, les autres n'ont qu' la respecter." Oui, mais... les codes que vous crirez seront de plus en plus complexes. Au moment o un morceau de VOTRE code tourne, il y a souvent un autre morceau de VOTRE code qui tournait avant et qui tournera peut-tre aussi aprs, par exemple si vous tes l'intrieur d'une boucle repeat. Le principe dans ces cas-l est toujours le mme : on sauvegarde l'tat dans une variable auquel on donne un nom facile retenir, on dfinit ensuite son propre sparateur de textes, puis quand on a fini, on remet en place l'ancien sparateur. Voici un exemple, autour du code prcdent auquel j'ai enlev les commentaires : -- sauvegarde du sparateur : set ancienSeparateur to text item delimiters set set set set set monTexte to "Radis : 2 bottes, beurre : 1 plaquette, lessive : 1 baril" text item delimiters to "," maListe to text items of monTexte text item delimiters to return nouvelleListe to text items of monTexte

-- restauration du sparateur : set text item delimiters to ancienSeparateur display dialog nouvelleListe

:: J1 :: Une autre faon de voir la liste


L'inconvnient avec les items c'est qu'ils ne sont pas toujours simples atteindre. Avec les connaissances que vous avez dj dcouvertes dans les leons prcdentes, vous devriez pouvoir imaginer la situation suivante concernant la programmation d'un jeu (de roulette ? oui, par exemple ;-) Dans un jeu, il y a des joueurs. Donc, une liste de joueurs. Mais o ranger toutes les informations concernant chaque joueur ? Son nom, son score, son action en cours ? Rponse : dans une liste. Ce qui nous donne une liste de listes. Si nous sommes bien ordonns, nous rangerons toujours les informations concernant un joueur dans le mme ordre, et nous pourrons retrouver l'information dont nous avons besoin en demandant l'item correspondant dans la liste correspondant au joueur. Par exemple pour obtenir le score du troisime joueur, nous demanderons l'item 2 de l'item 3 de notre liste de listes. moins que ce ne soit l'item trois de l'item 2 de la liste de listes ? Voil ce que je voulais montrer. Mme bien range au bout d'un moment, les listes de listes, a s'embrouille et il faut continuellement retourner voir dans le code o l'on a rang les infos. Possible donc, mais pas trs pratique. AppleScript a mieux nous

proposer, je vous l'ai fait miroiter : l'enregistrement. N'ayez pas peur du mot, l encore c'est une chose trs simple. D'ailleurs, nous avons dj crois un enregistrement, rappelez-vous, c'tait la leon B. Le rsultat renvoy par une instruction display dialog. Cela se prsentait ainsi : {button returned:"OK"} et je vous avais alors brivement expliqu qu'il s'agissait d'un enregistrement de proprits. Ce qu'AppleScript peut faire? nous pouvons le faire. Il est temps pour moi de dvelopper.

:: J2 :: Des proprits, pour quoi faire ?

Une proprit, (comme button returned dans l'exemple prcdent) n'est rien d'autre qu'une variable qui porte un nom. Comment a, une variable aussi ? Vous avez raison de poser la question, mais il y a ici une diffrence qui n'est pas neutre. La proprit est "attache" quelque chose. Elle a donc un nom complet, un peu comme nous, un prnom et un nom. Les variables n'ont que le prnom, les proprits ont un nom de famille. Retournez voir l'usage que nous faisions du result de nos instructions display. Nous parlions toujours du "button returned of the result". Ou alors, nous copiions d'abord le result dans une variable, mais nous parlions toujours du button returned of maVariable. Le sens de "proprit" est double : on pourrait dire "particularit" mais galement, une proprit est toujours la "proprit" de quelqu'un.

:: J3 :: Les proprits de script

Nous pouvons dclarer une proprit de script ainsi : property maPropriete:"Proprit 1" Cette ligne dfinit une proprit qui s'appelle maPropriete, lui donne la valeur "Proprit 1". Comme rien d'autre n'est prcis, cette proprit appartient directement au script dans lequel elle est crite. Voici la faon thorique d'y accder ensuite ou de la modifier, en utilisant son prnom et nom de famille. property maPropriete:"Proprit 1" set maPropriete of me to "Proprit 2" display dialog maPropriete of me Le "of me" de ces lignes signifiant en franais " moi", comme si c'tait le script qui parlait de sa proprit. videmment, de la mme faon que l'on ne prcise pas le "of me" lors de la dclaration, AppleScript nous permet d'omettre le nom de famille pour les proprits de script. L'usage est alors identique celui des variables : c'est trs pratique, mais gardez bien en tte qu'il s'agit d'une facilit accorde par AppleScript. Dans certains cas complexes, vous serez obligs de prciser le "of me". Si vous avez besoin de le voir pour l'assimiler, voici ce que cela donne : property maPropriete:"Proprit 1" set maPropriete to "Proprit 2" display dialog maPropriete

:: J4 :: Une proprit persistante

Plus intressant pour les proprits de script : la persistance. Une proprit est dite persistante. Certains langages parlent de variables globales ou locales, ce n'est pas tout fait similaire, mais l'usage peut tre identique. Pour ceux qui n'ont jamais entendu parler de variables locales ou globales, oubliez de suite (oui, c'est un ordre). Les proprits restent uniques l'intrieur d'un script, nous verrons plus tard que ce n'est pas le cas des variables. Mais il y a plus fort : la persistance existe en dehors du code. NB 1 : Pour une fois, ce sont les utilisateurs antrieurs au systme mac os X qui seront favoriss : un script compil garde la trace des valeurs contenues dans une proprit entre deux usages. Pourquoi cela n'est plus le cas avec mac os X ? Pour des questions de principe : mac os X est un unix et l'unix pour tre trs protecteur, ne permet pas aux applications de se modifier elles-mmes. Du coup, Apple du revoir la persistance de ses proprits la baisse dommage. NB 2 : Depuis la parution de cet article, AppleScript a encore volu sur mac os X et la persistance des proprits est revenue. Et c'est tant mieux ! Vous pouvez visualiser cette persistance avec l'exemple ci-dessous : property compteur : 1 display dialog "Proprit : " & compteur

set compteur of me to (compteur of me) + 1 Lancez ce script : le message affiche 1. Relancez le : le message affiche 2, puis 3 etc. Tapez un espace la fin du code puis supprimez-le, cela oblige le script se recompiler et la prochaine tentative : le message redevient 1. Cela montre que tant que le script n'est pas recompil (modifi dans le code), la valeur de la proprit persiste. Mais ds qu'il y a intervention sur le code, la valeur initiale est redonne la proprit.

:: J5 :: Il est temps de reparler de liste

Les proprits ne sont pas rserves aux scripts. Elles peuvent tre attaches sous la forme d'une liste, comme celle du result de l'instruction display dialog. C'est ce genre de liste qu'AppleScript appelle un enregistrement. Le principe est simple : placer dans une variable une liste de proprits de la faon la plus classique qui soit : l'instruction set. Par exemple, si nous voulons crer un enregistrement pour y stocker des informations sur un joueur, nous pouvons crire : set leJoueur to {nom:"Nouveau Joueur", score:0, action:"Aucune"} La variable leJoueur contient 3 proprits. 2 sont de type texte : nom et action. Une de type nombre entier : score. Nous allons pouvoir accder trs facilement chaque information concernant le joueur : set leJoueur to {nom:"Nouveau Joueur",score:0, action:"Aucune"} set nom of lejoueur to "Alain" set score of leJoueur to 10 set action of leJoueur to "Pari" la suite de ce code, la variable leJoueur maintenant la valeur : {nom:"Alain",score:10, action:"Pari"} Cela nous simplifie normment la tache dans le cas d'une liste de joueurs, comme vous le montre l'exemple suivant. Je sais que cela fait pas mal de lignes et que je ne vous y ai plus habitu depuis quelques leons mais cela vous fera une bonne rvision. Le but est de crer une variable listeJoueurs (une liste) qui contient 4 joueurs (des enregistrements) avec des noms choisis par l'utilisateur. Ce script est basic, il ne gre pas les mauvaises rponses de l'utilisateur par exemple, mais il n'est l que pour vous montrer la facilit d'accs aux informations quand elles sont ranges dans un enregistrement. Je vous rassure si vous aimez la complexit, nous reprendrons bientt un exemple de jeu de roulette beaucoup plus complet que le prcdent et nous nous attacherons faire les choses de faon solide pour ne pas perdre notre utilisateur en cours de route. set listeJoueurs to {} -- je cre une liste vide set nouveauJoueur to {nom:"", score:0, action:"Aucune"} -- je me servirai de la variable nouveau joueur comme d'un modle -- je rpte 4 fois puisque je connais le nombre de joueurs repeat with rang from 1 to 4 -- je demande un nom l'utilisateur display dialog "Entrez le nom du joueur " & rang default answer "" -- je donne ce nom au modle de nouveau joueur set nom of nouveauJoueur to text returned of the result -- je fais une copie de ce modle la fin de la liste copy nouveauJoueur to the end of listeJoueurs end repeat -- j'affiche le rsultat dans une boucle repeat -- qui fonctionne de la mme faon que la prcdente repeat with rang from 1 to 4 display dialog nom of item rang of listeJoueurs end repeat

:: J6 :: Avantages contre inconvnients

Nous avions vu qu'AppleScript pouvait considrer du texte comme une liste, ce qui nous donnait la possibilit d'utiliser le mme vocabulaire pour travailler sur du texte ou des listes. Ce n'est plus le cas avec un enregistrement. En effet, la notion d'item est totalement oublie. Vous ne pourrez pas demander l'item 1 de {nom:"", score:0, action:"Aucune"}. Les "labels" (les prnoms des proprits) sont substitus aux items. Du coup, vous ne pouvez pas crire ceci : copy property rang:1 to the end of nouveauJoueur -- dommage, ca marche pas Pour rajouter une proprit supplmentaire un enregistrement dj cr, vous devez d'abord crer la proprit, ce qui veut dire lui donner un nom de famille, un propritaire, avant de runir les deux

enregistrements : set nouveauJoueur to {nom:"", score:0, action:"Aucune"} set rajout to {rang:1} set nouveauJoueur to nouveauJoueur & rajout Attention l encore : s'il y a dans chaque enregistrement que vous runissez une proprit qui porte le mme label, la valeur de la proprit de la deuxime (celle de droite) sera perdue dans la runion. Seule la valeur de celle de gauche sera conserve, car il ne peut pas y avoir deux proprits portant le mme nom. Suivez bien le mouvement : set nouveauJoueur to {nom:"", score:0, action:"Aucune"} set rajout to {score:10, rang:1} -- les deux enregistrements ont la proprit score en commun set nouveauJoueur to nouveauJoueur & rajout La valeur du score du nouveau joueur est toujours de 0. Un conseil donc si vous enrichissez de cette faon vos enregistrement, n'oubliez pas de placer l'enrichissement avant pour donner de nouvelles valeurs aux proprits. En remplaant la dernire ligne par set nouveauJoueur to rajout & nouveauJoueur la variable nouveau joueur reoit la fois une nouvelle proprit : le rang, mais aussi une nouvelle valeur pour son score : 10. Ah, un dernier dtail. Vous ne pouvez pas transformer un enregistrement en texte comme on peut le faire d'une liste, mme si toutes les proprits sont de type texte. Ce n'est qu'une demi mauvaise nouvelle, car vous pouvez transformer un enregistrement en liste. Donc en liste, puis en texte. Comme AppleScript autorise l'usage de plusieurs transtypages sur la mme ligne de code, vous pouvez "forcer" un enregistrement devenir du texte ainsi : set text item delimiters to "," -- vous alliez l'oublier celui-ci ? set nouveauJoueur to {nom:"Alain", score:0, action:"Aucune"} set auFormatTexte to nouveauJoueur as list as string display dialog auFormatTexte Rsultat : auFormattexte vaut : "Alain,0,Aucune" Si vous vous tes surpris penser "oui, mais l, j'ai perdu les labels" c'est que vous venez de rsumer tout l'intrt des labels face aux items, des enregistrements face aux listes. Et si vous en tes dus c'est que vous venez enfin de raliser que vous ne pourrez pas avoir la fois les items et les proprits ;-)

:: K1 :: Veuillez suivre mes instructions


Les instructions disponibles dans AppleScript sont limites. Elles ne font pas tout fait ce que nous recherchons voir pas du tout. Pourquoi ne pas apprendre AppleScript les instructions dont nous avons besoin ? Vous ne savez pas comment faire ? C'est tellement simple que vous ne risquez pas de l'oublier. Voyons voir un exemple : -- afficher la date au dbut du programme set montexte to (current date) as string -- obtenir la date courante au format texte display dialog "Nous sommes le : " & return & montexte -- afficher la date repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} if button returned of the result = "Quitter" then exit repeat end repeat -- afficher la date la fin du programme set montexte to (current date) as string display dialog "Nous sommes le : " & return & montexte Ce programme symbolique affiche la date puis se rpte btement jusqu' ce que l'utilisateur clique sur le bouton "Quitter". Enfin, il affiche de nouveau la date. Il y a l une rptition : les deux premires et les deux dernires lignes de code. Mais on ne peut pas rutiliser la variable monTexte sans la redfinir car la date (ou au moins l'heure) a chang. Oh, ce n'est pas un exemple complexe, mais tout de mme. Si AppleScript avait une commande pour afficher la date, ce serait dj mieux, nous pourrions crire :

afficherLaDate() repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} if button returned of the result = "Quitter" then exit repeat end repeat afficherLaDate() Si vous tes curieux, collez ce code dans l'diteur de script puis cliquez sur le bouton "Vrifier" (tout droite). Le texte se transforme, AppleScript l'accepte ! Et oui, AppleScript accepte des instructions qu'il ne connait pas. Mais si vous cliquez sur le bouton "Excuter", vous obtenez le message "Script ne comprend pas le message afficherLaDate". Oui, nous pouvons utiliser des instructions encore faut-il les dfinir. Voici le code pour cela, rien de mystrieux, je le commente aussitt. afficherLaDate() repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} if button returned of the result = "Quitter" then exit repeat end repeat afficherLaDate() on afficherLaDate() set laDate to (current date) as string display dialog "Nous sommes le : " & return & laDate end afficherLaDate J'ai rajout 4 lignes la fin du code. Vous pouvez maintenant coller le tout dans l'diteur de script, il voudra bien s'excuter. Ce que vous devez remarquer en premier, c'est que l'on commence par "on afficherLaDate" et que l'on termine par "end afficherLaDate". Cela devient presque classique, (surtout le end) : nous sommes en train d'ouvrir et de fermer une instruction compose, comme pour un if ou un repeat. Le "vrai" code est entre les deux. Ce ne sont que les lignes reprises sur le premier exemple, qui permettent de rcuprer la date au format texte puis de l'afficher. Qu'ai-je besoin d'expliquer davantage ? Le principe ? chaque fois qu'AppleScript trouve dans le code le nom de notre instruction, il le remplace par le code qui se trouve entre les lignes "on" et "end". Tout simplement. afficherLaDate() est donc un nouveau "mot" d'AppleScript, une instruction disponible n'importe o l'intrieur du script, et le code entre le "on" et le "end" est la dfinition du mot "afficherLaDate()".

:: K2 :: Pourquoi des parenthses ?

Bonne question. Vous avez remarqu que le nom de notre instruction est toujours suivi d'une parenthse ouvrante puis une fermante : (). quoi cela sert ? faire entrer des paramtres dans l'instruction. Tout comme l'instruction "display dialog" accepte des paramtres : buttons, default button, etc. nous pourrions avoir besoin d'envoyer nous aussi des paramtres dans notre fonction. Par exemple, dire "Bonjour" quand le programme se lance, dire "Au revoir" quand il se quitte. Nous pourrions faire un message particulier pour cela, mais pourquoi ne pas le faire au moment d'afficher la date ? Regardez comme c'est simple. afficherLaDate("Bonjour.") repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} if button returned of the result = "Quitter" then exit repeat end repeat afficherLaDate("Au revoir.") on afficherLaDate(leMessage) set laDate to (current date) as string display dialog leMessage & return & "Nous sommes le : " & return & laDate end afficherLaDate Il n'y a pas plus de lignes de code dans cet exemple que dans le prcdent. Mais maintenant, nos messages sont personnaliss. Regardez comment cela fonctionne :

Dans la premire ligne, j'ai crit, entre les parenthses de l'instruction, le texte qui me sert personnaliser mon message : "Bonjour." Je fais pareil dans la dernire ligne du code principal mais avec "Au revoir". Et voil. Comment mon instruction se dbrouille-t'elle pour utiliser le texte que je lui passe en paramtre ? Il suffit, entre les parenthses de sa dfinition de placer un "label". Tout simplement un nom que je choisis moi-mme, ici j'ai choisi leMessage. Puis je l'utilise ou je veux dans le code de mon instruction. chaque fois qu'AppleScript rencontrera ce nom, il le remplacera par le paramtre, "Bonjour" ou "Au revoir" selon le cas. Le principe est trs semblable celui des variables. Comment faire pour passer plusieurs paramtres une instruction ? Dans le code principal, en sparant les paramtres par des virgules. Dans le code de notre instruction, en sparant les labels par des virgules. Voici comment par exemple, on peut aussi personnaliser le bouton du message. afficherLaDate("Bonjour.", "Commencer") repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} if button returned of the result = "Quitter" then exit repeat end repeat afficherLaDate("Au revoir.", "A bientt") on afficherLaDate(leMessage, lebouton) set laDate to (current date) as string display dialog leMessage & return & "Nous sommes le : " & return & laDate buttons {leBouton} default button lebouton end afficherLaDate Pas besoin d'autres explications ? C'est bon signe ;-)

:: K3 :: La mme chose, mais autrement.

Personnellement, j'utilise la mthode prcdente, parce qu'elle me parat plus souple. Mais peut tre que c'est d ma pratique d'autres langages qui fonctionnaient ainsi. Voici une autre mthode qu'AppleScript propose. Elle permet d'viter l'usage des (), et de travailler un peu comme AppleScript, en nommant les paramtres. C'est, mon avis, trs bien pour les anglophones, mais peu intressant pour les petits franais. En fait, AppleScript nous offre toute une liste d'identificateurs (voir leon A !) de paramtres par dfaut. La voici : about, above, against, apart from, around, aside from, at, below, beneath, beside, between, by, for, from, instead of, into, on, onto, out of, over, since, thru (ou through), under. Comment les utiliser ? Vous en choisissez un (par paramtre) pour son "sens", puis vous vous en servez pour introduire votre paramtre. Reportez-vous au fonctionnement de l'instruction display dialog, ici c'est pareil. Et bien sr il faut utiliser la mme faon d'crire dans le code principal que dans le code de votre instruction. Par exemple, j'ai choisi d'utiliser le "for" : afficherLaDate for "Bonjour." repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} if button returned of the result = "Quitter" then exit repeat end repeat afficherLaDate for "Au revoir." on afficherLaDate for leMessage set laDate to (current date) as string display dialog leMessage & return & "Nous sommes le : " & return & laDate end afficherLaDate Comme vous le voyez, l'avantage est d'obtenir un code qui ressemble davantage de l'anglais pur. On peut alors imaginer des instructions avec des paramtres multiples et dont le sens serait vident : afficherLaDate from hier thru demain into leMessage -- au lieu de : afficherLaDate (hier,demain,leMessage)

Si vous trouvez l'un plus simple que l'autre utilisez-le, mais je continuerai dans ces articles utiliser la deuxime forme car j'y suis plus habitu, donc plus l'aise pour les explications.

:: K4 :: L'instruction, c'est dans quel ordre ?

Dans les exemples de cet article, j'ai plac le code principal en premier, puis le code de l'instruction. Est-ce une obligation ? Non. Vous pouvez trs bien crire les codes des instructions en premier, puis le code principal. Vous pouvez mme crire quelques lignes de code, puis une instruction, puis le reste du code principal. Attention, il y a une limite : vous ne pouvez pas crire le code d'une instruction l'intrieur d'une autre instruction compose, comme les "if", "repeat", etc. Cela veut dire que ceci fonctionne : afficherLaDate for "Bonjour." repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} if button returned of the result = "Quitter" then exit repeat end repeat on afficherLaDate for leMessage set laDate to (current date) as string display dialog leMessage & return & "Nous sommes le : " & return & laDate end afficherLaDate afficherLaDate for "Au revoir." Mais cela ne fonctionne pas : afficherLaDate for "Bonjour." repeat -- un repeat symbolique display dialog "Ce programme ne sert rien" buttons {"Quitter", "Continuer"} on afficherLaDate for leMessage set laDate to (current date) as string display dialog leMessage & return & "Nous sommes le : " & return & laDate end afficherLaDate if button returned of the result = "Quitter" then exit repeat end repeat afficherLaDate for "Au revoir." J'espre de toute faon que cela ne vous drange pas, car l'intrt majeur d'crire ses propres instructions, c'est de simplifier son code. Inutile alors de l'entrecouper par les dfinitions des instructions. La rgle la plus simple est de garder le code principal simplifi au dbut et de placer les dfinitions des instructions la fin.

:: L1 :: Pratiquons d'abord...
Avant de risquer de vous perdre dans la thorie, je prfre vous montrer de quoi nous allons parler par l'exemple. Histoire de vous prouver encore une fois que c'est simple. Vous savez maintenant comment apprendre AppleScript une nouvelle instruction, et je vous ai rappel que certaines instructions d'AppleScript, par exemple l'instruction Display dialog, permettent de rcuprer un rsultat grce une variable ? proprit ? qui s'appelle the result. Tout est dit, il ne vous manque que l'instruction elle mme qui s'appelle "return", ne pas confondre avec le return qui permet d'aller la ligne dans du texte. Il faut mettre derrire l'instruction return la valeur que l'on veut renvoyer au programme principal. Exemple, inutile mais je pense assez clair, si l'on veut avoir une instruction qui renvoi toujours la valeur 2, appelons la "deux()", elle s'crit ainsi : -- Mon instruction qui renvoie la valeur 2 on deux() return 2 end deux

-- code principal deux() set leResultat to the result display dialog leResultat Vous devez suivre sans problme ce qui se passe ici, sinon relisez l'article B et comparez ces lignes avec celles o nous avons dcouvert les rsultats de l'instruction display dialog. Elles sont identiques. L'instruction deux() se termine par l'instruction return 2, ce qui fait que quand deux() est utilis dans le code principal, notre instruction renvoie la valeur 2, qui atterrit dans la variable the result. On peut donc la rcuprer dans une variable pour l'exploiter selon nos besoins. Rappelez-vous (ou relisez) la fin de la leon B. Je vous disais, pour ceux qui taient les plus l'aise, que l'on pouvait sur la mme ligne, placer le rsultat de l'instruction dans une variable. Dans le cas prsent, cela simplifie beaucoup notre code principal. Voici la ligne quivalente nos deux premires lignes de code principal : set leResultat to deux() Tout le monde est l'aise maintenant avec cette faon de l'crire ? videmment, cette formulation n'utilise plus la variable the Result, mais il faut bien comprendre que deux() est remplac par son rsultat, et que c'est ce rsultat qui est plac dans notre variable. C'est simple, c'est tellement vident que vous n'en voyez srement pas encore tout l'intrt. Je passe donc la thorie.

:: L2 :: ...thorisons ensuite

Il est vraiment intressant ce "the result" et avant de le faire disparatre de nos lignes de codes, essayons de bien comprendre de quoi il s'agit. Pas vraiment une variable, plus proche d'une proprit, c'est plus simplement un "mot" pour dsigner un principe de fonctionnement de tous les langages. je vais essayer d'tre simple. Je vous rassure, ce n'est pas complexe comme ide, c'est plutt le choix des mots pour en parler qui est difficile. Alors, si vous vous sentez un peu perdus dans mes explications, ne tranez pas ici, passez au paragraphe suivant, vous n'aurez rien perdu d'important, mais si vous tes curieux de savoir comment tout cela marche, jetez un coup d'il dj sur ceci : set quatre to 2 + 2 -- je mets 4 dans une variable display dialog the result -- le rsultat vaut 4 ! La premire ligne de code mets la valeur de 2 + 2 (donc 4) dans une variable qui s'appelle quatre. La suivante affiche un message qui nous apprend que "the result" vaut 4 ! a vous tonne ? Non, pas trop ? Vous croyez que the result prend la valeur de la variable quatre ? Ce n'est pas tout fait a. Enlevons des morceaux dans ce code, voyons ce qui se passe. 2 + 2 -- je fais juste une addition, sans l'associer une variable display dialog the result -- le rsultat vaut 4 ! The result prendrait donc la valeur de l'addition ? C'est presque a, mais vous n'tes pas au bout de vos surprises : 2 -- je ne peut pas faire plus simple display dialog the result -- le rsultat vaut 2 ! a y est, vous y tes. La valeur de the result est la dernire valeur qui trane. Je tente de vous expliquer cela : en programmation, on demande l'ordinateur de raliser des travaux. Celui-ci voit dbarquer la totalit du code, et tout son travail va tre de rsoudre le tout en remplaant chaque morceau par des valeurs. La premire chose qu'il fait, c'est de sparer le code en morceaux. Il a pour cela diffrents sparateurs, les retours chariots qui sparent nos lignes de codes, les parenthses : (), les signes d'oprations +, - par exemple. Ces sparateurs ont un ordre prcis. En premier, les retours chariot. Notre programme spare donc les lignes puis regarde dans la premire pour voir s'il s'agit d'une valeur. Sinon, il regarde s'il y trouve un sparateur de moindre importance : par exemple des (), oui ? il regarde l'intrieur. Il y trouve une opration ? Il coupe et regarde de chaque cot. Enfin, une valeur. Il n'y a plus qu' remonter dans cette hirarchie. Pour ne pas perdre cette valeur, il la pose sur son espace de travail, son bureau, si l'image vous convient mais les programmeurs eux, parlent de la pile. Le programme remonte alors pour voir ce qu'on lui demande de faire. Dans le dernier exemple de code, on ne lui demandait rien du tout. Le "2" tait pos l, et le programme l'a donc dpos sur sa pile. J'aurais crit : 2 4

display dialog the result Le 2 aurait t recouvert par un 4 sans avoir servi. Et the result aurait pris la valeur 4, car c'est tout simplement a, the result : c'est le dessus de la pile. Et tout simplement galement, quand on demande une instruction de renvoyer une valeur : "return 2", on demande juste au programme de mettre cette valeur sur la pile. Puis qu'elle s'y trouve, on peut en faire ce que l'on veut. Quand on crivait : set maVariable to 2 "to" est un sparateur pour l'ordinateur. Il regarde sa droite : trouve 2 et le mets sur sa pile. Il remonte vers la surface des instructions, voit qu'on lui demande de ranger dans un bout de mmoire : "set maVariable", il range quoi dedans ? Oui, le dessus de sa pile. Et quand on crit set maVariable to deux(), c'est le mme phnomne. Le programme regarde droite du "to", trouve une instruction, comme ce n'est pas une valeur, il va voir dedans ce qu'il y a. Si le dernier morceau de cette instruction dpose une valeur sur la pile grce l'instruction return, le programme sera content de trouver une valeur, reviendra en arrire, regardera droite du "to" et se dira : on me demande de ranger dans un morceau de mmoire. Je range quoi ? Le dessus de la pile. C'tait quoi ? Pas besoin de m'en rappeler, je sais que c'est sur la pile. Le principe est simple et diablement efficace pour un ordinateur qui, quoi que vous pensiez peut-tre, ne sait jamais faire qu'une seule chose la fois. J'espre que vous ne pensez pas que je vous prend pour des simplets, si mes explications vous semblent couler de source. Ou plutt si, car ce serait la preuve que je vous ai fait passer quelque chose que j'ai mis longtemps comprendre, que certains amis programmeurs n'ont pas forcment bien compris et qui a pourtant son intrt. Car quand on a compris que l'on ne fait que manipuler des dessus de pile, on peut crire ceci : set maVariable to deux() + deux() Mais oui, j'additionne deux dessus de pile, et je range le tout dans une variable. C'est tout de mme plus simple que d'crire : deux() set maVariable to the result deux() set maVariable to maVariable + the result En fait une instruction contenant une instruction return DEVIENT, aux yeux du programme, la valeur donne en paramtre au return. On peut mme crire ceci : on deux() return 2 end deux on double(nombre) return (nombre * nombre) end double -- un exemple d'utilisation de l'instruction "double" : set maVariable to double(2) -- maVariable vaut quatre -- mais ca marche de la mme faon ici : set maVariable to double(deux()) -- maVariable vaut quatre aussi La premire instruction, vous la connaissez. La deuxime, "double()", reoit un paramtre( un dessus de pile), l'appelle "nombre", et mets le double de ce nombre sur la pile ! suivre, un exemple d'utilisation : 2 est dpos sur la pile, entrant dans "double() sous le nom de "nombre". L'instruction dpose donc 2 x 2 (soit 4) sur la pile. Et le dessus de pile est rang dans la variable maVariable. Bien sr, on peut le dire sans parler du dessus de pile, mais je veux mettre en avant le principe de fonctionnement. Si vous avez bien suivi mon histoire de pile, la ligne suivante n'est pas plus complique : au lieu du nombre 2, c'est l'instruction deux() qui doit rentrer dans l'instruction double() sous le nom de "nombre". Pour le programme, deux() n'tant pas une valeur, il cherche l'valuer, morceaux par morceaux. Au final, on lui dit de mettre 2 sur la pile, il se retire et c'est le dessus de la pile qui rentre dans l'instruction double(). Je ne vous explique pas la suite, elle est identique.

:: L3 :: Un peu plus de vocabulaire...


Pour commencer, je vais maintenant utiliser un peu de vocabulaire pour diffrencier les instructions qui renvoient une valeur (avec un return quelqueChose) et celles qui ne retournent rien, que nous avons vues la leon prcdente. Celles-ci s'appellent des procdures. Alors qu'une instruction qui renvoie une valeur s'appelle une fonction. NB : Les procdures dposent forcment quelque chose sur la pile de travail, car l'ordinateur ne sait pas comment faire autrement pour travailler. Mais AppleScript surveille, et sans l'utilisation d'un return, vous ne pourrez pas accder ce dessus de pile. Ce que je veut dire en clair, c'est que : on deux() 2 end deux et on deux() return 2 end deux devraient tre quivalents, mais AppleScript veille au grain, et vous ne pourrez pas exploiter le "the result" de la premire version.

:: L4 :: Plus de prcision :

L'instruction "return" est puissante car elle termine dfinitivement la fonction en cours, mme si il reste des instructions l'intrieur de celle-ci. Par exemple : on deux() return 2 beep end deux Cette instruction ne bipera pas, car ds que le programme rencontre l'instruction return, il quitte la fonction deux(). Cela n'tonnera pas ceux qui ont suivi mon histoire de pile : en effet, l'ordinateur ne peut vraiment rien faire sans sa pile. Si on lui demande de mettre quelque chose dessus, il doit aussitt quitter pour que cette valeur puisse tre utilis avant d'tre recouvert. De toute faon, cela nous arrange dans la plupart des cas. Par exemple si l'on veut une fonction qui nous retourne le nombre le plus grand entre deux valeurs qu'on lui passe en paramtre, on pourrait crire : on lePlusGrand(nombre1, nombre2) if (nombre1 > nombre2) then return nombre1 else return nombre2 end if end lePlusGrand Mais on peut crire sans problmes : on lePlusGrand(nombre1, nombre2) if (nombre1 > nombre2) then return nombre1 return nombre2 end lePlusGrand Puisque si le nombre 1 est le plus grand, le programme ne passera pas par la deuxime ligne. Je vous en ai donn le code principal la fin de l'article prcdent, le revoil : introduction() repeat while inscriptions() repeat while parier() gagner() end repeat scores()

nettoyage() end repeat quitter()

:: M1 :: Dcryptons
Ces quelques lignes forment rellement le code principal de notre programme. Maintenant que vous tes familier des instructions repeat, vous pouvez comprendre ce code juste en le lisant. Il s'agit d'une suite d'instructions, en franais, qui videmment n'existent pas encore et que nous devrons crire, mais elles nous permettent d'avoir une ide globale de notre programme. Nous pourrons les crire ensuite, morceau par morceau. instructions(), gagner(), scores(), nettoyage() et quitter() sont des instructions qui ne nous ramnent pas de valeur. Ce seront donc des procdures. introduction() et parier() sont utilises comme test de nos 2 repeat. elles doivent donc prendre une valeur boolenne, en se terminant par un "return false" ou "return true". Ne vous inquitez pas si vous suivez difficilement l'intrt de la chose, j'en reparlerai plus tard. Car avant de dcortiquer cette structure, ce squelette de programme, laissez-moi vous dire comment j'en suis arriv l. C'est important pour bien progresser.

:: M2 :: Des ides dans un cahier

Avant de programmer "srieusement", il faut beaucoup rflchir. Se lancer dans l'aventure sans s'y prparer est pour certains un plaisir suffisant, mais on risque de se lasser assez vite si l'on ne parvient pas ses fins, si l'on bloque dans une impasse et que l'on doit tout recommencer depuis le dbut. Rflchir ? Oui mais comment ? Tout dpend de la complexit de ce que vous voulez entreprendre, mais sinon, il y a 3 tapes. La premire consiste noter toutes les ides concernant le projet, en vrac. Par exemple, notre programme de roulette. Comment je vois la chose ? Et bien, il doit tre jouable plusieurs, chaque joueur pariant sur un chiffre de 1 8, et sur pair ou impair. Ensuite la roue tourne, la bille dsigne un nombre et l'on rpartit les gains. Puis a recommence tant qu'on a des sous miser. Quand plus personne ne peut miser, la partie est finie. On affiche les meilleurs scores, puis on recommence moins que le joueur veuille quitter le jeu. a serait bien si le programme se rappelait du nom des joueurs pour ne pas avoir le retaper chaque fois. Voil pour l'ide gnrale du programme. partir de cela, il faut rdiger plus clairement la demande. Dans le mtier, et dans d'autres, cela s'appelle le "cahier des charges". C'est normalement le document de rfrence pour pouvoir s'arrter de programmer et dire : "Voil le programme qui rpond la demande". Ce n'est malheureusement jamais le cas, car il y a toujours des dcouvertes, des oublis qui font que le dveloppement doit aller plus loin que le cahier des charges. Mais ne dsesprons pas, essayons avec notre roulette.

:: M3 :: Un cahier bien rang

- Le programme "Mini-Roulette" est un jeu dont la rgle est la suivante : - 1 8 joueurs peuvent s'inscrire en dbut de partie. Les inscriptions ne peuvent pas tre prises en cours de partie. - Chaque joueur, lors de l'inscription, reoit un pcule de 10 points qui lui servira miser. - La banque dbute la 1e partie avec un pcule de 50 points. - Ensuite commence le 1er tour : - Chaque joueur doit faire 2 paris, nomms A et B - Le pari A consiste choisir un nombre entre 1 et 8 - Le pari B consiste choisir entre pair et impair. - Pour chaque pari A et B, le joueur mise un point de son pcule qu'il dpose sur le tapis. - Les joueurs ont la possibilit de s'abstenir de parier (A, B ou les 2), mais si aucun joueur ne parie, la partie se termine. - Les paris termins, une valeur est tire au hasard de 0 8. - Si le tirage tombe sur zro, la banque est seul bnficiaire du tapi (les sommes mises).

- Si le tirage n'est pas zro, la banque vrifie les paris des joueurs. - Si le joueur a mis sur la bonne valeur au pari A, il reoit 8 points qui s'ajoutent son pcule - Si le joueur a mis pair et que le tirage est pair, ou s'il a pari impair et que le tirage est impair, il reoit 2 points qui s'ajoutent son pcule. - Si le joueur n'a pas pari, il ne reoit pas de point. - Les points redistribus sont pris en priorit sur le tapis. - Si le tapis est suffisant, les points restants s'ajoutent au pcule de la banque. - Si le tapis n'est pas suffisant, les points sont pris sur le pcule de la banque. - Le tour de jeu est termin. - ce stade, si l'un des joueurs n'a plus de points (pcule = zro), il se retire. - Si le pcule de la banque est ngatif, la partie est termine, la Banque saute. - On peut ici afficher les pcules des joueurs et de la banque et proposer au(x) joueur(s) de s'arrter ou de continuer un nouveau tour et ceci, jusqu' ce qu'il n'y ait plus de joueurs dans le jeu, auquel cas, la partie est galement termine. - Quand la partie est finie, les meilleurs scores sont affichs. - Puis les joueurs ont la possibilit de quitter le programme ou de relancer une partie, auquel cas les inscriptions sont relances. - Un joueur dj inscrit dans une ancienne partie dont le pcule est infrieur 10 points reoit des points pour atteindre nouveau 10. Un joueur dj inscrit dont le pcule est suprieur dix garde son pcule. - La banque, elle, remet son pcule 50 points quel que soit son pcule en fin de partie prcdente. Ouf, pas trs intressant tout cela ? Vous devez pourtant vous rendre compte la lecture, que tout cela aura de l'importance un moment ou un autre pour l'criture du code de notre programme. Alors, autant le savoir l'avance. Bien sr, si vous tes simplement un curieux dcouvrant la programmation, c'est vous d'crire ce cahier des charges. Mais il n'y a pas besoin de connaissances particulires en programmation pour l'crire. Tout le monde peut le faire, et pour le professionnel c'est souvent le client qui crit le cahier des charges ou bien ils l'crivent en commun. L'tape suivante, elle, demande des connaissances en programmation.

:: M4 :: Le cahier devient "algorithme"

Encore un mot trange pour parler de quelque chose de simple, que vous avez dj dcouvert. Pourquoi vous inquiter ? Je vous ai habitu vous expliquer les choses avant de les nommer par leur nom technique. C'est le cas l aussi :-) . L'algorithme, c'est tout simplement le squelette. L'algorithme de notre programme de miniroulette, c'est a : ALGORITHME introduction() repeat while inscriptions() repeat while parier() gagner() end repeat scores() nettoyage() end repeat quitter() Les pros qui lisent ces articles critiqueront peut-tre le fait qu'il est simpliste, c'est vrai. On peut crire un algorithme plus dtaill. Mais petits pas, vous verrez qu'on peut dj aller loin, mme si l'on dbute. Une autre critique plus srieuse : un algorithme ne s'crit pas dans un langage de programmation mais dans le langage courant. Cela permet, dans un travail en groupe par exemple, de laisser le choix du langage celui qui tape le code. Ou de rutiliser l'algorithme pour dvelopper le mme programme sur une autre machine (un PC ?) avec un autre langage. Essayons, et voyons en mme temps comment on passe du cahier des charges l'algorithme. Il y a d'abord, dans la plupart des programmes une premire partie qui sert initialiser les donnes (variables,

proprits, etc). On peut y caser aussi, tout ce qui n'a pas de lien direct avec le droulement du programme, moi j'y case la plupart du temps un message de bienvenue, et la possibilit d'accder aux prfrences, la rgle du jeu. a sera le cas avec la mini-roulette, mme si ce n'est pas dans le cahier des charges, cela va de soi. EXEMPLE -- algorithme initialisations et options diverses Ensuite, on attaque la premire partie. Le rflexe du programmeur : je vois dans le cahier des charges que l'utilisateur devra pouvoir relancer une nouvelle partie sans avoir besoin de quitter le programme. C'est donc une boucle repeat. Mais quel repeat ? Disons ternel pour l'instant. Dans chaque partie, il y a d'abord les inscriptions. Ensuite on lance et on relance la roulette (les paris puis les gains) jusqu' ce qu' la fin de la partie. C'est donc encore un repeat. Puis on affiche les meilleurs scores. Dans le langage courant : EXEMPLE -- algorithme initialisations et options diverses rpte la partie inscription des joueurs rpte le tour de roulette prendre les paris des joueurs distribuer les gains fin du rpte le tour de roulette afficher les meilleurs scores fin du rpte la partie C'est dj assez clair, et assez proche du langage AppleScript. Ce qui nous manque, et c'est trs important, ce sont les conditions de sortie des boucles repeat. Pour le premier, la chose est assez simple. Peu importe la faon dont la partie prcdente s'est termine, les deux conditions qui peuvent empcher une nouvelle partie sont : - l'utilisateur ne veut plus jouer, il faut lui demander son avis un moment ou a un autre. - l'utilisateur n'a inscrit aucun joueur, c'est qu'il ne veut plus jouer (?) mon avis, je peux runir ces deux test au moment des inscriptions. Une faon de l'crire : EXEMPLE -- algorithme initialisations et options diverses rpte la partie inscription des joueurs s'il n'y a pas d'inscrits ou que l'utilisateur veut s'arrter alors sortir du rpte la partie fin du si rpte le tour de roulette prendre les paris des joueurs distribuer les gains fin du rpte le tour de roulette afficher les meilleurs scores fin du rpte la partie Mais avec un peu de pratique, je me dis que je pourrai faire tout cela au moment des inscriptions. En faisant une instruction de type fonction je renverrai une valeur, vrai ou faux, pour dire si les inscriptions se sont bien passes ou non. Si je peux faire a, alors je peux crire un "rpte tant que" au lieu d'un "rpte ternel". EXEMPLE -- algorithme

initialisations et options diverses rpte la partie tant que les inscriptions se passent bien rpte le tour de roulette prendre les paris des joueurs distribuer les gains fin du rpte le tour de roulette afficher les meilleurs scores fin du rpte la partie J'ai pass un peu plus de temps rflchir sur les diffrentes causes qui peuvent terminer la partie. Toutes ces causes doivent pouvoir faire sortir du deuxime "rpte". J'ai trouv : - plus aucun joueur n'a de pcule, - plus de pcule la banque, - aucun joueur n'a pari. Je pense que ces trois conditions, je pourrai les vrifier au moment du pari. Je peux crire sur le mme principe que pour le premier "rpte" : EXEMPLE -- algorithme initialisations et options diverses rpte la partie tant que les inscriptions se passent bien rpte tant qu'il y a des paris distribuer les gains fin du rpte afficher les meilleurs scores fin du rpte la partie La pratique aidant, je sais aussi qu'il faudra bien que je fasse un peu de rangement dans mes donnes, entre chaque partie. Je vais donc l'crire juste aprs l'affichage des meilleurs scores. Ah ! J'oubliais aussi quelque chose de trs important, tellement vident que je l'oublie souvent et je ne suis pas le seul. Pourquoi est-ce que je sors du premier repeat ? Parce que l'utilisateur veut quitter. videmment, si mon programme ne fait plus rien, c'est presque pareil. Mais presque pareil, ce n'est pas suffisant. Il vaut mieux de toute faon s'occuper nous-mmes de quitter le programme et faire un dernier rangement. Ce qui donne : -- algorithme initialisations et options diverses rpte la partie tant que les inscriptions se passent bien rpte tant qu'il y a des paris distribuer les gains fin du rpte afficher les meilleurs scores faire le mnage ncessaire fin du rpte la partie quitter le programme proprement Et voil, comparez maintenant cet algorithme en franais courant et celui crit en AppleScript, vous devriez tout comprendre. vous de choisir comment vous prfrez crire vos algorithmes, mais une chose est sre et certaine : crivez les.

:: N1 :: Du plus simple...
Pour nous permettre de lancer notre programme, il faut apprendre AppleScript ce qu'il doit faire quand il rencontre une de nos instructions. La mthode est simple, contentons nous pour l'instant de lui dire de ne rien faire. Une dclaration vide de code : un "on monInstruction" suivi d'un "end monInstruction". Cela nous donne : introduction() repeat while inscriptions() repeat while parier()

gagner() end repeat scores() nettoyage() end repeat quitter() on introduction() end introduction on inscriptions() end inscriptions on parier() end parier on scores() end scores on nettoyage() end nettoyage on quitter() end quitter Lancez le script, votre programme se droule normalement... C'est--dire qu'il ne se passe rien. C'est une premire russite, mais le fait de ne pas avoir de message d'erreur n'est pas suffisant pour tre certain du bon droulement du programme. Pour suivre ce qui se passe, nous allons insrer dans chacune de nos instructions un message qui nous dira l ou nous en sommes. Excution : introduction() repeat while inscriptions() repeat while parier() gagner() end repeat scores() nettoyage() nettoyage() end repeat quitter() on introduction() display dialog "Introduction" buttons {"OK"} end introduction on inscriptions() display dialog "Inscriptions" buttons {"OK"} end inscriptions on parier() display dialog "Parier" buttons {"OK"} end parier on gagner() display dialog "Gagner" buttons {"OK"} end gagner

on scores() display dialog "Scores" buttons {"OK"} end scores on nettoyage() display dialog "Nettoyage" buttons {"OK"} end nettoyage on quitter() display dialog "Quitter" buttons {"OK"} end quitter Testez... :-)

:: N2 :: ... Au plus compliqu

Que se passe-t-il ? Nous obtenons les messages : "Introduction", "Inscriptions"... "Quitter" Oui, c'est un peu court n'est-ce pas. Le programme est interrompu au moment des inscriptions et reprend avec l'instruction "Quitter". Que se passe-t'il dans notre code principal au moment des inscriptions ? Nous lanons une boucle repeat "while". Ce qu'AppleScript attend dans ce genre de repeat, c'est une valeur boolenne (un VRAI ou un FAUX) qui lui permettrait de prendre sa dcision : continuer ou arrter la boucle. la place de cette valeur, j'ai mis la fonction "Inscriptions" en me disant que je dciderai dans cette dernire s'il faut lancer une nouvelle partie ou non. Si oui, je ferai un "return TRUE", sinon, je ferai un return "FALSE". Mais pour l'instant, ma fonction ne renvoie rien pour une raison simple : je ne l'ai pas encore crite. Alors, en l'absence d'une rponse "VRAI" AppleScript considre tous les autres cas comme faux. Votre premire ide si vous suivez bien, devrait tre alors d'insrer une ligne "return true" dans la fonction "Inscriptions"... pourquoi pas, mais alors rappelez vous que le raccourci pour arrter une boucle ternelle est "Pomme- Majuscule-Point" :-) car c'est ce qui va se produire. Si la fonction renvoie toujours "VRAI", la boucle repeat ne s'arrtera jamais. Il faut ruser un peu pour trouver une solution pour notre squelette, sans avoir se lancer dj dans la version complte du code. J'utilise trs souvent ce genre de construction et je le rgle ainsi. on inscriptions() display dialog "Inscriptions" buttons {"Arrter", "Continuer"} default button "Continuer" if (button returned of the result = "Continuer") then return true else return false end if end inscriptions Lancez, cette fois, le message "Inscriptions" vous demande si vous voulez continuer ou vous arrter. la ligne de code suivante, le programme vrifie : si vous avez cliqu "Continuer", il renvoie "true", sinon, il renvoie false. Une faon plus simple de l'crire, si vous tes l'aise avec les boolens, est la suivante : on inscriptions() display dialog "Inscriptions" buttons {"Arrter", "Continuer"} default button "Continuer" return (button returned of the result = "Continuer") end inscriptions L'astuce que l'on utilise souvent en programmation est d'affirmer une galit. Cette affirmation sera soit vraie, soit fausse, selon que l'utilisateur aura bien cliqu sur "Continuer" ou non. On peut donc l'utiliser comme un boolen, sans connatre sa valeur. Dans notre exemple, si l'utilisateur a vraiment cliqu sur "Continuer", alors (button returned = "Continuer") est vrai, et la valeur "true" sera renvoye vers le programme principal. S'il a cliqu sur "Arrter", alors (button returned = "Continuer") est faux, et la valeur "false" sera retourne vers le programme principal. C'est exactement le mme rsultat que celui de l'exemple de code prcdent, mais sur 2 lignes au lieu de 6. videmment, ce n'est pas toujours une bonne chose de compter les lignes, mais la matrise de la logique des boolens est assez importante pour que vous fassiez l'effort de la comprendre.

:: N3 :: Retour vers la pile...


Ce paragraphe fait suite au chapitre L - 2, une histoire de pile. Vous vous souvenez ? J'y reviens juste pour profiter de l'exemple prcdent. L encore, il ne s'agit que de curiosit, si vous ne vous sentez pas l'aise avec les grandes thories, passez directement en N - 4, vous n'aurez rien perdu. Pour les autres, remplacez la fonction inscriptions par celle-ci (c'est la deuxime ligne du code qui change) on inscriptions() display dialog "Inscriptions" buttons {"Arrter", "Continuer"} default button "Continuer" button returned of the result = "Continuer" end inscription Et oui, j'ai supprim l'utilisation du return. Mais testez, vous verrez, cela fonctionne. Car AppleScript ne surveille pas trs bien l'usage du return. Il ne le surveille que si l'on veut explicitement appeler la variable "the result". Dans notre cas, on ne passe pas par "the result". AppleScript regarde simplement s'il y a un "true" sur le dessus de la pile. Incidence trange, notre fonction "inscriptions" n'en est plus une. Pour AppleScript, il s'agit d'une procdure. Mais une procdure qui est tout de mme utilise comme valeur boolenne, donc une fonction, heu? A vrai dire, il n'y a pas de diffrence entre une procdure et une fonction. Seul l'usage que l'on en fait compte. Maintenant, ne prenez pas pour habitude de vous passer de l'instruction "return". Il vaut toujours mieux suivre la rgle du jeu, d'autant plus qu'Apple pourrait bien un jour renforcer la vrification de l'usage du return et votre programme deviendrait incompatible. Je vous l'avais dit, ce paragraphe n'tait qu'une parenthse pour les curieux ;-)

:: N4 :: Mme symptme, mme remde

Revenons notre squelette. Cette fois ci, il fonctionne, mais il bote un peu. Regardez bien : nous ne passons toujours pas par la case gagner. La cause est toujours la mme : l'instruction "Parier" est utilise comme valeur boolenne du repeat while suivant. Mme cause, mme rponse : on parier() display dialog "Parier" buttons {"Arrter", "Continuer"} default button "Continuer" return (button returned of the result = "Continuer") end parier Et voil, notre squelette fonctionne cette fois parfaitement. Avec beaucoup d'imagination videmment, vous pouvez dj vous y croire, de pari en pari et de partie en partie. Vus voyez que c'tait simple, et que cela ne nous a pas pris beaucoup de temps crire. C'est pourtant la mthode la plus efficace pour commencer l'criture d'un programme. Elle permet de vrifier rapidement si l'algorithme est viable et le terrain est maintenant tout prt pour que l'on puisse crire chaque fonction et procdure en voyant aussitt notre programme prendre forme.

:: O1 :: Une dco "standard"


Dans notre programme, nous allons tre amens crire souvent des instructions "display dialog". Elles seront longues crire, alors qu'une grande partie en sera commune. De plus, nous voudrions donner un peu de style notre programme, comme une en-tte commune tous nos messages. Quelque chose comme ceci : Par exemple : display dialog "Mini-Roulette : Inscription des joueurs" & return & "Entrez votre nom :" default answer "" buttons {"OK"} default button "OK" C'est long n'est-ce pas ? Et nous allons devoir le faire souvent. Mini-Roulette est le nom de notre programme, nous pourrions faire un effort pour le connaitre tout le temps. "Inscription des joueurs", c'est l'action en cours. L aussi, on pourrait l'crire une bonne fois pour toute dans chaque tape principale de notre code. De mme, default answer, buttons et default buttons vont revenir a chaque instant. Seul "Entrez votre nom" est un message qui sert exclusiment cet instant l du code. En faisant un effort, je pourrais donc rduire cette ligne de code l'appel d'une fonction telle que : affiche("Entrez-votre nom :") Cela serait beaucoup plus simple, plus clair, n'est-ce pas ? Et bien, on va le faire. property jeu :{ nom :"Mini-Roulette", action :"Inscription des joueurs"} -- un exemple

d'utilisation de notre fonction affiche("Entrez-votre nom :") -- notre fonction on affiche(message) display dialog nom of jeu & " : " & action of jeu & return & message default answer "" buttons {"OK"} default button "OK" end Voil, c'est fait. Je vous explique avant de compliquer notre fonction : Premire ligne : je cre une proprit de script, qui contient elle mme deux proprits : son nom et l'action en cours. L'intret d'utiliser une prorit, rappelez-vous, c'est qu'elle est persistante. Grce cela, nous pourrons l'appeler de n'importe quel endroit de notre script, ce qui n'est pas le cas d'une variable. Une variable ne dpasse jamais les frontires d'une fonction ou d'une procdure. Deux variables, portant le mme nom, mais utilises dans 2 fonctions diffrentes auront deux contenus diffrents. En fait ce seront deux morceaux de mmoire diffrents. Le nom du jeu sera mis dans la proprit "jeu" une bonne fois pour toutes au dbut du programme.. Au dbut de chaque action principale de notre jeu, je mettrai jour la proprit action. Deuxime ligne, ce que nous cherchons a faire : une ligne de code simple pour afficher un message. C'est un exemple de ce que permet la fonction qui suit immdiatement. Ensuite, la fonction qui fait le travail et que je n'ai besoin d'crire qu'une seule fois : "on affiche (message)" : c'est le dbut de mon instruction, le texte de notre message entrera dans le paramtre qui s'appelle message. Rien de nouveau. La fonction se termine par un "end affiche" tout aussi normalement. Vient ensuite mon display dialog, ou j'appelle le nom du jeu (nom of jeu), l'action en cours (action of jeu), puis je place le paramtre "message". Enfin, mes boutons standards et le bouton par dfaut. Avec le mme code, je pourrai maintenant crire : affiche ("Qui est l ?") affiche ("Donnez-moi votre prnom :") affiche ("Votre nom de famille :") Plus besoin d'crire un seul display dialog. Vous tes emballs ? a vous plait que ce soit facile ? Alors on va compliquer un peu :-)

:: O2 :: Remplissons notre cahier et recommenons

Oui, compliquons-nous peu les choses. L'usage des fonctions permet de se simplifier la vie, mais en contrepartie, il faut bien s'appliquer pour les crire . Nous venons de simplifier l'appel d'un display dialog bien prcis : celui qui permet l'utilisateur de saisir du texte. Il y en a un autre, celui qui ne fait qu'afficher un message d'alerte. Ferons-nous une fonction pour chaque type de display dialog ? Comment faire quand nous voudrons un autre bouton que le "OK" ? Et puis plus important : comment rcuprerons-nous le bouton cliqu, le texte saisi ? Ce qui se trouve habituellement dans the result ? Ne tremblez pas. Rflchissons calmement. prenons un cahier et notons de quoi nous avons besoin : Toujours : afficher un message Toujours : rcuprer l'action de l'utilisateur Parfois : demander une saisie Parfois : prciser des boutons. Cela n'a rien de compliqu. Ce qui vient "parfois", je l'crirai avec une condition, un "if". Le reste viendra en dehors du if. --Algorithme

Je prepare le nom du jeu, l'action en cours et le message si il n'y a pas de boutons fournis par l'utilisateur alors je met le boutons "OK" dans la liste des boutons fin du si si on ne me prcise rien, j'affiche le message sans saisie avec la liste des boutons si besoin d'une saisie alors j'affiche le message avec les options de saisie et la liste des boutons end if je retourne la reponse --fin de l'algorithme Vous y voyez plus clair ? Alors attaquons le code. property jeu : {nom:"Mini-Roulette", action:"Inscription des joueurs"} affiche("Entrez-votre nom :", "", {}) affiche("Attention !", 0, {}) affiche("Combien de boutons voyez-vous ?", "Trois", {"1", "2", "3"}) on affiche(message, reponse, boutons) -- prpare le message afficher set leMessage to nom of jeu & " : " & action of jeu & return & message -- vrifie la liste des boutons if (count of boutons) = 0 then set boutons to {"OK"} end if if reponse = 0 then -- un display dialog sans zone de saisie display dialog leMessage buttons boutons default button (last item of boutons) else -- un display dialog avec zone de saisie display dialog leMessage default answer reponse buttons boutons default button (last item of boutons) end if return the result end affiche Comparez l'algorithme et le code, cela devrait tre clair. Regardez comme il nous est facile de faire suivre le "the result" de notre dialog : nous le renvoyons notre tour comme rsutat de notre fonction. Ce qui est surtout plus complexe que dans l'exemple prcdent, c'est l'utilisation de notre fonction. Elle a dsormais besoin de trois paramtres : le premier (qui devient la variable message dans la fonction, sert toujours de message. Le deuxime (qui devient reponse) dcide s'il faut ou non une zone de saisie. Pour ne pas en avoir, il faut le mettre 0. Pour en avoir une, il suffit de mettre du texte dans ce paramtre (mme vide sous la forme ""). Le troisime sert de liste de boutons. Si elle est vide, notre fonction se chargera de la remplir. Et si on se trompe dans les paramtres en appelant notre fonction ? Nous aurons un message d'erreur, mais ce n'est pas plus grave que de se tromper en crivant une instruction display dialog. Nous voil donc en possession d'une fonction grant la plupart des possibilits de l'instruction display dialog. Il manque la gestion des icones et la temporisation, mais nous n'en n'aurons pas besoin, sinon cela serait possible selon le mme principe. Grce a cette fonction, tous les messages de notre application auront donc une apparance similaire, un "look" pauvre sans doute, mais un "look" quand mme. Ah, si ! J'avais dit que nous ferions de la dco ! Avoir juste le nom du jeu et de l'action en cours, cela n'est peut tre pas suffisant pour vous ? Alors on pourrait par exemple crer une proprit "deco" et remplacer la premire ligne de notre fonction ainsi : -- dans la dclaration des proprits du script : property deco : "::: "

-- dans notre fonction, la premire ligne devient : set leMessage to deco & nom of jeu & " : " & action of jeu & return & deco &message Travailler ainsi nous permettra de changer l'aspect de tous nos messages en une seule instruction : par exemple set deco to "*** " Voil surtout ce que je voulais vous dmontrer de l'intrt des fonctions : elles nous compliquent un peu les choses au dpart, mais ensuite, elles enrichissent le programme et nous simplifient la vie. Notre dco est un exemple un peu futile pour comprendre tout l'intrt de ce que nous venons de raliser, mais croyez-moi, vous devrier chercher dans vos programmes toutes les actions rptitives pour les traiter de cette faon. Ce serait un bon exercice avant des travaux plus complexes et de bonnes habitudes de travail prendre pour faire voluer vos programmes.

:: P1 :: L'invit qui ne faisait pas parti de la liste


Cette instruction s'appelle "choose from list". (Choose from list est une addition au langage ApplScript, mais comme cette addition est maintenant dj ancienne, je suppose que tout le monde y aura accs, sinon, essayez de trouver une mise jour) Voici un exemple tester... choose from list {"1","2","3","4","5"} Testez cette instruction, elle prsente une fentre vous demandant de choisir entre les valeurs 1,2,3,4 et 5. Un clic sur la ligne dsire puis sur "OK", ou un double clic sur la ligne, et le choix est fait. Simple et efficace. Il esiste quelques paramtres pour cette instruction : with prompt Le "prompt" c'est la phrase qui introduit la liste. Par dfaut (en franais) : "Veuillez faire votre choix". Mais on pourrait par exemple : choose from list {"1","2","3","4","5"} with prompt "Pariez sur une valeur :" with multiple selections allowed Ce paramtre permet d'autoriser l'utilisateur choisir plusieurs lignes la fois par majuscule-clic et commande-clic. Attention : multiple selections est l'identificateur du paramtre, allowed est le parametre. (allowed est un boolen "vrai", mais ce n'est pas utile de vous en rappeler ;-) choose from list {"1","2","3","4","5"} with multiple selections allowed with empty selection allowed Sur le mme principe que le paramtre prcdent, celui-ci authorise l'utilisateur ne rien choisir dans la liste s'il le dsire. Sans ce paramtre, le bouton "OK" ne s'active pas si il n'y a pas de slection. Seul le bouton "Annuler" est clicable. choose from list {"1","2","3","4","5"} with empty selection allowed default items Permet de dcider si une ou plusieurs valeurs doivent tre slectionnes par dfaut. par exemple, pour prparer la slection sur le "4" : choose from list {"1","2","3","4","5"} default items {"4"} Remarquez que (comme pour la liste des boutons d'un display dialog) ce paramtre est une liste, mme si vous ne prcisez qu'une valeur par dfault. C'est ce qui permet d'avoir la mme syntaxe dans le cas ou la slection multiple est authorise et que l'on veut pr-slectionner plusieurs valeurs. choose from list {"1","2","3","4","5"} default items {"1","3"} with multiple selections allowed OK button name et cancel button name Enfin, ces deux paramtres qui permettent de remplacer le nom des boutons "OK" et "Annuler" A utiliser sparemment ou ensemble. choose from list {1, 2, 3, 4, 5} OK button name "Oui" choose from list {1, 2, 3, 4, 5} cancel button name "Non" choose from list {1, 2, 3, 4, 5} OK button name "Oui" cancel button name "Non" Mme si l'on ne prcise que le nom du bouton "OK" ou que celui du bouton "Annuler", il y a toujours les deux boutons. C'est une obligation dont nous allons devoir tenir compte tout l'heure. Evidemment, comme l'instruction "Display Dialog", l'instruction "choose from liste" dpose un "the result" sur

le dessus de la pile, et nous pourrons l'exploiter exactement comme celui d'un display dialog. Il diffre par contre dans son contenu, puisqu'il n'a que deux formats : il contient "false" si l'utilisateur a cliqu sur le bouton "Annuler" Sinon, il contient la liste des lments slectionns.

:: P2 :: Y a plus qu'

Maintenant que nous connaissons cette instruction, intgrons l notre fonction d'affichage. La liste de paramtres sera passe en tant que "rponse" dans notre fonction (2eme paramtre) et pour savoir que c'est un "choose from liste" qui est attendu par l'appel, il nous suffit de tester le type de la variable. Si c'est une liste, alors on fait un choose from list. Si c'est un zro, un display dialog standard etc. Pour tester le type d'une variable l'instruction est "class of" class of "2" -- retourne "string" (texte) class of 2 -- retourne" integer" (nombre) class of {2} -- retourne" list" (liste) on peut donc faire un test boolen par : if (class of "2" = string) then beep -- cette ligne beep car l'affirmation est vraie. Pour le reste, je vous le disais, nous devons faire attention ce qu'il y ai bien deux boutons dans la liste des boutons (ce qui permet ensuite de ne rien prciser si l'on veut les boutons standards). Ce qui donne : property jeu : {nom:"Mini-Roulette", action:"Premier pari"} property deco : "::: " -- un exemple d'utilisation, format choose from list affiche("Pariez sur un chiffre", {"1", "2", "3", "4", "5"}, {"Passer", "Parier"}) -- essayez d'crire la mme ligne sans la fonction "affiche" pour voir la diffrence ! on affiche(message, reponse, boutons) -- prpare le message afficher set leMessage to deco & nom of jeu & " : " & action of jeu & return & deco &message -- vrifie la liste des boutons if (count of boutons) = 0 then set boutons to {"OK"} end if -- ici commencent les diffrents choix de fentre de dialogues if class of reponse is list then -- un choose from list -- donc on fait attention ce qu'il y ait 2 boutons if (count of boutons) = 1 then set boutons to "Annuler" & item 1 of boutons end if choose from list reponse with prompt leMessage OK button name (item 2 of boutons) cancel button name (item 1 of boutons) else if reponse = 0 then -- un display dialog sans zone de saisie display dialog leMessage buttons boutons default button (last item of boutons) else -- un display dialog avec zone de saisie display dialog leMessage default answer reponse buttons boutons default button (last item of boutons) end if return the result end affiche

:: P3 :: Application pratique

Remplaons dans notre code les instructions display dialog par des appels notre fonction "affiche". Il nous faut aussi penser mettre a jour la proprit "action"... ----------------------------------------

-------- paramtres permanents ------------------------------------------------------property jeu : {nom:"Mini-Roulette", action:"Premier pari"} property deco : "::: " ---------------------------------------------- code principale -------------------------------------------------------------introduction() repeat while inscriptions() repeat while parier() gagner() end repeat scores() nettoyage() end repeat quitter() ----------------------------------------------- fonctions du code principal ----------------------------------------------------on introduction() set action of jeu to "Introduction :" affiche("", 0, {}) end introduction on inscriptions() set action of jeu to "Inscriptions :" affiche("", 0, {"Arrter", "Continuer"}) return (button returned of the result = "Continuer") end inscriptions on parier() set action of jeu to "Paris" affiche("", 0, {"Arrter", "Continuer"}) return (button returned of the result = "Continuer") end parier on gagner() set action of jeu to "Rpartition des gains :" affiche("", 0, {}) end on scores() set action of jeu to "Scores :" affiche("", 0, {}) end scores on nettoyage() set action of jeu to "Nettoyage :" affiche("", 0, {}) end nettoyage

on quitter() set action of jeu to "Au revoir :" affiche("", 0, {}) end quitter ----------------------------------------------- ma fonction d'affichage-------------------------------------------------------on affiche(message, reponse, boutons) -- prpare le message afficher set leMessage to deco & nom of jeu & " : " & action of jeu & return & deco &message -- vrifie la liste des boutons if (count of boutons) = 0 then set boutons to {"OK"} end if -- ici commencent les diffrents choix de fentre de dialogues if class of reponse is list then -- un choose from list -- donc on fait attention ce qu'il y ai 2 boutons if (count of boutons) = 1 then set boutons to "Annuler" & item 1 of boutons end if choose from list reponse with prompt leMessage OK button name (item 2 of boutons) cancel button name (item 1 of boutons) else if reponse = 0 then -- un display dialog sans zone de saisie display dialog leMessage buttons boutons default button (last item of boutons) else -- un display dialog avec zone de saisie display dialog leMessage default answer reponse buttons boutons default button (last item of boutons) end if return the result end affiche J'ai peu de choses commenter sur cela, car nous avons dj cr tous les morceaux de ce code auparavant. Ne vous laissez pas impressionner par sa longueur : c'est le propre de tous les codes d'tre longs et cela ne va pas aller en s'arrangeant avec les articles suivants ;-). Voil pourquoi j'utilise les commentaires comme : ----------------------------------------------- ma fonction d'affichage-------------------------------------------------------pour bien sparer les diffrentes sections de mon code et les retrouver plus facilement. Je ne vous conseillerai jamais assez d'en faire autant. Si vous jetez un oeil l'intrieur de chacune des fonctions appeles par notre code principale, vous remarquez qu'il y a maintenant 2 lignes de code. La premire met jour la proprit "action" pour que les messages suivent la chronologie du jeu. La deuxime est un simple appel de notre fonction d'affichage, dont tous les paramtres sont laisss par dfaut puisqu'ils ne sont l que pour une vrification. Sauf, bien sr, ceux de "inscriptions" et "parier" puisqu'ils vrifient au passage la volont de l'utilisateur.

:: Q1 :: A vos marques...
Mais pour s'occuper de cette fonction, tous les lments devraient dj tre en place : les inscriptions, les paris. Qu'a cela ne tienne, nous pouvons le faire d'une faon directive : nous inscrivons deux joueurs, et nous leur imposons des paris.

Cela va nous obliger nous poser les bonnes questions. Ou allons-nous ranger ces informations ? Et bien, en ajoutant quelques proprits supplmentaires notre proprit principale, le "jeu". Rcapitulons : Nous aurons besoin d'une liste de joueurs, deux pour l'instant. Chaque joueur sera aussi une liste contenant : son nom, son tat (actif ou inactif), son pcule, son pari A et son pari B. par exemple : {nom:"Alain",actif:true,pecule:10,pariA:2,pariB:"pair"} -- et {nom:"Bernard",actif:true,pecule:10,pariA:3,pariB:"impair"} nous les rangerons dans une liste, dans la proprit "jeu" sous la forme : property joueurs : { {nom:"Alain",actif:true,pecule:10,pariA:2,pariB:"pair"} -- et {nom:"Bernard",actif:true,pecule:10,pariA:3,pariB:"impair"} } Il nous faudra galement le pcule de la banque, un "tapis" (pour y ranger les mises) et un endroit pour ranger le tirage au sort . J'ai choisi de tout mettre dans une proprit "banque" et de garder des noms semblables ceux utiliss pour les joueurs afin de ne pas surcharger ma propre mmoire : property banque : {pecule:10, tapis:4, pariA:"2", pariB:"pair"} Pour l'instant les valeurs seront fixes, mais cela devrait dj nous permettre de tester notre fonction "gagner", les proprits pariA et pariB de notre banque contenant la valeur du tirage au sort.

:: Q2 :: ... prts ? ...

Voil notre proprit "jeu" telle que nous la dclarerons au dbut du code property jeu : {nom:"Mini-Roulette", action:"", banque:{}, joueurs:{}} -- et nous ferons une fausse initialisation pour simuler les inscriptions et les paris : set banque of jeu to {pecule:10, tapis:4, pariA:"2", pariB:"pair"} set joueurs of jeu to { {nom:"Alain", actif:true, pecule:10, pariA:"2", pariB:"impair"}, {nom:"Bernard", actif:true, pecule:10, pariA:"3", pariB:"pair"} } Que devons nous faire ensuite ? Reportons-nous notre cahier des charges. Si le tirage tombe sur zro, la banque est seul bnficiaire du tapi (les sommes mises). Si le tirage n'est pas zro, la banque vrifie les paris des joueurs. Si le joueur a mis sur la bonne valeur au pari A, il reoit 8 points qui s'ajoutent son pcule. Si le joueur mis pair et que le tirage est pair, ou s'il a pari impair et que le tirage est impair, il reoit 2 points qui s'ajoutent son pcule. Si le joueur n'a pas pari, il ne reoit pas de point. Les points redistribus sont pris en priorit sur le tapis. Si le tapis est suffisant, les points restants s'ajoutent au pcule de la banque. Si le tapis n'est pas suffisant, les points sont pris sur le pcule de la banque. Le tour de jeu est termin. A ce stade, si l'un des joueurs n'a plus de points (pcule = zro), il se retire. Si le pcule de la banque est ngatif, la partie est termine, la Banque saute. Tout ceci concerne bien la parie qui nous intresse, et avec un peu de pratique on devine facilement l'algorithme qui suit : -- algorithme si le pariA de la banque est 0 alors affichons un message. sinon

rptons pour chaque joueur actif si le pariA du joueur = le pariA de la banque alors le pecule du joueur augmente de 8 le tapis descend de 8 fin du si si le pariB du joueur = le pariB de la banque alors le pecule du joueur augmente de 2 le tapis descend de 2 fin du si si le pcule du joueur est zro il devient inactif fin du rpte on affiche les gagnants du pari A on affiche les gagnants du pari B fin du si le tapis va la banque on affiche un message pour dire si la banque perd ou gagne des points C'est assez simple, mais avec un peu de pratique je peut anticiper sur deux choses. - pour afficher la liste des gagnants, il faut la construire. - pour savoir si un joueur est actif, il me faudra un "si" supplmentaire. J'aurais pu faire autrement, en crant une deuxime liste, ne contenant que les joueurs actifs, mais cela compliquait trop l'exercice. Je prends soin de vous une dernire fois en rcrivant cet algorithme, plus dtaill, qui vous permettra de mieux suivre le dveloppement du code car il va tre plus long que tout ce que nous avons vu jusqu'a prsent, mais vous devez vous y habituer.. --algorithme si le pariA de la banque est 0 alors affichons un message. sinon crons une liste vide de gagnantsA crons une liste vide de gagnantsB rptons pour chaque joueur si le joueur est actif alors si le pariA du joueur = le pariA de la banque alors le pecule du joueur augmente de 8 le tapis descend de huit rajoutons le joueur la liste des gagnantsA fin du si si le pariB du joueur = le pariB de la banque alors le pecule du joueur augmente de 2 le tapis descend de 2 rajoutons le joueur la liste des gagnantsB fin du si si le pcule du joueur est zro il devient inactif fin du si fin du rpte on affiche les gagnants du pari A on affiche les gagnants du pari B fin du si le tapis va la banque on affiche un message pour dire si la banque perd ou gagne des points, voir si la banque saute !

:: Q3 :: ... Partez !

De l'algorithme au code, il n'y a qu'un pas, mais cette fois il est assez long. on gagner() -- mise jour de l'action en cours set action of jeu to "Rpartition des gains :"

-- si le zro est tir if pariA of banque of jeu = "0" then set message to "Le zro est sorti !" & return & "Tout le tapis va la banque." affiche(message, 0, {"Pas de chance !"}) -- sinon else -- prparation de listes vides pour les gagnants set gagnantsA to {} set gagnantsB to {} -- vrification des paris des joueur actifs repeat with chaqueJoueur in joueurs of jeu if actif of chaqueJoueur then -- vrification du pari A if pariA of chaqueJoueur = pariA of banque of jeu then set pecule of chaqueJoueur to (pecule of chaqueJoueur) + 8 set tapis of banque of jeu to (tapis of banque of jeu) - 8 copy chaqueJoueur to the end of gagnantsA end if -- vrification du pari B if pariB of chaqueJoueur = pariB of banque of jeu then set pecule of chaqueJoueur to (pecule of chaqueJoueur) + 2 set tapis of banque of jeu to (tapis of banque of jeu) - 2 copy chaqueJoueur to the end of gagnantsB end if -- limination des joueurs insolvables if pecule of chaqueJoueur < 1 then set message to nom of chaqueJoueur & " est insolvable." & return & "Il(elle) se retire du jeu." affiche(message, 0, {"Dommage"}) set actif of chaqueJoueur to false end if end if end repeat --affichage des gagnants du pari A if (count of gagnantsA) = 0 then --si il n'y a pas de gagnants, un message set message to "Pas de gagnants au pari A" else --sinon, on construit un message avec tous les noms des gagnants set message to "Gagnant(s) du pari A :" & return & return repeat with chaqueGagnant in gagnantsA --petite mise en forme du texte pour chaque gagnant set message to message & "- " & nom of chaqueGagnant & " (passe " & pecule of chaqueGagnant & " points)" & return end repeat end if affiche(message, 0, {}) --affichage des gagnants du pari B if (count of gagnantsB) = 0 then --si il n'y a pas de gagnants, un message

set message to "Pas de gagnants au pari B" else --sinon, on construit un message avec tous les noms des gagnants set message to "Gagnant(s) du pari B :" & return & return repeat with chaqueGagnant in gagnantsB --petite mise en forme du texte pour chaque gagnant set message to message & "- " & nom of chaqueGagnant & " (passe " & pecule of chaqueGagnant & " points)" & return end repeat end if affiche(message, 0, {}) end if -- ajoutons le tapis la banque set pecule of banque of jeu to (pecule of banque of jeu) + (tapis of banque ofjeu) -- si le tapis est ngatif, on vrifie si la banque saute -- on en profite pour prparer la premire partie du message, selon les cas if tapis of banque of jeu < 0 then if pecule of banque of jeu < 1 then set message to "Bravo ! Vous venez de faire sauter la banque !" else set message to "La banque perd " & -(tapis of banque of jeu) & " points." end if else set message to "La banque gagne " & (tapis of banque of jeu) & " points." end if -- on complte le message et on l'affiche set message to message & return & "La banque possde " & pecule of banque ofjeu & " points." affiche(message, 0, {}) -- on remets le tapis zro set tapis of banque of jeu to 0 end gagner Je sais, cela reprsente quelques pages sur votre cran. Et peut tre mme plus d'une page imprime. Mais une premire faon de vous familiariser avec ce code, c'est de le tester dans votre diteur pour voir ce qu'il produit. N'oubliez pas si vous le copiez/collez, de l'insrer dans le code principal que nous avons crit la dernire fois ainsi que les lignes d'initialisation qui sont au paragraphe prcdent (Q2). Sinon, vous pouvez le tlcharger en totalit "ici". Testez-le sous toutes ses coutures. Vous pouvez forcer le destin en modifiant les paramtres lors de l'initialisation. Mettez par exemple la banque ou l'un des deux joueurs zro, changez les paris des joueurs pour qu'ils perdent peu a peu leur pcule. Et si vous avez du mal suivre le code, ce n'est pas si important. Ce que je vous montre ici, c'est plus la mthode pour faire avancer un programme complexe, en s'arrangeant pour qu'il soit fonctionnel afin de le tester, tapes par tapes, que le code proprement dit qui ne contient pas d'instructions nouvelles.

:: Q4 :: Alors ? Toujours obscur ? Cherchez l'exception.

Si vous avez pris soin de lire le code, l'algorithme et de tester le script, tout devrait tre relativement comprhensible. Non ? Ce qui complique parfois la chose, ce sont les "exceptions". Par exemple, quand je veux afficher la liste des gagnants, je prpare un message qui dit : "Les gagnants sont : " puis une boucle repeat ajoute les gagnants un par un. Oui, c'est bien, mais si il n'y a pas de gagnants ? Je suis oblig de prvoir cette exception et de prparer un message diffrent : "Il n'y a pas de gagnants".

C'est aussi sur ce principe que le message concernant l'tat de la banque se construit petit petit ( la fin du code). En fonction du tapis, ngatif ou positif, on regarde si la banque a suffisamment d'argent pour tenir le coup. Sinon, elle saute. Dans chacun des cas, on construit petit petit le message. La gestion des exceptions est l'un des principaux mangeurs de code que le programmeur rencontre chaque instant. Il vous faudra en avoir pratiqu beaucoup pour ne plus vous en inquiter et rajouter tout naturellement un "if" supplmentaire par ci par l. Pour le reste, je ne penses pas que vous rencontriez de problme et sinon, ne vous inquitez pas. Cette partie du code tait assez complexe, les suivantes seront plus simple. Elle vous permettront de vous familiariser avec la longueur des codes et vous pourrez revenir lire celui-ci enrichis d'un peu de pratique.

:: R1 :: Qui gagne quoi ?


La difficult d'un programme, c'est de ne pas savoir qui fait quoi, quel moment. Il faut donc travailler dans un monde inconnu, en n'utilisant que des rfrences aux donnes, pas a leur contenu. Ce que je veux dire, c'est que nous savons pour l'instant qu'il n'y a que deux joueurs, Alain et Bernard et nous avons dfinit dans le code les valeurs de leur pari. Mais dans la ralit du programme final, nous ne saurons ni le nombre de joueurs, ni leur nom, ni leurs paris. Nous devons crire notre code en oubliant ces infos, elles n'ont d'autre utilit pour l'instant que de vrifier le bon fonctionnement du code que nous crivons. C'est dans ces cas l que le repeat numrateur se rvle trs utile. Il va nous permettre de travailler sur chaque joueur, tout a tour.

:: R2 :: Allons y calmement :

Mais avant de nous lancer dans l'un des codes les plus longs de notre programme, un petit rcapitulatif de notre cahier des charges sur la partie qui nous intresse ne nous fera pas de mal : Si le tirage tombe sur zro, la banque est seul bnficiaire du tapi (les sommes mises). Si le tirage n'est pas zro, on vrifie les paris des joueurs. Si le joueur a mis sur la bonne valeur au pari A, il reoit 8 points qui s'ajoutent son pcule Si le joueur mis pair et que le tirage est pair, ou s'il a pari impair et que le tirage est impair, il reoit 2 points qui s'ajoutent son pcule. Si le joueur n'a pas pari, il ne reoit pas de point. Les points redistribus sont pris en priorit sur le tapis. Si le tapis est suffisant, les points restants s'ajoutent au pcule de la banque. Si le tapis n'est pas suffisant, les points sont pris sur le pcule de la banque. Le tour de jeu est termin. A ce stade, si l'un des joueurs n'a plus de points (pcule = zro), il se retire. Si le pcule de la banque est ngatif, la partie est termine, la Banque saute. Tout ceci concerne bien la partie du code qui nous intresse, et avec un peu de pratique on devine facilement l'algorithme qui suit : --algorithme --algorithme si le pariA de la banque est 0 alors affichons un message. sinon rptons pour chaque joueur actif si le pariA du joueur = le pariA de la banque alors le pcule du joueur augmente de 8 le tapis descend de 8 fin du si si le pariB du joueur = le pariB de la banque alors le pcule du joueur augmente de 2 le tapis descend de 2 fin du si si le pcule du joueur est zro il devient inactif fin du rpte on affiche les gagnants du pari A

on affiche les gagnants du pari B fin du si le tapis va la banque on affiche un message pour dire si la banque perd ou gagne des points C'est assez simple, mais avec un peu de pratique je peut anticiper sur une chose : - pour afficher la liste des gagnants, il faut la construire. --algorithme si le pariA de la banque est 0 alors affichons un message. sinon crons une liste vide de gagnantsA crons une liste vide de gagnantsB rptons pour chaque joueur si le pariA du joueur = le pariA de la banque alors le pcule du joueur augmente de 8 le tapis descend de huit rajoutons le joueur la liste des gagnantsA fin du si si le pariB du joueur = le pariB de la banque alors le pcule du joueur augmente de 2 le tapis descend de 2 rajoutons le joueur la liste des gagnantsB fin du si si le pcule du joueur est zro il devient inactif fin du rpte on affiche les gagnants du pari A on affiche les gagnants du pari B on liste quels joueurs ont encore le droit de jouer fin du si le tapis va la banque on affiche un message pour dire si la banque perd ou gagne des points, voir si la banque saute !

:: R3 ::R De l jusqu'au code, il n'y a qu'un pas :


on gagner()

-- mise jour de l'action en cours : l'affichage du tirage au sort set action of jeu to "Le " & pariA of banque of jeu & ", " & pariB of banque of jeu& " !" -- nous allons construire un seul message, je prpare la variable set message to ""

-- si le tirage est diffrent de zro, if pariA of banque of jeu is not "0" then -- prparation de listes vides pour les gagnants set gagnantsA to {} set gagnantsB to {} -- vrification des paris des joueur actifs repeat with chaqueJoueur in tourDeTable -- vrification du pari A if pariA of chaqueJoueur = pariA of banque of jeu then set pecule of chaqueJoueur to (pecule of chaqueJoueur) + 8 set tapis of banque of jeu to (tapis of banque of jeu) - 8 copy chaqueJoueur to the end of gagnantsA end if

-- vrification du pari B if pariB of chaqueJoueur = pariB of banque of jeu then set pecule of chaqueJoueur to (pecule of chaqueJoueur) + 2 set tapis of banque of jeu to (tapis of banque of jeu) - 2 copy chaqueJoueur to the end of gagnantsB end if end repeat --affichage des gagnants du pari A if (count of gagnantsA) is not 0 then set message to message & return & "Gagnant(s) du premier pari :" & return repeat with chaqueGagnant in gagnantsA --petite mise en forme du texte pour chaque gagnant set message to message & "- " & nom of chaqueGagnant & return end repeat end if --affichage des gagnants du pari B if (count of gagnantsB) is not 0 then set message to message & return & "Gagnant(s) du second pari :" & return repeat with chaqueGagnant in gagnantsB --petite mise en forme du texte pour chaque gagnant set message to message & "- " & nom of chaqueGagnant & return end repeat end if -- si il n'y a aucun gagnants dans tous les paris, on le dit if (count of (gagnantsA & gagnantsB)) = 0 then set message to message & return & "Il n'y a aucun gagnant." & return end if end if -- limination des joueurs insolvables repeat with chaqueJoueur in tourDeTable if actif of chaqueJoueur then if pecule of chaqueJoueur < 1 then set messageTemporaire to nom of chaqueJoueur & " est insolvable." & return & "Il(elle) se retire du jeu." affiche(messageTemporaire, 0, {"Dommage"}) set actif of chaqueJoueur to false end if end if end repeat -- on liste quels joueurs ont encore le droit de jouer -- (cette petite fonction mrite un article elle toute seule) -- (je la dtaillerai donc dans le prochain article) set tourDeTable to selectionner(tourDeTable, true)

-- ajoutons le tapis la banque set pecule of banque of jeu to (pecule of banque of jeu) + (tapis of banque ofjeu) -- si le tapis est ngatif, on vrifie si la banque saute -- on en profite pour prparer la premire partie du message, selon les cas -- et les boutons du message pour pouvoir les modifier selon les cas if (count of tourDeTable) < 1 then

set boutons to {"Fin de la partie"} else set boutons to {"Arrter", "Continuer"} end if if (pecule of banque of jeu) < 1 then set message to "Vous venez de faire sauter la banque !" & return & message set boutons to {"Bravo !"} else set message to "Le Casino est " & pecule of banque of jeu & points & return &message end if affiche(message, 0, boutons) -- si le joueur clique sur "Arrter", on met la proprit "tour " zro, -- cette proprit sera teste dans la fonction parier() if button returned of the result is not "Continuer" then set tour of jeu to 0 end gagner Je sais, cela reprsente quelques pages sur votre cran. Et peut tre mme plus d'une page imprime. Mais une premire faon de vous familiariser avec ce code, c'est de le tester dans votre diteur pour voir ce qu'il produit. N'oubliez pas si vous le copiez/collez, de l'insrer dans le code principal que nous avons crit la dernire fois. Sinon, vous pouvez le tlcharger "ici" (afin de pouvoir fonctionner, ce script intgre la fonction "Selectionner" que nous dcouvrirons la prochaine fois). Testez-le sous toutes ses coutures. Vous pouvez forcer le destin en modifiant les paramtres lors de l'initialisation. Mettez par exemple la banque ou l'un des deux joueurs zro, changez les paris des joueurs pour qu'ils perdent peu a peu leur pcule.

:: R4:: R - 4 Alors ? Toujours obscur ? Cherchez l'exception.

Si vous avez pris soin de lire le code, l'algorithme et de tester le script, tout devrait tre relativement comprhensible. Non ? A ce stade, je ne serais pas surpris de lacher quelques uns d'entre-vous. Alors attachez-vous d'avantage l'algorythme qu'au code. C'est lui qui est le plus important. A partir du mme algorythme, des programmeurs diffrents criraient des codes diffrents car il n'y a as qu'une seule faon de faire les choses. Ce qui complique surtout le code, ce sont les "exceptions". Par exemple, quand je veux afficher la liste des gagnants, je prpare un message qui dit : "Les gagnants sont : " puis une boucle repeat ajoute les gagnants un par un. Oui, c'est bien, mais si il n'y a pas de gagnants ? Je suis oblig de prvoir cette exception et de prparer un message diffrent : "Il n'y a pas de gagnants". Personnellement, pour viter la profusion de messages j'ai prfr m'arranger pour que le message ne soit pas affich. C'est aussi sur ce principe que le message concernant l'tat de la banque se construit petit petit ( la fin du code). En fonction du tapis, ngatif ou positif, on regarde si la banque a suffisamment d'argent pour tenir le coup. Sinon, elle saute. Dans chacun des cas, j'ai construit petit petit le message, les boutons, et je ne lance qu'un seul appel a ma fonction d'affichage de message. Le procd demande un peu de maitrise et d'habitude, mais on pourrrait galement appeler un affichage pour chaque cas. Le code serait peut tre plus long, mais plus simple suivre. Ce que je tente de vous dire, c'est qu'au lieu de vous dcourager, vous devriez plutot partir d'une page blanche, ne garder que l'algotythme et tenter d'en crire le code votre faon. En travaillant ainsi, vous pourrez choisir des noms de variables qui vous parleront davantage que les miens, vous pourrez suivre votre propre logique, et, enfin, mme si vous laissez quelques trous de scurit ou que vous oubliez quelques exceptions, vous les dcouvrirez petit a petit. A vous ensuite de dcider si vous crivez le code pour rgler le soucis ou non, en fonction de l'ambition de votre projet ou de l'intrt que vous portez l'exercice. C'est avec de la pratique que vous dcouvrirez que la gestion des exceptions est l'un des principaux mangeurs de code que le programmeur rencontre chaque instant. Il vous faudra en avoir pratiqu beaucoup pour ne plus vous en inquiter et rajouter tout naturellement un "if" supplmentaire chaque fois que c'est ncessaire.

Cette partie du code tait assez complexe, les suivantes seront plus simple (tout au moins jusqu'a ce que nous manipulions la liste des joueurs). Vous pourrez donc revenir lire celui-ci plus tard, enrichis d'un peu de pratique.

:: S1 :: Sept lignes pour un article ?


Les plus curieux d'entre vous ont peut tre dj regard dans le script fourni l'article prcdent en quoi consistait cette instruction. Pour mettre tout le monde galit, la voici : on selectionner(joueurs, vrai) set reponse to {} repeat with chaqueJoueur in joueurs of jeu if actif of chaqueJoueur = vrai then set end of reponse to (chaqueJoueur) end if end repeat return reponse end selectionner Quoi ? Seulement 7 lignes de code ? Oui :-) Au moins cette fois ci je suis sr de ne pas vous effrayer. Et je suis (presque) certain que que vous ne voyez l aucune difficult insurmontable. Donc, pas de quoi en faire un article ? Et bien, c'est ce que nous allons voir.

:: S2 :: Que fait cette instruction ?

Cette instruction sert nous simplifier un peu la vie. Nous avons une proprit "jeu" qui contient une liste de joueurs. Mais dans cette liste, au fur et a mesure des parties, il risque d'y avoir du monde. Il risque aussi d'y avoir pas mal de joueurs qui n'ont plus un rond, ou qui n'ont pas voulu participer la partie en cours. Vous dcouvrirez tout cel quand nous crirons le code pour grer la liste des joueurs, mais ce n'est pas encore pour aujourd'hui. En fait cette liste de joueurs va devenir le tmoin des nombreuses parties dj joues, avec Paul et Virginie, Romo et Juliette, Sherlock et Watson, en bref tous les amis que vous avez invits tester votre premier programme AppleScript. C'est grce a cette liste, par exemple, que nous pourrons proposer les noms des anciens joueurs lors d'une nouvelle inscription, ce qui vitera souvent d'avoir retaper son nom. C'est aussi cette liste qui nous permettra de lister les meilleurs scores. Voil pourquoi j'ai dcid de ne pas m'encombrer en permanence de la liste entire. En vriant la proprit "actif" de chaque joueur, je peut savoir si il participe la partie en cours ou non, ce qui me permet de l'inclure dans la liste des participants que j'ai appele "tour de table". Cette liste me permet de ne rpter ensuite le code des paris et des gains qu'avec ces joueurs l. Toutes ces explications, vous les aviez probablement devines simplement en lisant le code. Je vous flicite. Une petite subtilit ? J'aurais pu simplement crire : on selectionner(joueurs) set reponse to {} repeat with chaqueJoueur in joueurs if actif of chaqueJoueur then set end of reponse to (chaqueJoueur) end if end repeat return reponse end selectionner Regardez attentivement, j'ai supprim le deuxime paramtre de l'instruction, "vrai", et j'ai simplifier la ligne du "if". Cette deuxieme version de ma fonction serait suffisante pour obtenir la liste des joueurs actifs. Mais une fonction comme celle ci, par habitude, je l'cris pour quelle permette de rcuprer aussi les inactifs, si on le dsire. Ce n'est pas toujours utile mais le code n'est vraiment pas plus compliqu et vite de devoir crire une autre fonction quand elle est ncessaire. A l'usage, il suffit de donner l'instruction "selectionner", la liste de joueurs que l'on veut trier, et une valeur

boolenne pour dire si l'on veut les joueurs actifs ou inactifs : set selection to selectionner(joueurs of jeu, true) -- permet de rcuprer les joueurs actifs. set selection to selectionner(joueurs of jeu, false) -- permet de rcuprer les joueurs inactifs. Ceci est une habitude de travail. Bon, d'accord, c'est un bon truc mais a ne valait pas la peine d'crire un article complet sur le sujet non plus. Il y a donc autre chose que vous n'avez pas vu.

:: S3 :: Ce qui devrait vous tonner.

Ce qui devrait vous tonner, c'est que l'on cre une nouvelle liste pour les joueurs actifs. Cette liste (appelons l tourDeTable puis que c'est ainsi que je l'utilise) est indpendante de la premire (joueurs of jeu) n'est-ce pas ? Alors quand je mets jour le pariA et le pariB du 1er joueur de tourDeTable, que se passe t-il dans la liste "Joueurs of jeu" ? Et encore ceci : pariA et pariB sont des valeurs qui ne m'intressent que pendant chaque tour de roulette. Si je l'oublie ensuite, cela m'est gal. Mais le pcule du joueur ? Son tat actif ou inactif ? Je vais faire voluer celui qui se trouve dans la liste "tourDeTable", mais quand je voudrai recommencer une nouvelle partie, comment connaitrai-je le pcule d'un ancien joueur ? Faudra-t-il que je le mette a jour chaque fin de tour ? La procdure risque de devenir trs complxe, il me faudrait reparcourir a chaque fois la liste pour retrouver l'empacement de chaque joueur et remettre son pcule jour. Si c'etait le cas, la charge de travail serait plus complexe que de rechercher la liste des joueurs actifs a chaque fois que j'en ai besoin. Trs bien, donc ca ne fonctionne pas comme a, et probablement que cela vous semblait vident. C'est cette vidence l que je voudrais remettre en cause aujourd'hui car si elle est en possibilits, elle l'est galement en dangers. Petits exemple choisis : -- une variable A set variableA to "Bonjour" -- une variable B construite sur la premire set variableB to variableA -- modifions la premire set variableA to "Au revoir" -- questions : que vallent les variables A et B ? log variableA log variableB -- une variable A set variableA to {texte:"Bonjour"} -- une variable B construite sur la premi?re set variableB to variableA -- modifions la premire set texte of variableA to "Au revoir" -- questions : que vallent les variables A et B ? log texte of variableA log texte of variableB Testez ces quelques lignes, et vrifiez le rsultat dans la fentre de l'historique. Alors ? Normalement, vous devriez commencer vous poser des questions. La premire partie vous donne A : "Bonjour", et B:"Au revoir" La seconde, qui est pourtant construite l'identique vous donne : A : "Au revoir", et B:"Au revoir" Deux codes semblables, deux rsultats diffrents. Dans le premier cas, l'instruction set a fait une "copie" de A dans B. Comme A et B sont deux morceaux de mmoire diffrents, quand on modifie l'un, on ne modifie pas l'autre. Dans le second cas, l'instruction "set" ne fait pas une copie. Pourquoi ? Parcequ'Apple l'a voulu ainsi, pour simplifier le travail de programmation d'une part (nous allons voir pourquoi) et pour ne pas encombrer la mmoire. En fait, que ce passe-t-il dans le deuxime cas ? La variable A est une un enregistrement qui contient une proprit. Pour AppleScript, ce format de variable, cette classe, est un format complexe, et plutot que d'en

faire une copie dans la variable B, AppleScript se contente de noter dans la variable B ou se trouve la variable A. Ainsi quand on appelle B, applescript retourne chercher les informations dans le morceau de moire ddi la variableA. Un seul morceau de mmoire, cela explique que si l'on modifie A, on modifie aussi B.

:: S4 :: O l'on se lance dans l'espionnage.

La variable A, c'est facile, nous savons qu'il sagit d'un enregistrement. Mais comment expliquer ce qu'est la variable B ? Le plus simple serait de dire qu'il s'agit juste d'un nouveau nom pour acceder au morceau de mmoire de A. "variableA" et "variableB" seraient donc deux labels pour la mme case mmoire. Si cette explication vous suffit et que vous avez peur que je vous perde avec d'autres explications, vous pouvez vous contenter de cette dfinition. Si vous tes plus courageux, je vous dirait que non, ce n'est pas le cas. "variableA" est le label unique de la case mmoire concerne. Il faut davantage voir "variableB" comme un espion. En crivant "set variableB to variableA" on crit : "variable B, je te charge de surveiller la variable A". Ainsi, quant on demande a B la valeur du texte, il ne donne pas sa valeur propre (il n'en a pas) mais va espionner la variable A et nous ramne la valeur de son texte. Si les deux instructions "set" de tout a l'heure ne donnent pas le mme rsultat c'est que dans le premier cas, AppleScript considre que le contenu de A est trop simple pour mriter un espionnage. Je sais, c'est parfois nervant de voir qu'AppleScript dcide notre place. Pour tre responsable de nos propres dcisions, on peut utiliser l'instruction complte. Ainsi : -- une variable A set variableA to "Bonjour" -- une variable B qui fait rfrence la premire set variableB to a reference to variableA -- modifions la premire set variableA to "Au revoir" -- questions : que vallent les variables A et B ? log variableA log variableB -- une variable A set variableA to {texte:"Bonjour"} -- une variable B construite sur la premi?re set variableB to a reference to variableA -- modifions la premire set texte of variableA to "Au revoir" -- questions : que vallent les variables A et B ? log texte of variableA log texte of variableB L'utilisation de l'instruction complte "set variableB to a reference to..." force AppleScript utiliser un espion plutt qu'une copie. La premire partie nous donne cette fois le mme rsultat que la seconde. Le rsultat de la seconde ne change pas. Rappelez vous donc que l'instruction complte est "set maVariable to a reference to...". En usant de cette formule, vous aurez toujours un espion et jamais de mauvaise surprise. La formulation "set maVariable to..." est un raccourci de la prcdente, elle facilite l'criture mais comporte le danger d'obtenir une copie plutot qu'un espion.

:: S5 :: De l'intrt de l'espionnage.

Nous avons vu l'un des intrts de faire de l'espionnage : crer une slection temporaire a l'intrieur d'une liste, telle qu'en modifiant une valeur de la slection modifie l'lment original correspondant dans la liste. En fait, maintenant vous devez comprendre que la slction, comme celle de l'instruction selectionner, n'est pas une liste de valeurs mais bien une liste d'espion. Notre fonction teste la valeur "actif" de chaque joueur, et si elle est vraie, elle place un espion sur ce jour. C'est cet espion qui est list dans notre tourDeTable. Et lorsqu'au demande le pari A ou B l'espion, il nous retourne la valeur du jour qu'il espionne.

Ce systeme est trs pratique, la fois parcequ'il permet de stocker une fois et une seule les donnes et d'y acceder par diffrentes listes de slections (on pourrait imaginer une selection de joueurs qui ont pari sur pair, une slection de joueurs dont le pcule est suprieur 20 etc L'autre avantage des espions est d'acclrer de beaucoup les temps de travail. En effet, les parties du code qui ne s'intressent qu'aux espions sont trs rapides car les espions sont des morceaux de mmoires trs petits, alors que les morceaux de codes qui s'inressent aux donnes elles mme sont ralenties par le poids des donnes. Voici un exemple, un peu inutile mais trs explicite sur la rapidit de l'usage des espions : -- modifiez la valeur max pour l'adapter la rapidit de votre mac set max to 5000 -- pour vrifier la rapidit de chaque version, je note le temps de dpart set leTemps to current date set maListe to {} repeat with nombre from 1 to max -- dans cette version, je copie chaque nombre la fin de ma liste copy nombre to the end of maListe end repeat -- le temps qu'a dur l'opration : log "Temps d'xcution de la version 1 : " & (current date) - leTemps & " secondes" -- petite verification sur le dernier item de la liste : log "Le dernier lment de la liste est " & item max of maListe

-- mme principe, je note le temps de dpart set leTemps to current date set maListe to {} repeat with nombre from 1 to max -- dans cette version, ce sont des espions que je place dans ma liste set end of maListe to nombre end repeat -- le temps qu'a dur l'opration : log "Temps d'xcution de la version 2 : " & (current date) - leTemps & " secondes" -- petite verification sur le dernier item de la liste : log "Le dernier lment de la liste est " & item max of maListe Quelques commentaires ? d'abord, la valeur max est une valeur arbitraire. Elle permet de repeter "max" fois un test afin de le mesurer. En effet, le test lui mme est trop rapide pour ressentir la diffrence. Plus on le rpte, plus le temps de travail du code se fait sentir. Pour chronomtrer les deux methodes afin de les comparer, j'enregistre l'heure (current date) dans une variable juste avant de commencer ma boucle repeat. L'opration termie, j'obtiens le temps pass en faisant "current date - leTemps" Le premier de mes test est une copie a chaque fois de la valeur de nombre la fin d'une liste, le second un espionnage sur chacun de ces nombres. Un petit test pour chaque code me permet de contrler qu'il a bien fonctionner. Alors ? Avez-vous test ? Que donne votre machine ? Si elle est plus puissante que la mienne vous devrez augmenter la valeur max pour pouvoir bien comparer. Sur le mien, la deuxime version (espionnage) est 50 100 fois plus rapide que la premire. Ce n'est pas rien !

:: S6 :: Des dangers de l'espionnage.

De quoi doit-on se mfier avec les espions ? Et bien de ne pas avoir affaire l'un d'entre eux si l'on en veut pas, bien sr. Prfrez donc toujours

l'instruction "copy" quand vous voulez un nouvel lment que vous pourrez modifier sans toucher l'original, et ne faites pas confiance l'instruction set pour faire les copies de donnes simples. L'autre danger de l'espionnage, c'est de trs vite confondre l'espion et sa cible. Normalement, Applescript vacue pour vous cette ambiguit en considrant que vous voulez toujours des informations sur la cible et non pas sur l'espion. Mais il arrive parfois que l'on place des espions sur d'autres espions, pour affiner encore une selection l'intrieur d'une slection par exemple. Trs vite applescript peut perdre les pdales et ne plus savoir si vous voulez parler de la cible d'un espion, de la cible de sa cible etc... Tout comme on peut lever l'ambiguit de l'instruction "set" avec un "set to a reference to", on peut lever l'ambiguit espion/cible en demandant expressement "the contents of" (le contenu de l'espion). Ainsi l'criture la plus rigoureuse de notre exemple devrait tre : -- une variable A set variableA to "Bonjour" -- une variable B qui fait rfrence la premire set variableB to a reference to variableA -- modifions la premire set variableA to "Au revoir" -- questions : que vallent les variables A et B ? log variableA log contents of variableB -- une variable A set variableA to {texte:"Bonjour"} -- une variable B construite sur la premire set variableB to a reference to variableA -- modifions la premire set texte of variableA to "Au revoir" -- questions : que vallent les variables A et B ? log texte of variableA log texte of contents of variableB C'est la fois assez rare (on rencontre ce probleme l'intrieur de certains repeat numrateurs car ils fonctionnent eux aussi sur le principe de l'espionnage) mais tellement perturbant quand on rencontre le problme qu'il faut garder la chose l'esprit.

:: S7 :: Alors ?

Alors ? Ces 007 petites lignes de rien du tout de notre instruction "selectionner", vous voyez qu'elles nous ont emmen assez loin. J'espre que vous n'avez pas eu de mal a me suivre dans cet article. L'espionnage mrite certes un peu de prudence, il est une aide prcieuse pour russir des programmes rapides. Mais n'oubliez pas qu'au dbut de cet article vous avez probablement trouv cela trs simple. Il ne s'agit que d'une question de vocabulaire et de logique. A propos de vocabulaire, un "espion" pour un programmeur, cela s'appelle un pointeur. :-) Que ceux qui connaissaient le mot et s'en sont douts lvent le doigt. La notion de pointeur est galement (et trs souvent) mal explique aux dbutants (enfin, mon got) en faisant appel aux principes logiques de fonctionnement de la mmoire qu'elle utilise, au lieu d'utiliser une mtaphore comme celle de l'espionnage. Alors, si vous passez un jour a un autre langage et que vous entendez parler de pointeurs, haussez les paules et ne soyez pas effrays, il vaut mieux comprendre l'intrt d'un pointeur que son fonctionnement. Certes, dans un langage comme le C, la syntaxe sur l'usage des pointeurs n'est pas assiste comme dans appleScript, mais l'usage n'en est pas beaucoup plus difficile et tout aussi intresant.

:: T1 :: Le retour au cahier des charges :


Reprenons notre cahier des charges et notons cette fois ce qui concerne les paris proprement dits : - Chaque joueur doit faire 2 paris, nomms A et B : - Le pari A consiste choisir un nombre entre 1 et 8.

- Le pari B consiste choisir entre pair et impair. - Pour chaque pari A et B, le joueur mise un point de son pcule qu'il dpose sur le tapis. - Les joueurs ont la possibilit de s'abstenir de parier (A, B ou les 2), mais si aucun joueur ne parie, la partie se termine. - Les paris termins, une valeur est tire au hasard de 0 8. Tout cela semble dj plus simple que la partie qui concernait les gains. Mefions-nous tout de mme, certains autres points sont concerns : - Si le pcule de la banque est ngatif, la partie est termine, la Banque saute. et - Puis les joueurs ont la possibilit de quitter le programme ou de relancer une partie, auquel cas les inscriptions sont relances. Pour ce dernier point, je renseigne une variable "tour" en demandant au joueur s'il veut continuer la partie ou non. Si le joueur a cliqu sur "arrter" alors la variable "tour" vaut 1, mais il faut bien a un moment ou a un autre que je me serve de cette information. Pour la fin de partie, c'est ici. Il faut donc que je retourne la valeur "false" car rappelez-vous, l'instruction "parier" sert de boolen une instruction repeat. C'est loin, je sais, mais un petit retour en arrire vers le code principal, la leon M, vous permettra de vous y retrouver. Pour la vrification du pcule de la banque, c'est le mme principe. Dans l'instruction "gagner", nous nous sommes occups de fliciter le joueur d'avoir fait sauter la banque, mais nous n'avons pas quitt la boucle des paris pour autant. Il faut le faire ici. De quoi d'autre faut-il se mfier ? - faire un petit nettoyage entre les diffrents tours de paris. - surveiller que les joueurs ont toujours de quoi honorer leurs paris.

:: T2 :: On peut donc se lancer et crire l'algorithme suivant :


-- algorithme pour parier : renvoyer faux si la banque a saut renvoyer faux si le joueur veut quitter augmenter la valeur de "tour" remettre le tapis zro rpter pour chaque joueur actif si son pcule est suprieur zro il peut faire un pari A proposer et enregistrer un choix entre 1 et 8 si le joueur a pari rduire son pcule augmenter le tapis fin de si fin de si si son pcule est suprieur zro il peut faire un pari B proposer et enregistrer un choix entre 1 et 8 si le joueur a pari rduire son pcule augmenter le tapis fin de si fin de si fin du rpter

Cet algorithme est simple, a mon avis et ne demande pas vraiment d'explications. Mais comme nous l'avons vu lors de l'article prcdent, c'est la gestion des exceptions qui va compliquer un peu notre code. Toutefois, comme il sera moins long que celui de l'article prcdent, je vais pouvoir le commenter un peu plus.

:: T3 :: Le code :
on parier() -- si la banque n'a plus d'argent, fin de la partie if pecule of banque of jeu < 1 then return false -- si le joueur veut s'arrter, fin de la partie if tour of jeu < 1 then return false -- sinon, on lance un tour de paris -- on remet le tapis zro set tour of jeu to (tour of jeu) + 1 set tapis of banque of jeu to 0 -- pour chaque joueur repeat with chaqueJoueur in tourDeTable -- premier pari : set action of jeu to "Premier pari" set pariA of chaqueJoueur to "Passe" if pecule of chaqueJoueur > 0 then -- choisir un chifffre de 1 8 set message to nom of chaqueJoueur & " : " & pecule of chaqueJoueur & " points." set leChoix to affiche(message, {"1", "2", "3", "4", "5", "6", "7", "8"}, {"Passer", "Parier"}) if leChoix is not false then set pariA of chaqueJoueur to leChoix as string set pecule of chaqueJoueur to (pecule of chaqueJoueur) - 1 set tapis of banque of jeu to (tapis of banque of jeu) + 1 end if end if -- second pari : set action of jeu to "Second pari" set pariB of chaqueJoueur to "Passe" if pecule of chaqueJoueur > 0 then -- choisir entre "Pair" ou "Impair" set message to nom of chaqueJoueur & " : " & pecule of chaqueJoueur & " points." set leChoix to affiche(message, {"Impair", "Pair"}, {"Passer", "Parier"}) if leChoix is not false then set pariB of chaqueJoueur to leChoix as string set pecule of chaqueJoueur to (pecule of chaqueJoueur) - 1 set tapis of banque of jeu to (tapis of banque of jeu) + 1 end if end if end repeat -- en l'absence de tout pari, fin de la partie -- (remarquez que si aucun joueur n'est actif, il y aura "absence de tout pari") if tapis of banque of jeu < 1 then return false -- tirage de la boule : set numero to some item of {"0", "1", "2", "3", "4", "5", "6", "7", "8"} -- mmorisation des paris A et B de la banque if numero is "0" then

set pariB of banque of jeu to "le tapis va la Banque" else if numero is in {"1", "3", "5", "7"} then set pariB of banque of jeu to "Impair" else set pariB of banque of jeu to "Pair" end if set pariA of banque of jeu to numero -- les paris se sont bien passs, la fonction renvoie "true" pour que la boucle repeat continue return true end parier

:: T4 :: Quelques explications :

Les premires lignes du code sont sufisamment commentes et ne posent pas de problme. Ensuite, l'intrieur de la boucle "repeat with chaqueJoueur in tourdeTable", vous voyez deux parties qui se resemblent par leur construction. Ce sont les paris A et B pour chaque joueur. set action of jeu to "Premier pari" set pariA of chaqueJoueur to "Passe" Rien de complexe pour la premire ligne, il s'agit juste de mettre a jour l'action en cours pour l'affichage personnalis de nos messages. Par contre, pourquoi la deuxime ligne ? Je l'utilise comme valeur par dfaut. En forant la valeur du pari pour ce joueur, je suis sur de ne pas laisser trainer son ancien pari. Ainsi, si le joueur ne parie pas sur un nombre, je n'ai pas besoin de faire le test, je laisse juste le code se poursuivre. Vous allez voir plus tard. A l'intrieur d'une instruction if qui me permet de savoir si le joueur a les moyens de parier, je construit un message, je l'affiche et j'enregistre le choix de l'utilisateur dans la variable "leChoix". Cela donne ceci : set message to nom of chaqueJoueur & " : " & pecule of chaqueJoueur & " points." set leChoix to affiche(message, {"1", "2", "3", "4", "5", "6", "7", "8"}, {"Passer", "Parier"}) Enfin, il ne me reste plus qu'a tester si le joueur a bien parier. S'il ne l'a pas fait, je n'ai rien a ajouter puisque j'ai dj mis une valeur par dfaut "passe". Si il l'a fait, j'enregistre son choix, je retire un point de son pcule et j'en ajoute un au tapis de la banque. set pariA of chaqueJoueur to leChoix as string set pecule of chaqueJoueur to (pecule of chaqueJoueur) - 1 set tapis of banque of jeu to (tapis of banque of jeu) + 1 Et voil, fin du pari A. Si vous regardez la construction du pari B, elle est identique et vous ne devriez pas avoir de mal vous y retrouver. Il ne reste plus maintenant qu'a lancer la boule, c'est dire renseigner les paris de la banque. Le tirage alatoire est fait par l'instruction "some item" qui permet d'obtenir un des lments de la liste au hazard. Ensuite, si le tirage est 0, on prpare un petit message spcial qui s'affichera automatiquement lors des rsultats (voir l'aricle R, dans l'instruction "gagner", puisque l'on affiche le tirage en se servant du pari A de la banque). Et pour le reste, on teste si le tirage fait partie des nombres impairs. Si oui, le pari B de la banque est impair, sinon, il est pair. Enfin, la ligne a ne pas oublier, puisque l'instruction "parier" sert de boolen a une boucle repeat, nous devons retourner une valeur, vraie ou fausse. Comme tout c'est bien pass, nous retournons la valeur "true" et la partie peut continuer. Encore une fois, n'hsitez pas a tester ce nouveau code, cela vous aidera a en comprendre l'intrt. En plus, il est maintenant jouable, mme si ce n'est toujours que par procuration, mais cela devrait enfin lui donner un peu d'intrt. Si vous voulez le code entier correspondant a cet article, vous pouvez le tlcharger ici.

:: U1 :: Vous connaissez la mthode maintenant, revoyons notre cahier des charges :

Un petit retour l'article M pour voir ce qui nous concerne aujourd'hui. EXTRAITS DU CAHIER DES CHARGES - 1 8 joueurs peuvent s'inscrire en dbut de partie. Les inscriptions ne peuvent pas tre prises en cours de partie. - Chaque joueur, lors de l'inscription, reoit un pcule de 10 points qui lui servira miser. - La banque dbute la 1re partie avec un pcule de 50 points. Exprim ainsi, cela semble trs peu, voire facile. Si vous vous en sentez le courage et les capacits, n'hsitez pas, lancez-vous. Pour ma part, un peu d'exprience m'oblige freiner des 10 doigts avant de me lancer dans le code. Je sais, par avance, que la gestion de listes auxquelles l'utilisateur a accs est complexe, source de bugs et problmes en tout genre. Tant que je suis le seul utilisateur de mon programme, je peux me dire : "Allez, faisons simple et s'il y a quelques soucis, je ferai attention en utilisant mon programme. C'est tout." Mais l'utilisateur d'un programme crit par une autre personne n'a pas cette tolrance, d'autant plus qu'il ne peut anticiper les risques de ses actions. Il peut tre tent de faire n'importe quoi. Soit parce qu'il ne voit pas le mal, soit parce qu'il n'a pas compris comment utiliser le programme, soit parce qu'il est vicieux (si, si, des fois, on se le demande ;-) Voici donc quelques erreurs classiques commises par les utilisateurs : - ne pas entrer de valeur quand on le leur demande Le risque : vous pouvez ensuite gnrer une phrase trange due l'absence de nom saisi. Par exemple : " gagne 8 points", lorsque vous espriez quelque chose tel que "Franois gagne 8 points". - entrer deux fois la mme valeur Ce cas de figure n'est pas forcment une erreur de l'utilisateur. Deux "Franois" par exemple peuvent vouloir jouer ensemble. On pourrait contourner cette difficult en grant une liste indexe. On attribue un numro unique chaque joueur, et l'on se base sur ce numro pour faire des appels chaque joueur. Ainsi, son nom n'est qu'une information comme une autre. D'ailleurs, c'est bien le cas pour les pcules : on ne peut pas obliger tous les joueurs avoir des pcules diffrents. Mais le cas du nom est un peu particulier, c'est pourquoi dans notre jeu nous empcherons deux joueurs de porter le mme nom. Et si deux "Franois" veulent jouer ensemble, ils se diffrencieront par un numro ou par l'initiale de leur nom de famille. - entrer des valeurs trop longues Il arrive que certaines valeurs, cause de leur longueur, ne tiennent plus dans les zones attribues pour l'affichage. "Antoine de la Tour de St Jacques de Compostelle, troisime du nom", par exemple. L, le risque de bug n'est pas trop grave, le seul souci tant la lecture du message. Nous ne nous occuperons pas de ce cas pour ne pas alourdir le code, mais pour un programme srieux, il vaudrait mieux en tenir compte.

:: U2 :: Action...

En ayant l'esprit les diffrents cas cits ci-dessus, lanons nous dans un algorithme. Premier point, nous devons limiter les inscriptions 8, maximum. -- Algorithme Pour les inscriptions : rpter 8 fois inscrire un joueur fin de rpter mettre les joueurs inscrits autour de la table dire si les inscriptions se sont bien passes fin des inscriptions J'y vais doucement. j'espre que vous me suivez. La question que l'on se pose ensuite c'est "Comment inscrire un joueur ?". Je veux proposer une liste des anciens joueurs, pour viter la saisie rptitive des noms, mais aussi pour

pouvoir rejouer avec un ancien pcule amass lors d'un jour de chance. A l'oppos, une fois qu'un joueur est inscrit, il ne faut plus le proposer. Techniquement, cela ne devrait pas poser de problme, mais ne serait pas trs raliste. Si le joueur est nouveau et n'a jamais entr son nom, il faut lui permettre de le faire. Enfin, s'il n'y a pas eu de troisime inscrit, par exemple, c'est que seuls deux joueurs veulent participer. Il faut donc forcer la sortie de notre boucle "repeat 8 times". Comme a se complique dj, nous allons diviser notre code en plusieurs fonctions. Tout d'abord, crivons une fonction qui s'occupera de l'inscription des joueurs (de 1 8), puis une autre qui ne s'occupera que de l'inscription d'un joueur. Cette dernire pourra par exemple renvoyer une valeur vraie s'il y a une inscription, fausse s'il n'y en a pas eu. Cela nous permettra de sortir de notre boucle repeat. Je reprends donc un algorithme un peu plus pouss. -- Algorithme Pour les inscriptions : runir les joueurs non inscrits autour de la table rpter 8 fois si choisir un joueur est faux alors je quitte le rpte fin de rpter mettre les joueurs inscrits autour de la table dire si les inscriptions se sont bien passes fin des inscriptions Pour choisir un joueur : je dresse la liste des noms que je connais dj et qui ne sont pas actifs (ce sont ceux qui sont autour de la table) Je propose cette liste, plus la possibilit d'entrer un nouveau nom. Si l'utilisateur ne choisit personne, alors je renvoie faux -- les inscriptions sont closes, il est inutile d'aller jusqu' 8 Si l'utilisateur a choisi nouveau alors Je demande quel est son nom Si ce nom n'est pas acceptable (vide, ou dj connu), je relance la saisie Je cre un nouveau joueur (actif par dfaut) J'ajoute ce nouveau joueur la liste des joueurs du jeu Sinon, si l'utilisateur a choisi un nom existant, alors On met ce joueur actif On remet son pcule 10 s'il est insuffisant On le retire d'autour de la table --pour empcher de le choisir une nouvelle fois Fin du Sinon Je retourne vrai pour dire que l'inscription s'est bien passe Fin de choisir un joueur Ouf, cela fait beaucoup tout d'un coup. je ne vais pas me lancer dans des commentaires sur cet algorithme., je pense qu'il est clair et assez proche du franais. Mais vous avez remarqu que j'ai tenu compte de plusieurs cas particuliers qui n'apparaissaient pas au premier abord. Pour allger encore mon code, je vais isoler les lignes qui concernent la cration d'un nouveau joueur et les placer leur tour dans une autre instruction que j'appellerai "nouveau nom". Que nous restera-t'il ensuite ? Et bien comme pour les instructions "gagner" et "parier", l'utilisateur peut dcider en fin de parcours de quitter. C'est ce que nous testons dans la variable "tour". Il faut en tenir comte ici aussi, ds le dbut. Si l'utilisateur veut quitter le programme, les inscriptions doivent retourner une valeur fausse pour quitter la boucle repeat dans laquelle elle est incluse. Je vous donne un dernier algorithme., attachez vous bien le comprendre car le code ensuite sera encore plus charg. --Algorithme Pour les inscriptions : si l'utilisateur a choisi de quitter, je retourne faux sinon, je mets le tour de jeu 1 runir les joueurs non inscrits autour de la table rpter 8 fois si choisir un joueur est faux alors je quitte le rpte

fin de rpter mettre les joueurs inscrits autour de la table dire si les inscriptions se sont bien passes fin des inscriptions Pour choisir un joueur : Je dresse la liste des noms que je connais dj et qui ne sont pas actifs -- ce sont ceux qui sont autour de la table Je propose cette liste, plus la possibilit d'entrer un nouveau nom. Si l'utilisateur ne choisit personne, alors je renvoie faux -- les inscriptions sont closes, il est inutile d'aller jusqu' 8 Si l'utilisateur a choisi "nouveau" alors j'ajoute un nouveau nom la fin de la liste des joueurs du jeu Sinon, si l'utilisateur a choisi un nom existant, alors Je mets ce joueur actif Je remets son pcule 10 s'il est insuffisant Je le retire d'autour de la table -- pour empcher de le choisir une nouvelle fois Fin du Sinon Je retourne vrai pour dire que l'inscription s'est bien passe Fin de choisir un joueur Pour un nouveau nom Je demande quel est ce nom Si ce nom n'est pas acceptable (vide, ou dj connu) je relance la saisie Je cre un nouveau joueur -- actif par dfaut Je renvoie ce joueur fin de nouveau nom Voil. Encore une fois, prenez votre temps avant d'aller voir le code lui-mme.

:: U3 :: Commenons par la fin

Pour ne pas vous perdre, il me semble plus simple d'crire en premier la dernire instruction : nouveau joueur. Voici son code : on nouveauNom() -- on dresse la liste des noms de joueurs dj existants pour qu'il n'y ait pas de doublons -- et pour viter que l'utilisateur entre un nom vide, -- je le mets dj dans la liste des existants set existants to {""} repeat with chaqueJoueur in joueurs of jeu copy nom of chaqueJoueur to the end of existants end repeat -- on demande un nom l'utilisateur, dans un repeat ternel repeat set leNom to text returned of affiche("Entrez votre nom :", "", {}) -- Si le nom existe dj, un message d'erreur if leNom is in existants then beep affiche("Impossible, ce nom est dj choisi ou vide.", 0, {}) else -- sinon, on quitte la boucle repeat en renvoyant le nom choisit return leNom end if end repeat end nouveauNom Pas de difficult majeure. La seule complication ici, c'est de dresser au pralable une liste des prnoms de joueurs existants. Ensuite, en regardant si la saisie de l'utilisateur se trouve dans cette liste, nous pourrons dire si la saisie est acceptable ou non. C'est la ligne "if leNom is in existant". Ensuite, je me sers d'un "repeat"

ternel (vous commencez connatre mes habitudes) pour forcer l'utilisateur saisir un nom valable. Je quitte ce "repeat" quand le nom me convient. Puisque l'on dit qu'il vaut mieux prvenir que gurir, je vais avoir besoin (bientt) d'ajouter ma liste un joueur dont le nom sera saisi par l'utilisateur. Pour clarifier l'criture, je prfre crire une mini fonction ne servant qu' cela. on nouveauJoueur(leNom) -- on renvoie une forme de l'enregistrement de base pour un joueur return {nom:leNom, actif:true, pecule:10, pariA:"9", pariB:"Passe"} end nouveauJoueur Bien, nous approchons de la difficult majeure. Attaquons nous l'instruction "Choix d'un joueur" : ----------------------------------------------- ma fonction d'inscription d'un joueur dj connu -------------------------------------------------------on choisirJoueur() -- je rcupre une liste des Noms des joueurs connus set liste to {} repeat with chaqueJoueur in tourDeTable copy nom of chaqueJoueur to the end of liste end repeat -- je donne le choix : set leChoix to affiche("Choisissez un joueur", liste & "Nouveau...", {"Terminer", "Oui"}) -- si l?utilisateur clique sur "Terminer", on renvoie faux, pour arrter les inscriptions if leChoix is false then return false set leChoix to item 1 of leChoix -- si l'utilisateur a choisi "nouveau", on appelle notre instruction nouveau nom if leChoix = "Nouveau..." then copy nouveauJoueur(nouveauNom()) to the end of joueurs of jeu else -- sinon, c'est que le joueur est connu, on recherche son nom pour l'activer repeat with chaqueJoueur in tourDeTable if nom of chaqueJoueur = leChoix then -- quand on a trouv le joueur, on l'active puis on vrifie son pcule -- et si son pcule est insuffisant, on le remet 10 set actif of chaqueJoueur to true if pecule of chaqueJoueur < 1 then set pecule of chaqueJoueur to 10 affiche(leChoix & " est crdit de 10 points", 0, {}) end if -- on repasse le tour de table au filtre "faux" pour ter le nouvel inscrit set tourDeTable to selectionner(tourDeTable, false) exit repeat end if end repeat end if return true end choisirJoueur Quelques explications : l encore, je dresse une liste de type texte pour avoir la liste des prnoms des joueurs qui sont autour de la table. Ainsi, je pourrai la passer en paramtre mon instruction "message", ce que je ne pourrais pas faire avec une liste de proprits. L'inverse est vrai aussi, quand l'utilisateur a choisi un nom, il faut parcourir la liste des joueurs pour retrouver le correspondant. Ici, l'usage d'espions (pointeurs) semblerait intressant, malheureusement, l'instruction "choose from list " est trop exigeante sur le format de liste qu'il faut lui passer en paramtre. Pour contourner ce problme, il vous manque encore quelques connaissances. Sinon, mme si je sais que ce code est long et complexe je ne pense pas que des commentaires en plus de ceux que j'ai insrs dans le code vous soient utiles. Il vous faut persvrer et surtout ne pas dsesprer car nous avons atteint ici les lignes de code les plus complexes de notre programme. En comparaison d'ailleurs, la

dernire instruction que nous devons crire est dj plus simple, il s'agit de l'instruction "inscriptions" elle mme : on inscriptions() -- si l'utilisateur a choisi de quitter, alors on renvoie faux if tour of jeu = -1 then return false -- sinon, c'est le dbut de la partie, notre compteur passe 1 set tour of jeu to 1 -- mise jour de l'action en cours set action of jeu to "Inscriptions" -- rassemblement des non inscrits autour de la table : set tourDeTable to selectionner(joueurs of jeu, false) -- je me limite 8 joueurs repeat 8 times if not choisirJoueur() then exit repeat end repeat set tourDeTable to selectionner(joueurs of jeu, true) -- on renvoie une valeur vraie si les inscriptions se sont bien passes -- (au moins un inscrit) return ((count of tourDeTable) > 0) end inscriptions A part la dernire ligne o il faut juste remarquer que l'instruction retourne faux s'il n'y a pas eu de joueurs inscrits, il n'y a pas la de quoi vous effrayer, n'est ce pas ?

:: U4 :: Enfin, quoi...
Ca y est ? Pour de vrai ? Notre programme de mini-roulette est termin ? Et bien nous pourrons certes l'amliorer encore un peu mais sinon, oui. Il est complet et fonctionnel. Pour comprendre ce que nous avons fait dans cet article, lancez le script complet (vous pouvez le tlcharger ici) et soyez attentifs la priode des inscriptions. La premire fois que vous l'utiliserez, vous n'aurez que le choix de "Nouveau...". Normal puisqu'il n'y a encore pas eu d'inscrits. Inscrivez autant de joueurs que vous voulez (ou pouvez : 8 maxi) et terminez la partie. Relancez le script sans quitter l'diteur : cette fois, les noms que vous avez dj entrs vous sont proposs dans la liste. Et si vous en slectionnez un, il n'apparatra plus lors de la proposition suivante, ce qui etait le but recherch pour qu'un joueur ne puisse s'inscrire qu'une seule fois par partie.

:: V1 :: A quoi sert la programmation ?


Heu... Je sais. Vous pensez que j'aurais d poser cette question plus tt. C'est vrai, mais l, je cherche juste une transition, voyez. La rponse que j'attends de vous est la suivante (je sais qu'il pourrait y en avoir d'autres) : laisser le travail astreignant (je n'ai pas os crire chiant) et rptitif la machine pour que l'utilisateur ne se concentre que sur les tches que l'on pourrait dire "nobles". Bon, c'est un peu utopique comme vision, mais a m'ira. "Laisser tout le travail astreignant et rptitif la machine..." Oui, c'est bien de cela dont je veux vous parler. Quand on pousse cette ide dans ces derniers retranchements, on peut obtenir des choses tonnantes. Par exemple : Et si le programmeur lui-mme n'crivait que les lignes "nobles" de son code et laissait la machine le soin de faire les rptitions elle-mme ? Cela vous surprend? Tant mieux. Cela vous interpelle? Encore mieux. J'en fais trop l? Ce n'est pas grave, c'est juste que ce sujet, plus que d'autres, me passionne. Partons d'un exemple trs simple.

:: V2 :: Devenons bibliothcaires

Imaginez que vous tes bibliothcaire. Imaginez une tagre "A" pleine de livres, que l'on vous demande de ranger en sens inverse sur une autre tagre "B". Rien de plus simple : vous prenez le premier livre de l'tagre A (tout droite) et vous le mettez la fin de

l'tagre B (tout gauche), puis vous prenez le deuxime et le mettez avant le premier, le troisime etc. Si vous deviez l'expliquer un bibliothcaire novice, vous diriez quelque chose comme : "Inverser les livres" c'est "Tu prends chaque livre et tu le mets avant ceux de l'tagre B". "Maintenant, attardons nous sur l'instant o vous avez pos le premier livre. Que vous reste-t-il faire? A ranger l' tagre A, en sens inverse, dans l'tagre B. Cela ne vous rappelle rien? C'est exactement notre travail de dpart. Plus prcisment, puisqu'il y a maintenant un livre dans l'tagre B, il nous faut ranger l' tagre A, en sens inverse, AVANT l'tagre B. Remarquez que cette prcision, le "avant", est tout aussi comprhensible quand l'tagre B etait vide. Imaginez que vous montriez cette fois un robot comment faire. Tout ce que vous devez lui montrer c'est a : vous prenez le premier livre de l'tagre A et vous le mettez juste avant la fin de l'tagre B. Puis vous lui dites : "Continue mon gars'". Il faut juste que votre discours, le vocabulaire utilis, soit bien prcis. Quelque chose comme : "Inverser les livres" c'est : "Mettre le premier livre de l'tagre A avant ceux de B, puis inverser les livres restantsde A. Notez que les notions de premier et de reste sont essentielles dans l'ide que j'essaye de vous exprimer. Cela tombe bien car si l'on compare la bibliothque une liste AppleScript, nous pouvons comparer le premier livre au "first item" de la liste, et le reste "rest of items" de la liste. Il y a tout de mme un norme pige dans ce principe : il arrive un moment o il n'y a plus de reste, et/ou/ donc pas de premier non plus. Si l'on oublie de dire notre robot qu'il doit s'arrter, il ne le fera jamais car il continuera aller de l'tagre A l'tagre B sans rien faire. Vous serez oblig de le dbrancher pour qu'il s'arrte. Il faut donc toujours donner un ordre d'arrt notre robot : vrifier l' absence d'un reste ou d'un premier. C'est en fonction des cas. Par exemple "jusqu' ce qu'il n'y ai plus de livres dans l'tagre A".

:: V3 :: Un peu de code ?

Tout cela reste abstrait, mais en comparant le code de la mthode traditionnelle avec celle dont je veux vous parler, cela va s'clairer. Voici une version dite "Classique" pour inverser une liste dans AppleScript : on inverser(EtagereA) set EtagereB to {} -- on cre une liste(tagre) vide repeat with chaqueLivre in EtagereA copy chaqueLivre to the beginning of EtagereB -- on copie chaque livre avant l'tagre B end repeat return EtagereB end inverser Vous avez dj vu plus complexe, n'est-ce pas? ;-) Je ne vous donnerai donc pas plus d'explications. Vous devez vous dire aussi qu'il existe une instruction "reverse of" qui fait le mme travail, mais je vous demande de l'oublier pour ma dmonstration. Voici une version avec la nouvelle mthode que je tente de vous expliquer depuis le dbut de cet article : on inverser(EtagereA) -- mon test pour sortir de la boucle if (count of EtagereA) < 2 then return EtagereA -- j'inverse le reste et j'ajoute le premier return inverser(rest of EtagereA) & {item 1 of EtagereA} end inverser Comme vous le remarquez de suite, je n'ai que deux lignes de code dans cette fonction. C'est l'un des avantages de la mthode. La premire ligne de code ne fait pas grand-chose, mais c'est pourtant la plus importante, je ne le dirai jamais assez : elle permet de sortir de la boucle. Sans elle, vous seriez oblig d'arrter le programme par un "pommemajuscule-point". Elle regarde s'il y a besoin de trier l'tagre. S'il n'y a qu'un livre ou mme pas un seul, ce n'est plus la peine de trier. Donc on renvoie l'tagre elle-mme.

La deuxime ligne code fait tout le travail. Regardez d'abord la fin de la ligne : elle se termine par "& {item 1 of EtagereA}". Cela veut dire que nous construisons une liste onous mettons le premier livre de l'EtagereA la fin. Et devant ce livre nous mettons quoi? Et bien tous les autres livres : le reste de la liste. Mais ils ne sont pas inverss? C'est vrai, mais puisque l'instruction que nous crivons sert cela, nous passons le reste des livres notre propre fonction. Elle nous les renverra inverss, et ils seront rangs avant le premier livre. Je ne sais pas pour vous, mais moi, la premire fois que j'ai dcouvert cette mthode, je lui ai trouv un ct "magique". On a l'impression que le travail se fait tout seul. Et c'est exactement cela : on donne l'exemple, et le programme poursuit avec le reste des donnes. Voil pourquoi je parlais de "Laisser tout le travail astreignant et rptitif la machine..." et de n'crire que la partie "noble" du code. Cette mthode de programmation s'appelle la rcursivit.

:: V4 :: Querelle de clochers ?

Oui, il y a un peu querelle sur cette mthode. Certains l'aaaaaaadorent (vous avez compris que j'en fais partie), d'autres la dnigrent. Leurs arguments sont recevables et sont les suivants : - la rcursivit est trs gourmande en mmoire. - elle est dangereuse utiliser - elle ne fait rien que l'on ne puisse faire par une mthode classique - elle est plutt lente. Les trois premiers points ne sont pas discutables et sont parfois des handicaps svres. - AppleScript, qui se tire pourtant assez bien de la rcursivit, trouve par contre des limites de mmoire, notamment sur la gestion de variables de type rcursif. - Le danger, nous l'avons vu, c'est de boucler ternellement, ce qui oblige interrompre de force le programme. C'est pour cela qu'il faut particulirement faire attentions aux conditions de sortie d'une fonction rcursive. - Je mets tout de mme un petit bmol sur le troisime point : s'il est vrai que tout ce qui est fait en rcursif peut tre fait autrement, une fois qu'on y est habitu, le code rcursif se rvle plus court, facile relire, comprendre et corriger, ce qui est loin d'tre le cas avec les mthodes classiques quand le travail faire est trs complexe. C'est sur le dernier point que la polmique est la plus virulente. En effet, certains langages sont plus lents en rcursif, mais ce n'est pas une gnralit. La plupart du temps ces diffrences sont minimes. Enfin, il existe certains langages comme le CAML (on me l'a dit donc je rpte) mais surtout le LISP (que je connais et que j'adore) qui sont exclusivement rcursifs et qui ont une puissance et une rapidit sidrantes. AppleScript s'en tire trs bien. Vous pourrez vous amuser chronomtrer versions "rcursives" et versions "classiques", les rsultats sont tellement proches qu'il est difficile de dpartager quelle mthode est la plus rapide. Peut-tre qu'une dfinition de la rcursivit s'impose? La rcursivit c'est l'usage, l'intrieur d'une fonction, de cette mme fonction pour poursuivre le travail entam.

:: V5 :: Comment et quand "penser rcursif"?

Avant un exemple plus complexe, voici un autre essai pour vous apprendre penser rcursif. Je dois maintenant ajouter un livre dans mon tagre A, par ordre alphabtique. Dans la vie courante : je regarde le nom des livres en partant du dbut. Quand je trouve un livre dont le titre vient aprs celui que je dois ranger, j'insre le nouveau livre juste avant. Cette fonction ne pose pas de problme avec une mthode classique, mais essayons de penser rcursif. En rcursif, je sais que je dispose volont de ma fonction applique sur le reste. Donc je dois penser : "Insrer livre = si mon livre vient avant le premier, je range le livre. Sinon, je range le livre dans le reste." On l'crit : on inserer(Livre, Etagere) -- Si l'tagre est vide, ranger le livre. Indispensable ! if Etagere = {} then return {Livre}

-- si le livre vient avant ceux de l'tagre, on retourne le livre et l'tagre if Livre < Etagere then return {Livre} & Etagere -- sinon, on retourne le premier livre de l'tagre -- et l'on insre le livre dans le reste de l'tagre return {item 1 of Etagere} & inserer(Livre, rest of Etagere) end inserer Vous suivez toujours ? Alors montez votre propre bibliothque ! On vient de recevoir plein de bouquins. Le seul problme, c'est qu'ils ne sont pas rangs du tout. Mais en vrai pros du rcursif, cela ne vous cause aucun souci. N'est-ce pas? on ranger(Bibliotheque) -- moins de 2 livres? La bibliothque est range if (count of Bibliotheque) < 2 then return Bibliotheque return inserer(item 1 of Bibliotheque, ranger(rest of Bibliotheque)) -- Je vais m'expliquer. end ranger Simple, n'est-ce pas? Ou bien vous tes un peu perturbs? Je me sers juste de la fonction "inserer" que nous avons crit auparavant. Cette fonction me permet de ranger un livre au bon endroit. Je range donc le premier livre dans le reste. Mais bien sr, le reste n'est pas tri. ! Qu' cela ne tienne, ma fonction sert justement cela. Je trie donc le reste des livres, et j'y insre le premier. Si cela vous semble encore surraliste, dfinissez la bibliotheque comme tant par exemple {"Voltaire","Rousseau","Montaigne","Zola"}, et demandez son rangement. Vous verrez que cela fonctionne. Prenez le temps de suivre les tapes, en les crivant sur un papier au besoin, pour voir ce que devient chaque fois la Bibliotheque. Vous verrez que vers la fin, le reste, du reste, du reste... c'est {"Zola"}, qui est forcment tri puisqu'il est seul. La fonction trier renvoi donc {"Zola"}. " partir de l, la fonction "insrer" peut entrer en action et ranger "Montaigne" par ordre alphabtique, puis "Rousseau", etc.

:: V6 :: De retour au Casino...

Et si nous voulions fignoler notre programme de roulette? Nous pourrions y insrer un tableau des "HighScores". Pour cela, il faudrait trier les joueurs par ordre dcroissant de pcule. Voil quelque chose qui ressemble fort notre classement de bibliothque, et nous pouvons mettre a profit cet article : on HighScores(joueurs) -- moins de deux joueurs? C'est forcment le meilleur if (count of joueurs) < 2 then return joueurs set reponse to inserer(item 1 of joueurs, HighScores(rest of joueurs)) if (count of reponse) > 10 then set reponse to items 1 thru 10 of reponse return reponse end HighScores on inserer(joueur, liste) if liste = {} then return {joueur} -- Indispensable ! -- si le pcule du joueur est suprieur, il se classe devant if pecule of joueur > pecule of item 1 of liste then return {joueur} & liste -- sinon, je l'insre dans le reste return {item 1 of liste} & inserer(joueur, rest of liste) end inserer Ce code est tellement proche de celui de notre bibliothque que vous vous passerez de commentaires. Sauf peut-tre concernant la limite que j'ai fixe au tableau des high-scores : 10 entres me semblent suffisantes. Dernire question : ou insrer ce code? Et bien pour ma part, je vois deux endroits :

- l'un au dbut, en mme temps que l'affichage du message de bienvenue et du bouton permettant de lire la rgle. - l'autre, de la mme faon, au moment d'afficher les scores de la partie qui vient de se terminer. Puisque nous utiliserons deux fois l'affichage des highs-scores, autant crire son usage dans une procdure que nous pourrons appeler volont. Ce qui donnerait par exemple ceci : on afficheHighScores() -- mise jour de l'action en cours set action of jeu to "High-Scores" -- inclus dans un repeat eternel repeat -- on dresse la liste des meilleurs joueurs set maListe to HighScores(joueurs of jeu) -- et l'on prpare un message set message to "Les dix meilleurs scores sont :" & return -- on complte le message pour chaque joueur repeat with chaqueJoueur in maListe set message to message & nom of chaqueJoueur & " : " & pecule of chaqueJoueur & "point(s)" & return end repeat -- on affiche le message set reponse to affiche(message, 0, {"Effacer", "OK"}) -- si l'utilisateur choisit d'effacer les highs-scores, on vide la proprit "joueurs" de "jeu" -- sinon, on sort de la boucle if button returned of reponse is "Effacer" then set joueurs of jeu to {} else exit repeat end if end repeat end afficheHighScores Ce qui se passe aussi de commentaires, sauf, peut-tre, pour vous dire que j'ai inclus dans ce code la possibilit d'effacer les high-scores, et donc de remettre la liste des joueurs zro. Pour les deux appels nos highs-scores, rien de bien compliqu et je vous propose d'aller jeter un oeil dans le code final de notre MiniRoulette pour voir comment j'ai procd. Le fichier se trouve ici.

Вам также может понравиться