Le BDR, c'est cool, mais c'est un peu le chaos. Tout d'abord, les buggles gigotent en tout sens, et en plus, le code que vous avez écrit pour les faire bouger est très difficile à lire. Voici un nouveau monde de BDR, où les buggles vont faire une gentille petite ronde plus reposante. Nous profiterons de cette accalmie pour nettoyer un peu le code grâce aux nouveaux éléments que nous allons maintenant étudier.
switch
[/!][!scala]Les filtrages[/!]Le plus difficile à lire du code précédent est certainement la cascade de conditionnelles. Quelque part dans votre programme, vous avez sans doute écrit quelque chose comme:
if ([!java]getIndication() == 'R'[/!][!scala]litMessage() == "R"[/!]) {
droite();
avance();
} else if ([!java]getIndication() == 'L'[/!][!scala]litMessage() == "L"[/!]) {
gauche();
avance();
} else if ([!java]getIndication() == 'I'[/!][!scala]litMessage() == "I"[/!]) {
retourne();
avance();
/* d'autre if */
} else {
fini = true;
}
À la première lecture du code, il n'est pas évident qu'il ne s'agit que d'un
choix avec 4 branches en fonction du résultat de
[!java]getIndication()[/!][!scala]litMessage()[/!].
Pour améliorer ceci, nous allons utiliser [!java]un switch
,
dont la syntaxe est la suivante en Java.[/!]
[!scala] un filtrage (pattern matching en anglais), qui est une construction
très agréable qui généralisant le if
. Il s'agit sans aucun
doute de l'un des avantages majeurs du langage Scala par rapport à d'autres
tels que le Java ou le Python. Cette construction n'est cependant pas
révolutionnaire puisqu'elle existe depuis assez longtemps dans des langages
comme OCaml ou Haskell, mais il n'empêche. Elle est carrément cool![/!]
switch (expression) { case premierValeur: queFaireSiExpressionVautPremiereValeur(); break; case deuxiemeValeur: queFaireSiExpressionVautDeuxiemeValeur(); break; case troisiemeValeur: queFaireSiExpressionVautTroisiemeValeur(); break; /* autant de cas sur le même modèle qu'on le souhaite */ default: queFaireSiExpressionVautAucuneDesValeursProposees(); }
Remarquez que chaque branche du switch doit être terminée par un
break
. Si on l'oublie, la machine continue d'exécuter le cas
suivant dans la liste quand elle a fini le code du cas où elle a sauté dans
le switch. Il y a même quelques très rares cas où ce comportement est
pratique.
On peut réécrire le code BDR précédent bien plus clairement grâce à la construction switch de la façon suivante.
switch (getIndication()) { case 'R': droite(); avance(); break; case 'L': gauche(); avance(); break; case 'I': retourne(); avance(); break; default: return; }[/!] [!scala]
expression match { case valeur possible => instructions case autre valeur => d'autres instructions case troisieme valeur => encore d'autres instructions case _ => instructions par défaut }
L'expression fournie avant le mot-clé match
est évaluée, et
ensuite, les branches sont évaluées les unes après les autres jusqu'à en
trouver une où la valeur entre le case
et le =>
correspond à la valeur de l'expression. Le symbole _
agit comme
un joker qui correspond à tout. Cela veut dire que la dernière ligne telle
qu'elle est écrite correspond toujours à la valeur fournie, quelle qu'elle
soit. Voici un petit exemple où une variable nom
est mis en
correspondance.
nom match { case "Martin" => println("Salut Martin, comment vas-tu?") case "Gerald" => println("He Gerald! Ça va?") case _ => println("Bonjour, étranger.") }
Il est aussi possible d'avoir plusieurs instructions par branches, et même
d'avoir plusieurs valeurs sur une branche donnée, séparées par le caractère
|
.
nom match { case "Martin" | "Gerald" => println("Bonjour "+nom+", entre."); ouvreLaPorte() case _ => println("Bonjour étranger. Passe ton chemin sans entrer."); fermeLaPorte() }
Il est même possible d'ajouter des gardes à vos branches. Il s'agit de conditions supplémentaires qui doivent être respectées pour que la branche soit appliquée. C'est par exemple pratique pour faire du filtrage sur un ensemble de valeurs.
age match { case i if i<10 => println("Salut gamin!") case i if i<20 => println("Salut mec") case i if i<30 => println("Bonjour jeune home") case _ => println("Bonjour monsieur") }
Remarquez qu'il n'est pas nécessaire de vérifier à la seconde ligne que la valeur est supérieure à 10 puisque les lignes sont considérées dans l'ordre. Si la seconde ligne est considérée, c'est que la première ne correspondait pas.
Enfin, il est même possible de filtrer sur plusieurs variables à la fois!
(x,y) match { case (0,0) => println("C'est le point origine") case (_,0) => println("C'est un point de l'ordonée") case (0,_) => println("C'est un point de l'abscisse") case (_,_) => println("C'est un point quelconque") }
Je vous avais bien dit que le filtrage scala était une construction surpuissante ! Je l'adore !
[/!][!java|scala]Appliquez les améliorations que nous venons de voir pour adapter le code de votre buggle au nouveau pas de danse explicité ci-dessous.[/!] [!python]Nous allons maintenant apprendre un nouveau pas de dance à nos buggles. Il est un peu plus complexe, mais sinon, c'est toujours la même histoire.[/!] Remarquez qu'il est maintenant possible d'avancer jusqu'à 6 cases à la fois.
Indication | Quoi faire |
[!java]'R'[/!][!scala|python]"R"[/!] | Tourner à droite et avancer d'une case |
[!java]'L'[/!][!scala|python]"L"[/!] | Tourner à gauche et avancer d'une case |
[!java]'I'[/!][!scala|python]"I"[/!] | Se retourner (faire demi-tour) et avancer d'une case |
[!java]'A'[/!][!scala|python]"A"[/!] | Avancer d'une case |
[!java]'B'[/!][!scala|python]"B"[/!] | Avancer de deux cases |
[!java]'C'[/!][!scala|python]"C"[/!] | Avancer de trois cases |
[!java]'D'[/!][!scala|python]"D"[/!] | Avancer de quatre cases |
[!java]'E'[/!][!scala|python]"E"[/!] | Avancer de cinq cases |
[!java]'F'[/!][!scala|python]"F"[/!] | Avancer de six cases |
[!java]'Z'[/!][!scala|python]"Z"[/!] | Reculer d'une case |
[!java]'Y'[/!][!scala|python]"Y"[/!] | Reculer de deux cases |
[!java]'X'[/!][!scala|python]"X"[/!] | Reculer de trois cases |
[!java]'W'[/!][!scala|python]"W"[/!] | Reculer de quatre cases |
[!java]'V'[/!][!scala|python]"V"[/!] | Reculer de cinq cases |
[!java]'U'[/!][!scala|python]"U"[/!] | Reculer de six cases |
(n'importe quoi d'autre) | Arrêter de dancer. |
Quand votre programme fonctionne de nouveau, passez à l'exercice suivant.