TDM n°3 : Utiliser les chaînes de caractères !
Posté le 18/07/2018 18:00
Le Tuto Du Mercredi [TDM] est une idée qui fut proposée par Ne0tux. Voici le principe : un mercredi sur deux, nous postons un petit tutoriel sur l'Utilisation de la calculatrice, le Transfert, la Programmation, ou encore la Conception de jeu. Je vous en présente la troisième édition.
Apprendre à se servir des chaînes de caractères (Str) ! (Débutant)
Niveau : ★ ★ ☆ ☆ ☆
Une chaîne de caractère, c'est comme une phrase. Lorsque vous écrivez, vous assemblez des lettres et des signes de ponctuations, des chiffres parfois ou encore d'autres caractères spéciaux. Alors qu'une variable comme A ou θ contient une valeur numérique, les Str – chaînes de caractères, ou string en anglais – contiennent des suites de lettres et de chiffres, des mots, des phrases, etc. Elle sont bien trop peu utilisées dans la plupart des programmes du site, surtout chez les programmes débutants ou les programmes de cours, alors qu'elles peuvent se révéler extrêmement efficaces.
Partie I : Qu'est-ce qu'une Str ?
NB : Ce TDM se veut complémentaire à un cours déjà existant sur l'utilisation des Chaînes de caractères par Totoyo. N'hésitez pas à le consulter également si vous ignoriez jusqu'à présent l'existence des Str.
Comme indiqué dans l'introduction, une chaîne de caractères (Str) contient... des caractères. Des caractères peuvent être des lettres en bas de casse ou capitale, des chiffres, des signes de ponctuations, des espaces, des lettres grecques, des signes mathématiques, et tout autre caractère spécial. Tout ce que vous seriez susceptible d'écrire avec votre clavier, en somme.
Attention toutefois, une Str
N'EST PAS une valeur numérique. Toute tentative de calcul entre une Str et une valeur numérique provoquerait une erreur. Il existe cependant des techniques qui permettent de passer d'une Str à une valeur numérique et vice-versa.
Les chaînes de caractère peuvent avoir de nombreuses utilités. Elles peuvent être utilisées pour les programmes de cours, pour les dialogues dans un jeu, pour contenir le nom du joueur ou d'autres informations, et peut avoir des utilisations qui vont même bien au-delà de ce que vous pourriez imaginer : hardcoder des maps pour un jeu, stocker des données sur des monstres ou des attaques dans le code, ou même contenir des caractères qui décrivent des valeurs numériques... Avec un peu d'imagination, tout est possible !
Retenez bien que le premier caractère d'une chaîne est indexé à 1, et non pas à 0. Retenez également qu'une Str ne peut pas contenir plus de 255 caractères. Sachez également qu'un caractère prend 1 voire 2 octets, alors qu'une variable dans une liste en prend 12, voire 24. Employer les Str peut s'avérer très utile à cet endroit-là aussi.
Partie II : Initialiser les Str
Sachez qu'il existe de nombreuses fonctions qui permettent de manipuler les Str. La première chose à savoir faire est d'initialiser une Str comme il se doit. Voici différentes méthodes :
"Bonjour Mister 2 !" → Str 1
Str 2 → Str 1
? → Str 1 //Ce que rentre l'utilisateur va dans Str 1. Utile pour demander le nom du joueur par exemple.
Il existe des cas plus particuliers :
List 1[0] → Str 1
Exp►Str(Y1,Str 1)
La première ligne fonctionne dans les deux sens. Référez-vous au TDM précédent. La deuxième ligne est assez particulière et fait appel à une technique expliquée dans
ce tutoriel. Vous n'aurez probablement pas à vous en servir.
Attention toutefois. Les techniques suivantes
ne fonctionnent pas :
A → Str 1 //A est une valeur numérique, pas une Str.
"Hello world!"
Str Ans → Str 1 // Str Ans n'existe pas.
BONJOUR → Str 1 //BONJOUR n'a pas de guillemets : il sera considéré comme le produit des variables B, O, N, J, O, U et R. Donc, une valeur numérique.
Hello world!" → Str 1 //Bien sûr, erreur syntaxe s'il manque un guillemet.
Str 2 + A + ", je te love !" → Str 1 //Même délire : A est une valeur numérique.
StrJoin( Str 2, A) → Str 1 //Même problème qu'au dessus.
//Etc.
"Je suis :" → Str 1 //Ne dysfonctionne pas forcément mais peut provoquer des erreurs inattendues : l'interpréteur basic peut considérer le double-point comme un saut de ligne. Soyez vigilants en débugant votre programme si vous faites cela.
Partie III : Manipuler les fonctions pour les Str
Comparer deux Str : StrCmp(
StrCmp( compare chaque caractères des deux chaînes à la suite en partant, bien sûr, du premier caractère à gauche, jusqu'à ce que les deux caractères comparés soient différents. Pour les chiffres et les lettres, voici un ordre croissant pour StrCmp :
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
//Voici d'autres cas :
StrCmp("CAKE", "CAKEISALIE") //"CAKE" < "CAKEI". Renvoie -1
StrCmp("5", "5-") // "5" < "5-", donc renvoie -1.
Inverser une Str : StrInv(
Cette fonction inverse simplement l'ordre des caractères de la chaîne. Peut s'avérer amusant.
StrInv("Bonjour !") → Str 1
// Str 1 contient "! ruojnoB".
Concaténer (assembler) deux Str : StrJoin(
StrJoin( sert à fusionner deux chaînes de caractères. Toutefois, elle ne peut pas fusionner plus de deux Str en même temps : cette fonction ne prend que deux paramètres.
"BALDI" → Str 1
StrJoin("Bonjour, ", Str 1) → Str 1
//Str 1 contient "Bonjour, BALDI"
/!\ Cette technique n'est pas celle que je recommande pour concaténer deux chaînes. Voir la suite.
Concaténer plusieurs Str à la fois : +
Cette technique est
vivement recommandée pour concaténer plusieurs Str. Par rapport à Strjoin(, elle est plus courte et permet d'assembler plus de deux chaînes d'une seule traite.
"Darks" → Str 2
"666" → Str 1
Str 1 + " est le code secret, " + Str 2 + " !" → Str 3
// Str 3 contient "666 est le code secret, Darks !"
Extraire une partie de la chaîne : StrMid( (ou
StrLeft( et
StrRight( )
La fonction StrMid( – et, dans une moindre mesure, StrLeft( et StrRight( – est extrêmement utile. Je ne cesse de m'en servir. Elle permet d'extraire une partie d'une chaîne à partir d'un indice. Elle peut aussi prendre un troisième paramètre : la longueur de la chaîne à prendre. Si ce paramètre n'est pas préciser, StrMid( extrait tout le reste de la Str à partir de l'indice indiqué.
StrMid( Str 1, 4, 8) //extrait les 8 caractères de la Str 1 à partir du 4ème caractère compris.
Obtenir la longueur précise d'une Str : StrLen(
StrLen( renvoie la longueur de la chaîne de caractère indiquée. Attention toutefois,
une Str ne peut pas dépasser 255 caractères !
StrLen( "TROLOLOL") // Renvoie la valeur numérique 8.
Modifier la casse des lettres d'une Str : StrLwr( (Minuscules) et
StrUpr( (Majuscules)
StrLwr( et StrUpr( mettent respectivement les lettres d'une Str en minuscule et en majuscule. Ils ne prennent comme paramètre que la Str que vous voulez modifier.
StrLwr("Drak A ECRIT CE TUTO !")
// Renvoie "drak a ecrit ce tuto !"
StrUpr("Je n'aime PAS le chiffre 7."
// Renvoie "JE N'AIME PAS LE CHIFFRE 7."
Rogner une Str par la droite ou la gauche : StrShift(
StrShift( prend deux paramètres : la Str à manipuler et le nombre de caractères à rogner. Ce nombre peut être positif ou négatif. Les caractères qui disparaissent sont remplacés par des espaces.
Rechercher un caractère ou une chaine de caractères dans une Str : StrSrc(
Extrêmement utile, à connaître. StrSrc( renvoie la position (valeur numérique) de la première occurrence indiquée trouvée. Pour faire une analogie, c'est comme si vous faisiez
Ctrl + F sur votre navigateur internet. Bien sûr, StrSrc( respecte la casse. Peut prendre un troisième paramètre qui indique l'indice à partir duquel chercher. Attention : SrtSrc( s'arrête à la première occurrence trouvée. Quand rien n'est trouvé, renvoie 0.
"ATTENTION ! ZONE DANGEREUSE !" → Str 1
StrSrc(Str 1, "!") //Renvoie la valeur 11.
StrSrc(Str 1, "!", 12) //Commence la recherche à partir du 12ème caractère. Renvoie la valeur 29.
StrSrc(Str 1, "TENTION !") //Renvoie la position de "T" : 3.
StrSrc(Str 1, "x") //Renvoie 0 : Il n'y a pas de "x".
StrSrc(Str 1, "TENTION !", 9) //Renvoie aussi 0.
StrSrc(Str 1, "TABLE") //Renvoie également 0.
StrSrc(Str 1, "TANTION !") //Idem
Changer une Str en valeur numérique : Exp(
Exp( convertit la chaîne de caractère en une expression mathématique. Si la chaîne contient des lettres, elles sont considérées comme des variables alphanumériques. Si des lettres ne peuvent être converties en variables alphanumériques (minuscules, lettres spéciales, etc.), ou si des caractères ne peuvent être utilisés pour un calcul (espaces, etc.), provoque une erreur syntaxe.
Exp("32") //Renvoie la valeur numérique 32.
Exp("32A") //Renvoie le résultat de 32 * A.
Exp("32 * A") //Erreur syntaxe à cause des espaces.
Exp("BONJOUR") //Renvoie le produit des variables B, O, N, etc.
Exp("Bonjour !") //Erreur syntaxe.
Exp("5i+A*ln (12)-2") //Fonctionne, si "ln " a été entré avec la touche "ln" de la calculatrice.
Faire se déplacer du texte dans une Str : StrRotate(
StrRotate( décale de N les caractères d'une Str. N peut être positif ou négatif, et peut dépasser la longueur de la Str. Elle permet, entre autres, de simuler un défilement de texte.
StrRotate("Achetez les frites de FRITEMAX ! ", 3)
//Renvoie "etez les frites de FRITEMAX ! Ach"
StrRotate("Achetez les frites de FRITEMAX ! ", -5)
//Renvoie "X ! Achetez les frites de FRITEMA"
Partie IV : Application
Il y a de nombreuses manières d'exploiter les fonctions des Str ! En voici quelques unes, assez simples, qui pourront se révéler surement très utiles pour vos programmes, petits ou gros ! N'hésitez pas à poser des questions si besoin !
Enregistrer un nom de joueur.
Que ce soit pour nommer un personnage ou pour enregistrer un nom pour un score de jeu, il est souvent pratique d'être en mesure d'avoir le nom du joueur (ou un pseudonyme choisi par ce dernier). Nous pouvons très simplement récupérer son nom, et même faire en sorte qu'il commence par une majuscule et que le reste soit en minuscule !
"Votre nom"?→Str 1 //Str 1 contient donc le nom.
StrUpr(StrLeft(Str 1, 1)) + StrLwr(StrMid(Str 1, 2))→Str 1
//Dans cette deuxième ligne, on met la première lettre en majuscule et les suivantes en minuscule.
Faire une fonction qui affiche un message en combat.
Plutôt que de réécrire 100 fois un truc affreux comme "Text, 1,1,"Je suis..." : Text 9,1,"Très fort !", etc.", servez-vous des Str ! Dans un moteur de combat, par exemple, vous aurez surement besoin d'afficher des messages à chaque attaque. Mettons que j'enregistre le message à afficher dans Str 2 et que le nom du joueur soit dans Str 1. Cette fonction sera contenue dans un sous-programme.
PROG "COMBAT" :
//Début de tour :
Str 1 + " se prépare à agir !" → Str 2
Prog "TEXT"
[...]
//Au moment de l'attaque, dont le nom est dans Str 3 :
Str 1 + " lance " + Str 3 + " ! " → Str 2
Prog "TEXT"
[...]
//En fin de tour, par exemple :
Str 1 + " a terrassé l'ennemi ! Wheeee!" → Str 2
Prog "TEXT"
//Etc.
_________________________
PROG "TEXT" :
Cls
Text 1,1,Str 2
Do
GetKey
LpWhile Ans ≠ 77
//Affiche le texte et se met en "pause" tant que le joueur n'appuie pas sur [ALPHA]
Faire afficher sur une ligne un texte trop long.
En mode graphique, les lettres prennent, en moyenne, 4 px de large. L'écran de la calculatrice fait 128 px. 128 / 4 = 32. On peut donc considérer qu'à partir de 32 caractères, le texte à afficher dépassera vraisemblablement du cadre. On a le choix entre faire en sorte à ce que le texte ne dépasse jamais 32 caractères, l'afficher sur une deuxième ligne ou bien l'afficher sur une unique ligne en le faisant défiler. Voici comment faire pour cette dernière méthode :
"Je suis la phrase à afficher et j'ai beaucoup trop de lettres. Oh mon dieu ! Achetez les frites de chez FRITEMAX !" → Str 1
Text 1,1,Str 1
Do
If StrLen(Str 1) > 31 // Si la phrase est trop longue...
Then For 1 → A To StrLen(Str 1) Step 2
Text 1,1,StrRotate(Str 1, A) //On la fait défiler dans une boucle
GetKey⇒Break // On sort dès que le joueur presse une touche
Next
IfEnd
GetKey
LpWhile Not Ans //On arrête à l'appui d'une touche.
Hardcoder des données sur des personnages.
Mettons que vous ayez des données par défaut à attribuer à des personnages. Par exemple, une valeur qui correspond à sa force, une autre à sa sagesse et une autre à la robustesse de sa barbe (lol ?), et que vous voulez les attribuer à une liste lorsque le joueur choisit tel ou tel personnage. Si de telles données sont comprises entre 0 et 9, alors vous pouvez tout à fait avoir quelque chose de très propre comme ceci :
//J est l'ID du personnage.
J = 1 ⇒"645Jasper" →Str 4
J = 2 ⇒"428Pavel" →Str 4
J = 3 ⇒"908Brutus" →Str 4
J = 4 ⇒"373Gael" →Str 4
[...]
For 1→A To 3
Exp( StrMid( Str 4, A, 1)) → List 1[A] //On récupère les carac
Next
StrLeft( Str 4, 4)→Str 1//On récupère le nom.
Sélectionner un Sprite pour votre héros en Locate.
Lorsque vous faites un jeu en Locate avec un personnage qui s'y déplace, vous l'affichez surement en faisant :
Locate A, B, "θ"
Sachez que "θ" est aussi une chaîne de caractère. Alors pourquoi ne pas enregistrer ce caractère dans un Str, changeable à volonté ?
ClrText
"==================== Choisissez le heros"
0→D //Le compteur
"αβδσθ" → Str 1 //Les skins disponibles
While 1
StrLeft( StrRotate( Str 1, D), 1) → Str 2
Locate 10,4,Str 2
Do
GetKey
LpWhile Not Ans
Ans = 77 ⇒ Break //Le joueur valide
Ans = 27 ⇒ Isz D
'a //Ce commentaire évite le saut de ligne de Isz D si D = 0.
Ans = 38 ⇒ Dsz D
'a
WhileEnd
Str 2 → Str 1 //Str 1 contient le sprite choisi.
Et voila ! Maintenant, vous n'avez plus d'excuse. UTILISEZ LES STR ! Si ce tuto vous a plu et que vous souhaiteriez voir des techniques plus avancées sur l'utilisation des Str, alors manifestez-vous dans les commentaires !
Liens utiles :
Voir le TDM précédent :
Manipulez les Listes !
Tuto pour avoir
40 Str supplémentaires
Cours officiel de Planète Casio
sur les Str.
Var2Str, un utilitaire de
Totoyo pour convertir une variable en Str.
Citer : Posté le 18/07/2018 18:06 | #
Ce tuto est très intéressant !!
Je connaissais certaines de ces fonctions mais pas toute...
On dit que le Basic Casio est limité, c'es vrai mais on l'utilise à 10% de ses capacités maximum...
Citer : Posté le 18/07/2018 18:25 | #
Merci Shadow ! Disons plutôt que le Basic Casio est limité par rapport à d'autres langages de programmation.
Citer : Posté le 18/07/2018 19:56 | #
Bien joué, voilà un document très bien écrit ! Quelques remarques :
- « Il existe cependant des techniques qui permettent de passer d'une Str à une valeur numérique et vice-versa. » : alors techniquement non, ces deux types n'ont aucun rapport normalement, il faut créer des rapports qui n'existent pas et techniquement tu peux le faire entre n'importe quels types, aussi superstitieux que ça rende (e.g. « si un signal court alors lettre « E »).
- pour StrCmp(), il serait pas mal de rajouter le cas de « s'il n'y a plus assez de caractères pour comparer », comme avec CAKE et CAKEISALIE5.
- pour StrSrc(), le phrasé peut sous-entendre que pour rechercher la chaîne la fonction ne regarde que le premier caractère, peut-être rajouter un exemple comme "TENTION ?", "TANTION !" ou "TABLE".
Mon blog ⋅ Mes autres projets
Citer : Posté le 18/07/2018 21:47 | #
Merci de ton commentaire Cake. J'ai apporté des modifications en prenant en compte tes remarques pertinentes ! Par contre, pour la première remarque, je ne vois pas comment modifier le tuto en conséquence.
Citer : Posté le 19/07/2018 08:44 | #
Excellent tutoriel !
C'est vrai, à chaque fois qu'on me parle des strings, je me demande pourquoi je les ais pas encore utilisé...
Ça sera sûrement utile pour mon projet Évocalc.
Citer : Posté le 19/07/2018 17:28 | #
J'ai lu un poil vite, mais je ne crois rien avoir vu sur le niveau de compacité du stockage et la vitesse des fonctions. Tu peux certainement rappeler que la plupart des caractères font 1 ou 2 octets tandis qu'une valeur numérique dans une liste fait 12 octets, et linker le benchmark de Zezombye sur la vitesse d'accès aux variables puisqu'il mentionne quelques Str.
Citer : Posté le 19/07/2018 19:17 | #
Merci infiniment Drak! Ce tutoriel va faciliter énormément de choses!
Citer : Posté le 19/07/2018 21:25 | #
Comment faire une génération de map graphique AVEC des strings comme faisait reference Alexit sans Evocalc ?
Citer : Posté le 19/07/2018 23:33 | #
Ce à quoi faisait référence Alexot dans son commentaire, c'est le jeu Calcraft qui est en locate. Toutefois, tu peux aussi utiliser des strings pour générer des map en mode Graphique, et c'est ce que j'ai fait pour mon propre projet de jeu. C'est bien à ça que tu penses ?
Citer : Posté le 24/07/2018 00:17 | #
Toutefois, tu peux aussi utiliser des strings pour générer des map en mode Graphique
Ah ça m’intéresse. Peux-tu en parler davantage s'il te plaît? Perso j'en ai vraiment besoin...
Citer : Posté le 24/07/2018 00:35 | #
En gros, l'idée : dans mon exemple, j'ai des map qui se font en 11 * 6 cases, donc 66 cases. Dans mon Str, chaque case correspond à un caractère. Donc, une str s'écrit, dans le code, en 66 caractères + quelques opcodes pour les conditions.
Then //Position mondiale du joueur, ordonnée
Y = 1 ⇒ "000000000000000000000000000000000000000000000000000000000000000000"→Str 3
Etc.
IfEnd
Mettons par exemple que "0" décrit un vide, tout simplement, et que "1" décrit... une touffe d'herbe.
"000000000001111111111100000000000000000000000000000000000000000000"→Str 3 //J'ai une ligne de touffes d'herbe
"100000000001000000000010000000000100000000001000000000010000000000"→ Str 3 //J'ai une colonne de touffes d'herbe
"11111111111111111111111 [...] 1111111"→Str 3 //Ma map est recouverte d'herbe.
Ainsi, tu auras des caractères, qui vont de 1 à 9 puis de A à Z puis de a à z, pour décrire chacun de tes sprites.
Ensuite, pour convertir un caractère en valeur numérique, tu fais ça :
StrSrc( Str 9, "D")◢ //Ici, donne la valeur numérique correspondante pour "D" : 13
Pour plus de détails, je te cherche un lien... J'arrive.
Ajouté le 24/07/2018 à 00:39 :
Ici, j'explique comment j'ai fait pour stocker les maps dans mon jeu. Ce qui va t'intéresser sera surtout la première partie, avant que je ne parle des PNJ : https://www.planet-casio.com/Fr/forums/topic14452-8-Projet-de-RPG...-en-BASIC-!.html#154780
Tu peux aussi fouiller, si tu en as le courage, dans cette page de commentaire : https://www.planet-casio.com/Fr/forums/topic14452-2-Projet-de-RPG...-en-BASIC-!.html#145124
Citer : Posté le 24/07/2018 10:24 | #
Wow porquoi j'y ai pas pensé plus tôt ?
Citer : Posté le 26/07/2018 17:03 | #
Après, ce qui est plus fin, c'est de gérer les collisions. Soit tu crées une matrice en te basant sur le Str pour voir quelles cases sont traversables ou non, et quelles cases ont un effet, ce qui te permet de manipuler le tout un peu plus aisément ; soit tu te bases uniquement sur le Str (c'est ce que je fais) pour gérer les collisions et autres. Cette dernière solution évite d'avoir à remplir une matrice pour rien, mais demande de gérer assez bien le tout, avec la fonction StrCmp.
Par ailleurs, si vous avez des envies pour le TDM suivant, faites-m'en part !
Citer : Posté le 26/07/2018 18:02 | #
Hum...d'accord, je vois plus clair. Merci!
Ajouté le 26/07/2018 à 18:06 :
Ca marche aussi si on veut creer une map en multi drawstat?
Citer : Posté le 26/07/2018 18:39 | #
Bah, oui ! Cette technique, c'est surtout une technique de stockage. C'est à toi de voir comment tu intègres ton multi drawstat avec.
Citer : Posté le 26/07/2018 18:51 | #
Ah d'accord, je comprends
Citer : Posté le 27/07/2018 19:20 | #
J'ai rajouté dans le TDM un petit cas d'initialisation de Str où ça peut foirer : les doubles-points entre guillemets.
Citer : Posté le 28/07/2018 08:01 | #
Tu peux l'enlever ça, c'est plus valable dans les OS récents (>= 2.02).
Dans les OS en 2.00 il y avait effectivement un bug avec la double flèche :
qui faisait que l'interpréteur interprétait le contenu du string en tant que code, technique exploitée par ce tuto : https://www.planet-casio.com/Fr/forums/topic14192-1-[Astuce-Inutile]-Goto,-Str-et-Deux-points.html
Mais là il est corrigé et normalement il n'y a plus aucun bug en utilisant des deux points entre guillemets.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 28/07/2018 13:11 | #
Un tutoriel sur l'utilisation du DrawStat,SuperDrawStat et MultiDrawStat serait le bienvenu,
Je ne comprend pas cette technique...
Ajouté le 28/07/2018 à 13:11 :
Un tutoriel sur l'utilisation du DrawStat,SuperDrawStat et MultiDrawStat serait le bienvenu,
Je ne comprend pas cette technique...
Citer : Posté le 28/07/2018 13:53 | #
Bah, je sais pas, NineStars a déjà fait un tutoriel pour expliquer chacune de ces techniques. Est-ce que tu les as lu et que tu as du mal à comprendre ce qui y est expliqué ?