top of page

5. Modules

Organisation arborescente

 

Comme on l'a vu, l'indication Root.Home, au-dessus de la zone de commande, désigne le module courante c'est-à-dire l'espace de stockage des variables créées. En tapant la commande list (ou ls), on affiche la liste des éléments contenus dans ce module. Et là, on retrouve "en vrac" toutes les variables et fonctions que nous avons définies. On notera d'ailleurs que la Programmatrice les sauvegarde automatiquement, ce qui permet de les retrouver à chaque fois qu'on la redémarre et qui est très appréciable.

Si on veut faire un peu de ménage, on peut utiliser la commande remove (ou rm) comme on l'a déjà indiqué. Mais plutôt que de tout effacer, on peut créer des sous-modules et y ranger les éléments que l'on a créés. Pour cela, on peut utiliser la commande multi-fonctions define mais comme cette fois on ne veut par définir des fonctions mais des modules, on le précisera comme ceci :

  • define RecreMath : Module

Cette commande a pour effet 1) de créer un nouveau sous-module nommé "RecreMath" et 2) de changer de module courant en nous positionnant dans celui-ci. Et en effet, le module courant affiché est maintenant Root.Home.RecreMath.

En tapant quelques commandes, vous pouvez vérifier que ce nouveau module est bien vide et qu'il est possible d'y créer localement de nouvelles variables. Nous vous laissons faire ces manipulations en utilisant les instructions que nous connaissons bien maintenant...

De nouvelles instructions relatives aux modules et aux éléments qu'ils contiennent sont utiles à connaître :

- cd <module> (nom emprunté aux systèmes d'exploitation, cd étant l'abréviation de change directory) qui permet de changer de module courant en se positionnant dans <module>,

- ls <module> qui permet de lister le contenu du module <module> (nous utilisions auparavant la commande ls sans indication de module),

- move <element1> to <module> qui permet de déplacer un élément du module courant vers le module <module>,

- move <element1> to <element2> qui permet de renommer un élément.

- copy <element1> to <module> qui permet de copier un élément du module courant dans le module <module>,

- copy <element1> to <element2> qui permet de copier un élément sous un autre nom.

Depuis le module Root.Home.RecreMath, on peut retourner au module parent, Root.Home, par la commande :

  • cd Root.Home

Mais on peut aussi utiliser les noms relatifs '.' (module courant), '..' (module parent), '...' (module parent du parent) etc.

Exemple :

  • cd ..

Et, une fois dans le module Root.Home, on peut déplacer les variables et fonctions définies à la page Récréation mathématique par des commandes comme :

  • move facto to RecreMath

Ainsi les modules sont utiles pour mieux ranger les éléments créés. Mais également ils permettent d'effectuer des développements "modulaires" en regroupant des éléments de programmes qui concourent à une tâche particulière. 

En effet, un programme est composé en général de multiples fonctions, variables ou autres éléments qui interagissent pour effectuer le traitement voulu. Ceux-ci sont alors regroupés et organisés dans une arborescence de modules.

Nous vous proposons d'illustrerons ce point par un petit jeu.

Jeu des allumettes

Voici la règle de ce jeu à 2 joueurs : un tas d'allumettes est disposé devant les 2 joueurs. Chacun enlève à tour de rôle des allumettes du tas et celui qui enlève les dernières gagne la partie. Mais il y a deux contraintes à respecter : ne pas enlever toutes les allumettes du premier coup (bien sûr !) et, ensuite, ne pas en enlever plus du double du nombre que l'adversaire vient d'enlever.

Par notre programme, vous pourrez jouer contre l'ordinateur.

Eh bien, figurez-vous que c'est la suite de Fibonacci, que nous avons programmée précédemment, qui permet de gagner à ce jeu. Il suffit de toujours ramener le nombre d'allumettes à un nombre de la suite de Fibonacci. Par exemple, si le tas contient 38 allumettes, il faut en prendre 4 pour se ramener à 34 qui est un nombre de la suite.

Mais ce n'est pas toujours possible : dans notre exemple, si le joueur précédent n'avait pris qu'une allumette, le maximum autorisé est 2.

D'autre part, il faut veiller à ce que l'autre joueur ne puisse terminer juste après. Par exemple, si nous avons 33 allumettes, il n'est pas question d'en retirer tout de suite 12 pour nous ramener à 21 car l'adversaire pourrait rafler le reste d'un coup tout en respectant le maximum de 24 (12*2).

Dans ces 2 derniers cas, l'idée est de remplacer l'objectif initial (le nombre total d'allumettes) par l'objectif intermédiaire : le nombre d'allumettes à enlever pour atteindre la prochaine position gagnante c'est-à-dire, dans le 1er exemple, 4 et, dans le 2nd, 12.

Pour résoudre ce problème, nous aurons à définir deux fonctions que nous placerons dans un nouveau module Root.Home.Jeu.

=> Nous vous proposons donc de créer ce module Jeu, après quoi nous pourrons y définir les fonctions de notre programme.

Il nous faut maintenant définir la fonction qui calcule les valeurs cibles appartenant à la suite de Fibonacci. Nous écrirons pour cela une nouvelle variante de la fonction fibo qui rendra pour résultat la valeur de la suite la plus grande, inférieure ou égale à un nombre donné. Nous l'appellerons fibomax.

Puis, à partir de celle-ci, nous définirons la procédure du jeu elle-même nommée allumettes.

A vous de jouer maintenant... soit en écrivant le programme vous-même si vous êtes motivé, soit en recopiant le code ci-contre pour tester directement le jeu !

fibomax (max:int):int
var p,q = 0,1;
while q<=max do
   p,q = q,p+q
done;
p

allumettes (N:int);
var max : int = (N-1) // 2;
var otees : int;
while true do

   repeat
      read "Combien d'allumettes ? (maximum " ++ max ++ ")", otees
   until otees <= max; # pour éviter la tricherie !

   N -= otees;
   write "Vous : " ++ otees ++ ", Reste : " ++ N;
   if N <=0 then
      write "Vous avez gagné !";
      break
   fi;

   max = 2*otees;
   if N <= max then
      write "Moi : " ++ N;
      write "J'ai gagné !";
      break
   fi;

   # calcul du nombre à oter
   var objectif = N;
   otees = N - fibomax(N);
   while (otees > max || 3*otees >= objectif) do
      objectif = otees; # nouvel objectif
      otees = objectif - fibomax(objectif)
   done;
   # en position défavorable, il faut bien quand même enlever 1 allumette
   if (otees == 0) then otees = 1 fi;

   N -= otees;
   write "Ordi : " ++ otees ++ ", Reste : " ++ N;
   max = 2*otees

done

Affichage de l'arbre des données

Petit à petit, l'ensemble des données enregistrées dans la mémoire de la Programmatrice s'enrichit. Pour en avoir une vue d'ensemble, vous pouvez retourner dans le répertoire Home (par cd ..) et cliquer sur le bouton 'Display Tree'. Vous verrez alors les modules créés et en cliquant sur la petite poignée située à leur gauche, vous pourrez afficher leur contenu.

bottom of page