Scratch n’offre pas de manière naturelle des commandes permettant de travailler avec des chaînes de caractères ni ce que l’on appelle des « regex » ou expressions régulières permettant de rechercher des motifs particuliers dans un texte. L’opération n’est cependant pas impossible. En effet, travaillant depuis peu à la création d’un interpréteur Logo sous Scratch, tout simplement un petit programme permettant de jouer et dessiner avec la tortue comme dans le bon vieux Logo ou des logiciels comme Géotortue, j’ai été confronté au problème de la gestion des erreurs de frappe. Faire un interpréteur est en soi assez simple. Gérer les possibles erreurs faites par l’utilisateur relève par contre un peu plus du parcours du combattant.

Ainsi, par exemple, j’ai créé une fonction nommée « tn » pour « turn » qui est suivie d’un nombre de degrés. Celle-ci fait tourner la tortue à gauche ou à droite en fonction du nombre de degrés entrés, le sens naturel choisi étant celui des aiguilles d’une montre.

Sont considérées comme correctes les syntaxes suivantes :

  • tn 9 -> tourne de 9 degrés ; de même que tn -9 (cette fois, dans le sens inverse des aiguilles d’une montre)
  • tn 25 -> tourne de 25 degrés ; de même que tn -25
  • tn 132 -> tourne de 132 degrés ; de même que tn -132

Il nous faut donc vérifier que les commandes entrées par l’utilisateur correspondent bien à ce schéma.

Première étape avant de vérifier le reste de la séquence, s’assurer que la commande entrée est bien « tn ». Pour cela, on analyse les deux premières lettres de la réponse.

Une fois « tn » validée, nous pouvons vérifier la longueur de la séquence. L’exemple « tn 9 » nous montre que la taille minimum est 4 caractères et avec l’exemple « tn -132 » le maximum 7 caractères. Imbriquons un nouveau test dans la commande « si … sinon … ». Je choisis de les imbriquer pour faire au plus simple. C’est un peu moche mais nous verrons par la suite une méthode permmetant de d’obtenir quelque chose de plus cohérent et simple à lire.

Rien cependant ne m’empêche de taper « tnhkdj » et de recevoir le message « OK ! ». Nous savons que le troisième caractère doit obligatoirement être un espace. Ajoutons donc un nouveau test en dessous du premier.

Une fois ces tests passés, nous savons que notre commande est valide. Reste à savoir si l’utilisateur n’a fait aucune erreur dans la saisie du paramètre. Nous allons vérifier caractère par caractère. Les caractères acceptés sont « 0123456789-« . En dehors, point de salut. La commande sera automatiquement rejetée. Pour ne pas trop alourdir le code, il vaut mieux créer une fonction à part et l’utiliser dans le code principal.

C’est là que cela se complique un peu. Il me faut d’abord créer 5 variables. Petit rappel sur les noms variables : une variable peut porter n’importe quel nom mais il convient de lui donner un nom explicite de manière à pouvoir se souvenir facilement de son rôle. Personnellement j’ai tendance à reprendre sans cesse les mêmes noms de projet en projet afin de ne pas me perdre. Voici mes variables pour analyser la réponse de l’utilisateur :

  • string : la chaîne de caractères à analyser, correspondant à tout ce que l’utilisateur va entrer après « tn « 
  • count1 : un premier compteur utilisable dans une boucle
  • count2 : un second compteur
  • chars : la liste des caractères acceptés, soit « 0123456789-« 
  • verify : un compteur permettant de comptabiliser le nombre de tests validés ; si le paramètre entré est par exemple « -123 », soit 4 caractères, et que « verify » est égal à 4, on sait que les 4 caractères ont été validés ; si « verify » est égal à 3, un caractère est faux et invalide complètement le paramètre tapé par l’utilisateur (par exemple « -12a »)

Première étape : éliminer « tn  » de la chaîne de caractères à analyser, soit ne s’intéresser qu’au reste de la chaîne à partir du caractère n°3.

Après utilisation de cette commande, ma variable « string » est bien égale à « -123 » si je tape « tn -123 ». Il s’agit maintenant de vérifier si chaque caractère de cette variable est bien compris dans l’ensemble « chars », soit « 0123456789-« .

On commence par réinitialiser le premier compteur. Le code suivant comporte deux boucles.

La première passe en argument les caractères un à un de la chaîne, soit dans le cas de « -123 » : « -« , « 1 », « 2 », « 3 ». La seconde compare chacun de ces caractères aux caractères contenus dans la variable « chars ». Si l’un des tests est ok, c’est-à-dire que le caractère examiné est trouvé dans la variable « chars », on augmente la variable verify de 1.

Comme vous l’avez compris, un test validé = 1 point. Pour que le test soit complet, il faut que le nombre de points corresponde à la longueur de la chaîne de caractères. On vérifie cela avec une nouvelle condition « si … alors … sinon … ».

Petit conseil au passage: il vaut mieux avant intégration du script dans le programme utiliser des messages d’erreur personnalisés, chaque erreur générant un message particulier. Cela facilite la vie au moment de débuguer. On évite aussi de masquer l’affichage des variables tant que le script n’est pas fini.

Avons-nous d’ailleurs terminé ? Presque. Il reste un détail à régler : corriger la variable en cas de mauvaise valeur. Par exemple, dans notre cas, tourner de 360 degrés ou plus serait stupide car cela revient à faire un tour complet et plus. Pour revenir à une valeur plus raisonnable, il suffit de faire une division par 360 ou -360 en cas de valeur négative et de conserver le reste.

Pour éviter d’imbriquer des « si … alors … sinon … » à répétition, il suffit de s’inspirer de la méthode utilisée avec la variable « verify ». Si l’on attribue un point à chaque test validé, le score obtenu à la fin permettra de déterminer si le texte entré apr l’utilisateur est valide (par exemple, 10 tests effectués et score = 10 -> texte valide ; 10 tests effectués et score = 7 -> texte non valide).

Lien pour télécharger le script.