Nous savons déclarer des variables, nous déplacer dans nos mémoires, afficher un caractère et faire une boucle. C’est bien, mais pour aller plus loin en Brainfuck et en faire quelque chose de réellement intéressant, il nous faudra un peu plus que ça. Il va nous falloir comprendre comment conditionner l’exécution d’un bout de code. Accrochez-vous bien, et re-plongeons-nous dans ce langage si particulier ! Comprenons comment fonctionnent les conditions en brainfuck.

Le concept

Tout va se passer avec la syntaxe []. Si vous avez bien suivi le premier article, le Brainfuck n’exécute les boucles que si la variable actuelle est égale à 0. Donc si on prend l’exemple suivant:

[+]

Si nous lançons l’exécution de notre code et que nous regardons le résultat de nos variables, tout est à 0. Alors que dans le code suivant:

+[+>]

Notre mémoire aura 2 dans la mémoire 0, et 0 dans la mémoire 1 (j’utilise deux cases mémoires car pour sortir de la boucle, il faut que la mémoire active quand on rencontre un ] soit à 0).

On voit donc bien que dans le premier cas, nous ne sommes pas du tout entré dans la boucle, dans le second oui et nous avons pu exécuter des actions. Tout clair ? Eh bien voilà la base que nous allons utiliser pour toutes nos conditions: il faudra jouer avec nos variables pour qu’elles vaillent 0 ou plus.

Vous avez l’idée ? Alors créons un quizz en Brainfuck

Nos premières conditions en brainfuck

Tout d’abord on va afficher la question, pour ça j’utilise le très pratique Générateur de text de copy.sh. On va donc afficher la question (je ne vous la donne pas, je vous laisse lancer le code de votre côté).

-[--->+<]>----.---[-->+++<]>.------------.[--->+<]>---.[->+++<]>+.-[->+++<]>.-[--->++<]>-.+++++.++++++++.+[->+++<]>.+++++++++.++++++.[->++<]>+.-[----->++++<]>.++[--->++<]>.-------.--[--->+<]>-.--[->++++<]>-.[->+++<]>.---.--[->+++<]>.[->++<]>-.>++++++++++.[->+++++<]>-.----.[--->++<]>++.>-[--->+<]>-.[---->+++++<]>.++++.[->+++++<]>-.+[->++<]>.[-->+++<]>++.+++++++++++++.----.---------.+++++++++++++.+.+[++>---<]>-.[--->+++++<]>+.-[--->++++<]>+..>++++++++++.[->+++++<]>.-----.[--->++<]>++.++++++[->++<]>+.[--->+<]>.------.

On regarde à quoi ressemblent nos variables, et on vient ensuite tout remettre à 0. Ensuite on retourne sur la 3e variable (j’explique ensuite pourquoi):

[-]<[-]<<<<[-]<<<<<<<<<[-]<<<[-]<<<<<<<<<<<<<

Maintenant notre utilisateur a deux solutions: entrer 1 ou 2. Si on se réfère à une table ASCII, ça nous donne 49 ou 50, donc en retirant 49 à l’entrée utilisateur nous obtiendront 0 ou 1. Récupérons-donc l’entrée et retirons 49:

# On récupère la réponse de l'utilisateur
,
# On retourne à notre variable "0"
<<
# On ajoute 5
+++++
# On boucle donc 5 fois en ajoutant 10 à la variable "1" à chaque fois
[>++++++++++<-]
# On retire 1 pour obtenir 49
>-
On 49 fois 1 à notre variable "2"
[>-<-]
# On remet 1 dans notre variable "1" pour le "else" et on retourne sur la variable qui contient la réponse
+>

En condensé, ça nous donne:

,<<+++++[>++++++++++<-]>-[>-<-]+>

Afficher les réponses

Maintenant on se retrouve sur une variable qui vaut soit 0 (réponse juste) soit 1 (réponse fausse). Si la réponse est fausse on va donc afficher quelque chose. Ensuite on fait en sorte qu’à la fin de la boucle on se retrouve dans une variable vide avec une autre vide juste avant elle.

Comme ça ensuite on retourne une variable avant. Si on était entré dans le if, on arrive dans tous les cas sur une var vide donc on entrera pas dans le else. Si on était pas dans le if, on arrive sur la variable « 1 » qui contient 1. Donc on entrera dans la boucle suivante. Faisons déjà notre if:

[>>++++[++++>---<]>++.+[-->+++<]>-.--[--->+<]>--.+[----->+<]>+.+.-.-[->+++++<]>-.+.>>]

Ici on affiche juste le message, ensuite on se décale de 2 variables à droite. On est donc sûrs que la variable et sa précédente seront vides. N’hésitez pas à utiliser un compilateur avec debugger pour en être sûr.

Maintenant hors boucle, on retourne dans la variable précédente:

<

Ici on se retrouve soit dans la variable 1 (qui contient la valeur 1) si on a entré la bonne réponse, soit la variable 10 (qui est vide) si on a entré la mauvaise réponse. Donc on peut afficher le message de félicitation qui ne s’exécutera que si on est dans la variable 1:

[>++++[++++>---<]>-.---[----->+<]>-.+++[->+++<]>++.+[--->+<]>.-------.[--->+<]>-----.+.>]

Et voilà !

Nous avons maintenant une exécution conditionnelle dans notre code. À partir de là, la porte est ouverte à une très grande diversité de programmes. La seule limite est votre imagination… Et les 30.000 variables du langage !

Je vous mets ici le code complet:

# On affiche la question
-[--->+<]>----.---[-->+++<]>.------------.[--->+<]>---.[->+++<]>+.-[->+++<]>.-[--->++<]>-.+++++.++++++++.+[->+++<]>.+++++++++.++++++.[->++<]>+.-[----->++++<]>.++[--->++<]>.-------.--[--->+<]>-.--[->++++<]>-.[->+++<]>.---.--[->+++<]>.[->++<]>-.>++++++++++.[->+++++<]>-.----.[--->++<]>++.>-[--->+<]>-.[---->+++++<]>.++++.[->+++++<]>-.+[->++<]>.[-->+++<]>++.+++++++++++++.----.---------.+++++++++++++.+.+[++>---<]>-.[--->+++++<]>+.-[--->++++<]>+..>++++++++++.[->+++++<]>.-----.[--->++<]>++.++++++[->++<]>+.[--->+<]>.------.

# On reset les variables
[-]<[-]<<<<[-]<<<<<<<<<[-]<<<[-]
# On retourne sur la troisième mémoire
<<<<<<<<<<<<<

# On récupère la réponse de l'utilisateur
,

# On retire 49 pour voir si l'utilisateur a tapé 1 (cf. table ASCII)
<<+++++[>++++++++++<-]>-[>-<-]+>

# Si notre variable est supérieure à 0 c'est que l'utilisateur a tapé 2
[>>++++[++++>---<]>++.+[-->+++<]>-.--[--->+<]>--.+[----->+<]>+.+.-.-[->+++++<]>-.+.>>]
# On retourne sur la mémoire de notre valeur pour le else
<
# On affiche bravo
[>++++[++++>---<]>-.---[----->+<]>-.+++[->+++<]>++.+[--->+<]>.-------.[--->+<]>-----.+.>]