> Tutoriel LeekScript
Bien ! Il est temps d'ajouter des conditions à vos programmes !
Pour l'instant, votre code fait toujours la même chose. Les conditions vont remédier à cela.
Les conditions sont la première "structure de contrôle" dont nous allons parler. Celles-ci permettent de rendre votre code plus flexible, de faire en sorte qu’il s’adapte au contexte.
Pour l’instant, vous avez vu que votre code s'exécute de façon linéaire, une instruction après l’autre. Maintenant, nous allons voir comment exécuter ou non du code selon une condition.
Mais avant d’en venir aux conditions, il faut d’abord revenir sur les opérateurs. Nous avons surtout parlé des opérateurs permettant d’effectuer des calculs, et pour s’attaquer aux conditions, il va falloir voir ceux qui permettent de faire des comparaisons.
Ces opérateurs sont un peu différents de ceux que nous avons déjà vu. Par exemple, vous avez vu qu’en LeekScript, l’expression "4 + 6" donne pour résultat 10. Le résultat est un entier, un nombre. C’est une expression mathématique exprimant un calcul.
Les opérateurs de comparaison vont permettre d’écrire des expressions mathématiques qui exprimeront une relation. Si nous écrivons l’expression "2 ", c’est-à-dire "Inférieur strictement" et "Supérieur strictement". (Si besoin, la touche pour ces symboles se trouve à gauche du "W", l’un se fait avec la touche MAJ enfoncée, l’autre sans)
Bref, ces opérateurs permettent de tester la relation d'ordre entre deux éléments. Par exemple :
var resultat = a b;
Si la valeur de "a" est supérieure strictement à celle de "b", le résultat sera true, qui sera assigné à la variable "resultat". Si c’est l’inverse, ce sera false.
On parle bien ici de relations "strictes". Si a et b ont la même valeur, le résultat sera false; puisque aucune n’est plus petite ou grande que l’autre.
Et maintenant, la version non stricte des opérateurs relationnels.
Ainsi, pour l’opérateur supérieur ou égal, il suffit de mixer les opérateurs d’égalité et de relation. On obtient l’opérateur ">=" ! Le symbole de supériorité suivi du symbole d’égalité.
Par exemple :
var resultat = a >= b;
Si la valeur de "a" est supérieure ou égale à celle de "b", le résultat sera true, qui sera assigné à la variable "resultat". Si c’est l’inverse, donc inférieure strictement, le résultat sera false.
Et pour traduire "Inférieur ou égal", l’opérateur est donc "
A B A && B
falsefalse->false
falsetrue->false
truefalse->false
truetrue->true
Avec ce code, vous pouvez tester les quatre couples de valeur :
debug("false AND false : " + (false && false) ); // Affiche : false debug("false AND true : " + (false && true) ); // Affiche : false debug("true AND false : " + (true && false) ); // Affiche : false debug("true AND true : " + (true && true) ); // Affiche : true
En Français, c’est un "OU logique". Il y a deux façons de l’écrire en LeekScript, soit en écrivant "or", soit en utilisant le symbole "||" (deux "|", le symbole de la touche 6, en utilisant ALT GR).
Retestons avec le code précédent :
var A = true; var B = false; debug(A || B); // Affiche : true debug(A or B); // Affiche : true
Cette fois, le résultat est true ! Le résultat d'un OU logique sera true si au moins une des deux valeurs vaut true.
Ainsi, on a :
A B A || B
falsefalse->false
falsetrue->true
truefalse->true
truetrue->true
A nouveau, si vous voulez tester :
debug("false OR false : " + (false || false) ); // Affiche : false debug("false OR true : " + (false || true) ); // Affiche : true debug("true OR false : " + (true || false) ); // Affiche : true debug("true OR true : " + (true || true) ); // Affiche : true
En Français, c’est un "NON logique". Il y a deux façons de l’écrire en LeekScript, soit en écrivant "not", soit en utilisant le symbole "!" (C’est un bête point d’exclamation).
Contrairement aux précédents qui comparaient deux valeurs, celui-ci ne s’applique que sur une seule. Il permet d'inverser un booléen.
Testons le :
var A = true; var B = false; debug(!A); // Affiche : false debug(!B); // Affiche : true
Le résultat d'un NON logique sera l'inverse de la valeur. Si la valeur est true, elle devient false, et inversement.
Simplement, on a :
Anot A
false->true
true->false
Évidemment, si vous voulez tester :
debug("!false : " + (!false)); debug("!true : " + (!true));
Les opérateurs sont vraiment utiles, vous pouvez me croire. Qu’ils soient logiques ou arithmétiques, bientôt vous en utiliserez absolument partout.
Pfiou, nous en avons fini avec les opérateurs. Peut-être que vous avez encore du mal à voir à quoi ils vont vous servir. Cela devrait devenir plus clair dans la suite.
if est le mot-clé qui va nous permettre d'écrire une condition. En anglais, "if" signifie "si". Il permet de dire à votre poireau Si ceci, alors fais cela.
La syntaxe est la suivante :
if (condition) instruction;
Ici, la condition sera une "expression". Si cette expression vaut true, donc si elle est vrai, alors l’instruction sera exécutée. Par contre, si l’expression est fausse (si elle vaut false), alors l’instruction ne sera pas exécutée.
Mais cette syntaxe ne permet d'exécuter qu'une seule instruction.
Si vous souhaitez mettre plus d'instructions, il faudra utiliser cette syntaxe :
if (condition) { instruction; instruction; instruction; }
Avec cette syntaxe, vous pouvez mettre autant d'instructions que vous le souhaitez. Voire même une seule, ou aucune. Cette syntaxe est un peu plus lisible et aérée que la précédente.
Si "condition" est une expression qui a pour résultat true, alors le bloc de code contenu entre les accolades "{" et "}" sera exécuté. Et si la condition n'est pas vérifiée et vaut donc false, il ne se passera rien.
Essayons ceci :
if (false) { debug("La condition est vraie !"); }
Il ne se passe rien ! La condition étant fausse, l'instruction debug n'est pas exécutée. Essayez de remplacer false par true dans la condition, vous verrez que cette fois-ci, le message apparaît.
else est le mot-clé qui permet d'exécuter du code si la condition n'est pas remplie. En anglais, "else" signifie "sinon". Il permet de dire à votre poireau Si ceci, alors fais cela, sinon, fais ceci.
La syntaxe pour l'utiliser est la suivante :
if (condition) { // Instructions } else { // Autres instructions }
Comme précédemment, si la condition est vraie, le code dans les accolades qui suivent le IF sera exécuté. Mais si la condition n'est pas vraie, c'est le code se trouvant dans les accolades après le ELSE qui sera exécuté.
Améliorons le code vu plus haut :
if (false) { debug("La condition est vraie !"); } else { debug("La condition est fausse !"); }
Et voilà ! Avec true, vous aurez le message annonçant que la condition est vraie. Et avec false, vous aurez le message annonçant que la condition est fausse.
Il est possible de "fusionner" les mots-clé if et esle afin de créer différents cas de figure. On obtient quelque chose comme ceci :
if (condition) { // "condition" est vraie } else if (condition2) { // "condition" est fausse, mais "condition2" est vraie } else { // "condition" et "condition2" sont fausses }
Vous voyez le topo ? Non ? Pas de panique ! Vous allez comprendre avec quelques exemples. Il est temps de mettre en pratique les différents opérateurs que vous avez découvert !
Les ternaires sont une autre façon d'écrire une condition. Prenons une condition basique avec un if/else :
if (condition) { action1(); } else { action2(); }
Le même code avec un ternaire donnera ceci :
(condition) ? action1() : action2();
On peut aussi s’en servir pour une affectation, par exemple :
var maVariable = (condition) ? valeur1 : valeur2;
Les ternaires ont le désavantage d'être beaucoup moins lisibles que la structure if. Mais ils sont un peu moins cher en opérations.
Si vous débutez, vous n'avez pas encore besoin d'optimiser la moindre opération de votre code. Préférez donc utiliser la structure if classique pour vos débuts.
Comme vous l'avez vu, il est possible de comparer des valeurs. Et que vaut le résultat d'une comparaison ? Un booléen, oui ! Ainsi, on peut facilement faire ce genre de choses :
if (3 < 4) { debug("3 est inférieur à 4 !"); }
Bon, ce n'est pas la découverte du siècle, mais vous commencez peut-être à imaginer tout ce que vous pourriez faire. Faisons une comparaison un peu plus intéressante, et utile... Récupérons la distance entre vous et votre adversaire !
var distance = getCellDistance(getCell(), getCell(getNearestEnemy()));
if (distance < 10) { debug("L'ennemi approche mon Commandant !"); }
Et voilà ! Vous êtes en mesure d'exécuter du code en fonction de la distance avec votre adversaire. Ici, le message ne s'affichera que si l'ennemi se trouve à moins de 10 cellules de vous.
Si vous avez un peu de mal avec la ligne :
var distance = getCellDistance(getCell(), getCell(getNearestEnemy()));
En voici une version plus simple à comprendre :
var maCellule = getCell(); // On récupère la cellule de son poireau var ennemi = getNearestEnemy(); // Puis on récupère l’id de l’ennemi var celluleEnnemi = getCell(ennemi); // Ensuite, la cellule de cet ennemi var getCellDistance(maCellule, celluleEnnemi); // Et enfin, on obtient la distance entre les deux cellules
Vous pouvez aussi imbriquer vos conditions, comme ceci par exemple :
var enemy = getNearestEnemy(); var distance = getCellDistance(getCell(), getCell(enemy));
if (distance < 11) { if (distance < 8) { useWeapon(enemy); } else { useChip(CHIP_SPARK, enemy); } }
Prenons la fonction lineOfSight, elle renvoie true s'il y a une ligne de vue entre les deux cellules passées en paramètres.
Testons si votre poireau peut voir son adversaire :
var enemy = getNearestEnemy(); var los = lineOfSight(getCell(), getCell(enemy));
if (los) { debug("J'le vois chef ! J'le vois !"); } else { debug("Où est-il passé !? Il se cache ce lâche !"); }
Et hop, vous pouvez savoir si votre poireau voit son adversaire, et donc s'il peut lui tirer dessus.
N'oubliez pas que cette fonction renvoie un booléen, il est parfaitement inutile de faire quelque chose comme cela :
var myCell = getCell(); var enemyCell = getCell(getNearestEnemy());
if (lineOfSight(myCell, enemyCell) == true) { debug("J'le vois chef ! J'le vois !"); }
Le IF vérifie déjà si la condition est vraie, c'est comme si vous disiez à votre poireau : Est-ce que la condition "Il y a une ligne de vue est vraie" est vraie ? C'est redondant et vous prenez le risque que je vous tape sur les doigts.
Par contre, si c'est la condition inverse qui vous intéresse, vous pourriez vouloir faire quelque chose comme cela :
var myCell = getCell(); var enemyCell = getCell(getNearestEnemy());
if (lineOfSight(myCell, enemyCell) == false) { debug("Où est-il passé !? Il se cache ce poltron !"); }
Ce n'est pas mieux ! Le retour de lineOfSight vaut trueou false. Avec le retour, votre condition sera (true == false) ou (false == false). Ce qui est assez inutile.
Quelle est la bonne solution alors ? C'est d'utiliser le NON logique !
var myCell = getCell(); var enemyCell = getCell(getNearestEnemy());
if (lineOfSight(myCell, enemyCell)) { debug("J'le vois chef ! J'le vois !"); }
if (!lineOfSight(myCell, enemyCell)) { debug("Ou est t-il passé !? Il se cache ce poltron !"); }
Voilà comment on utilise correctement des booléens. Ce n'est plus redondant, c'est beau, c'est propre. On en mangerait.
Vous n'avez pas besoin des opérateurs ==, !=, === et !== avec des booléens. Il vous serviront principalement pour comparer des nombres, des constantes.
Par exemple :
if (getWeapon() != WEAPON_PISTOL) { setWeapon(WEAPON_PISTOL); }
Avec ce code, si vous n'avez pas d'armes dans les mains ou si ce n'est pas le Pistolet, alors votre poireau équipera ce dernier.
Une des premières réflexions qui vous traversera l'esprit sera peut-être celle-ci :
"Hum, je pourrais utiliser le Pistolet si je le peux, et dans le cas contraire, utiliser Étincelle". Et bien pourquoi pas ?
Il vous faudra donc commencer par les conditions à réunir pour pouvoir utiliser le Pistolet.
Ce dernier possède une portée allant de 1 à 7. Il faut donc commencer par vérifier la distance à l'aide de getCellDistance :
if (getWeapon() != WEAPON_PISTOL) { setWeapon(WEAPON_PISTOL); }
var enemy = getNearestEnemy(); var distance = getCellDistance(getCell(), getCell(enemy));
if (distance <= 7) { useWeapon(enemy); useWeapon(enemy); useWeapon(enemy); }
Mais ce n'est pas suffisant. La grande majorité des armes et des puces sont soumis à ce qu'on appelle "la ligne de vue". En clair, pour pouvoir utiliser le Pistolet, votre poireau doit pouvoir voir sa cible. Pour vérifier cela, on utilise la fonction lineOfSight.
if (getWeapon() != WEAPON_PISTOL) { setWeapon(WEAPON_PISTOL); }
var enemy = getNearestEnemy(); var distance = getCellDistance(getCell(), getCell(enemy)); var los = lineOfSight(getCell(), getCell(enemy));
if (distance <= 7 && los) { useWeapon(enemy); useWeapon(enemy); useWeapon(enemy); }
Nous avons notre condition ! On peut la lire comme "Si la distance est inférieure ou égale à 7 et qu'il y a une ligne de vue".
Il n'y plus qu'à rajouter l'utilisation d'Étincelle.
if (getWeapon() != WEAPON_PISTOL) { setWeapon(WEAPON_PISTOL); }
var enemy = getNearestEnemy(); var distance = getCellDistance(getCell(), getCell(enemy)); var los = lineOfSight(getCell(), getCell(enemy));
if (distance <= 7 && los) { useWeapon(enemy); useWeapon(enemy); useWeapon(enemy); } else { useChip(CHIP_SPARK, enemy); useChip(CHIP_SPARK, enemy); useChip(CHIP_SPARK, enemy); }
Ce code utilisera le Pistolet s'il y a la vue et la portée pour, sinon il utilisera Étincelle. Il n'y a pas besoin de vérifier la portée d'Étincelle. Si votre poireau est trop loin, il ne pourra juste pas l'utiliser.
Désormais, vous pouvez rendre votre code intelligent. Vous êtes capable de le faire s'adapter à la situation.
Le prochain chapitre parlera des boucles, une autre notion très importante en programmation.
Impossible de charger les données du jeu.
Vérifiez votre connexion et réessayez.