Ajouter un comportement conditionnel en Kotlin

1. Avant de commencer

Dans cet atelier de programmation Kotlin, vous allez créer un autre jeu de dés, Lucky Dice Roll, dans lequel vous devrez essayer d'obtenir un chiffre porte-bonheur. Votre programme définira un chiffre porte-bonheur et lancera le dé. Vous comparerez ensuite le résultat du lancer par rapport au chiffre porte-bonheur et imprimerez un message approprié des données extraites. Pour ce faire, vous allez apprendre à comparer les valeurs et à prendre différentes décisions dans votre programme Kotlin.

Pour vous aider au mieux à vous concentrer sur les nouveaux concepts de programmation, sans avoir à vous soucier de l'interface utilisateur, vous utiliserez l'outil de programmation Kotlin sur navigateur pour générer vos résultats dans la console.

Conditions préalables

  • Vous savez ouvrir, modifier et exécuter du code dans https://developer.android.com/training/kotlinplayground.
  • Vous savez créer et exécuter un programme Kotlin qui utilise des variables, des fonctions avec des arguments, des classes avec des méthodes, et qui affiche un résultat dans la console.

Points abordés

  • Comment utiliser les instructions if et else.
  • Comment comparer des valeurs à l'aide d'opérateurs tels que "supérieur à" (>), "inférieur à" (<) et "égal à" (==).
  • Utiliser des instructions when pour choisir une option en fonction d'une valeur donnée.
  • À quoi correspond le type de données Boolean et comment utiliser ses valeurs true et false pour la prise de décision.

Objectifs de l'atelier

  • Créer un jeu de dés basé sur Kotlin, Lucky Dice Roll, qui vous permet de spécifier un chiffre porte-bonheur. Le joueur gagnera la partie s'il obtient le chiffre porte-bonheur.

Ce dont vous avez besoin

  • Un ordinateur avec une connexion Internet.

2. Prise de décision dans votre code

Votre programme Lucky Dice Roller doit déterminer si l'utilisateur a obtenu un chiffre porte-bonheur et reçoit des félicitations, ou s'il reçoit un message l'invitant à réessayer.

En tant que développeur d'applications, vous devez décider comment celles-ci se comportent et génèrent des résultats différents pour vos utilisateurs.

Si vous créez une application d'achat, vous pouvez afficher différents écrans en fonction des options de livraison sélectionnées par l'utilisateur. Lors d'un quiz, vous pouvez afficher différents écrans en fonction de la réponse du joueur (correcte ou incorrecte). En fonction de l'application, vous pouvez prendre en compte de nombreux résultats, dont vous devrez tenir compte dans votre code.

Dans votre programme Lucky Dice Roller, l'application doit gérer plusieurs cas de figure, par exemple :

  • Si le résultat du dé est le chiffre porte-bonheur, alors un message de félicitations s'affiche !
  • S'il en est autrement (else if), le résultat du dé n'est pas le chiffre porte-bonheur, alors un message invitant à réessayer s'affiche.

Pour ajouter cette logique à votre code, utilisez des mots clés Kotlin spéciaux tels que if, else et when.

Examinons quelques exemples.

Utiliser une instruction if pour configurer une condition remplie

  1. Inspectez le code ci-dessous. Pouvez-vous deviner le résultat ?
fun main() {
   val num = 5
   if (num > 4) {
       println("The variable is greater than 4")
   }
}
  1. Copiez et collez le code dans l'éditeur de programme Kotlin, puis exécutez le programme pour observer le résultat.
The variable is greater than 4

Le processus décisionnel de ce programme se déroule comme suit :

  1. Créer une variable num et lui attribuer la valeur 5..
  2. Si la valeur de num est supérieure à 4, imprimer "The variable is greater than 4".
  3. Dans tous les autres cas, ne rien faire.

Dans l'exemple ci-dessus, num est défini sur 5. L'instruction if vérifie si la variable est supérieure à 4. Comme c'est le cas, le système exécute ensuite les instructions entre accolades et imprime le message.

Vous remarquerez la forme que prend l'instruction if :

  • Commencez par le mot clé if.
  • Ajoutez deux parenthèses (). La condition se trouve entre les parenthèses. La condition correspond à tout ce qui peut être true ou false. Par exemple, si un nombre est supérieur à un autre.
  • Ajoutez deux accolades {}. Entre les accolades, indiquez le code à exécuter si la condition est true.
if (condition-is-true) {
    execute-this-code
}

Utiliser une instruction if pour configurer une condition qui n'est pas remplie

  1. Remplacez la valeur de num par 3, comme indiqué ci-dessous. Que va-t-il se passer si vous exécutez ce code ?
fun main() {
    val num = 3
    if (num > 4) {
        println("The variable is greater than 4")
    }
}
  1. Copiez et collez le code dans l'éditeur de programme Kotlin, puis exécutez le programme pour observer le résultat vide.

Avec num défini sur 3, aucun élément n'est imprimé, car la valeur de num est inférieure à 4. Ainsi, la condition selon laquelle num doit être supérieur à 4 est false. Le code entre les accolades ne s'exécute pas, et rien n'est imprimé.

Utiliser else pour créer une alternative en cas d'échec des conditions

Plutôt que de ne rien faire, vous pouvez proposer une alternative aux utilisateurs lorsqu'une condition n'est pas remplie. Vous pouvez effectuer cette opération à l'aide d'une instruction else.

  1. Ajoutez une instruction else pour afficher un message lorsque la valeur de num n'est pas supérieure à 4, comme indiqué ci-dessous. Que va-t-il se passer si vous exécutez ce code ?
fun main() {
    val num = 3
    if (num > 4) {
        println("The variable is greater than 4")
    } else {
        println("The variable is less than 4")
    }
}
  1. Copiez et collez le code dans l'éditeur de programme Kotlin, puis exécutez le programme pour observer le résultat.
The variable is less than 4
  1. Notez que lorsque num a la valeur 3, le programme affiche le message "The variable is less than 4" associé à l'instruction else, car num n'est pas supérieur à 4.
  2. Remplacez num par 5 et exécutez le programme une nouvelle fois. Il est maintenant vrai que num est supérieur à 4. Le programme affiche "The variable is greater than 4".
  3. Remplacez num par 4 et exécutez votre programme. La valeur 4 n'est pas supérieure à 4 et le programme affiche "The variable is less than 4".

Bien que "The variable is less than 4" soit la sortie correcte pour les conditions que vous avez définies dans le code, cette instruction affichée n'est pas exacte, car 4 n'est pas inférieur à 4. Vous pouvez ajouter une autre condition qui vérifie la troisième possibilité, à savoir si num est exactement 4 et affiche une instruction correcte lorsque cette condition est "true".

Utiliser une combinaison if else pour ajouter d'autres conditions

Vous pouvez définir plusieurs conditions. Par exemple, voici comment couvrir toutes les possibilités pour num :

  • Si num est supérieur à 4, imprimez "The variable is greater than 4".
  • Si le champ num est égal à 4, imprimez "The variable is equal to 4".
  • Dans les autres cas, imprimez "The variable is less than 4".

Il s'agit de cas différents dans l'instruction if-else. Trois cas sont listés.

Le code mis à jour se présente comme suit :

fun main() {
    val num = 4
    if (num > 4) {
        println("The variable is greater than 4")
    } else if (num == 4) {
        println("The variable is equal to 4")
    } else {
        println("The variable is less than 4")
    }
}

Notez les modifications suivantes :

  • La valeur de num est désormais définie sur 4 pour que vous puissiez tester la nouvelle condition.
  • Entre les instructions if et else d'origine se trouve une nouvelle instruction else if pour le cas où num est parfaitement égal à 4.
  1. Copiez et collez le code ci-dessus dans l'éditeur de programme Kotlin, puis exécutez le programme pour observer le résultat.
The variable is equal to 4
  1. Testez la modification de la valeur de num et observez son impact sur le résultat. Définissez num sur 2 et 6 pour que toutes les conditions affichent true.

Flux de contrôle

Lorsque vous examinez les instructions if-else ci-dessus, le code s'exécute selon les conditions définies. Le déroulement de l'exécution avec ces conditions est appelé "flux de contrôle" du programme.

  • Imaginons que votre lancer de dés num produise un résultat égal à 3. Le programme vérifie la première condition (num > 4). Le résultat est "false", le programme vérifie la condition suivante (num == 4), qui est également "false". Le programme exécute ensuite le code de l'instruction "else", qui est la dernière option.
  • Si le résultat du lancer de dé affiche 6, la première condition (num > 4) est "true". Le programme affiche le message "The variable is greater than 4". Comme cette condition est "true", il n'est pas nécessaire de vérifier le reste. L'instruction if-else a été utilisée.
  • Utilisez une combinaison "else" + "if" pour ajouter d'autres conditions.

3. Créer le jeu Lucky Dice Roll

Dans cette section, en vous appuyant sur ce que vous avez appris lors de la tâche précédente, vous mettrez à jour le programme Dice Roller pour vérifier si vous avez obtenu un chiffre porte-bonheur prédéfini. Si vous obtenez le chiffre porte-bonheur, vous avez gagné !

Configurer votre code de démarrage

Vous démarrez le jeu Lucky Dice Roller avec un code semblable à celui de l'ancien programme Kotlin Dice Roller. Vous pouvez modifier la fonction main() dans votre code précédent pour qu'elle corresponde à celle que vous avez indiquée, ou copier et coller le code ci-dessous pour commencer.

fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    println("Your ${myFirstDice.numSides} sided dice rolled ${rollResult}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        return (1..numSides).random()
    }
}

Vérifier si le chiffre porte-bonheur a été lancé

Définissez d'abord un chiffre porte-bonheur, puis comparez le lancer des dés à ce nombre.

  1. Dans main(), supprimez l'instruction println().
  2. Dans main(), ajoutez une val appelée luckyNumber et attribuez-lui la valeur 4. Le code doit se présenter comme suit.
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4
}
  1. En dessous, ajoutez une instruction if avec une condition () entre parenthèses qui vérifie si rollResult est égal à (==) luckyNumber. Laissez un espace entre les accolades {} pour pouvoir ajouter du code.
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4
    if (rollResult == luckyNumber) {

    }
}
  1. Entre les accolades {}, ajoutez une instruction println pour imprimer "You win!".
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    if (rollResult == luckyNumber) {
        println("You win!")
    }
}
  1. Exécutez votre programme. Vous devrez peut-être l'exécuter plusieurs fois avant d'obtenir le message de réussite.
You win!

Répondre quand le chiffre porte-bonheur n'a pas été obtenu

Si le programme n'affiche aucun message lorsque l'utilisateur perd, celui-ci peut se demander si le programme fonctionne correctement. Il est recommandé d'afficher systématiquement une réponse lorsque l'utilisateur réalise une action. Pour le programme Lucky Dice Roller, vous pouvez utiliser une instruction else pour leur expliquer qu'ils n'ont pas gagné.

  1. Ajoutez une instruction else pour imprimer "You didn't win, try again!".
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    if (rollResult == luckyNumber) {
        println("You win!")
    } else {
        println("You didn't win, try again!")
    }
}
  1. Exécutez le programme. Qu'importe le résultat, vos utilisateurs en seront toujours informés.

À ce stade, les utilisateurs savent s'ils ont gagné ou non, mais pas pourquoi. Donnez toujours des informations aux utilisateurs afin qu'ils comprennent le résultat de leurs actions. Imaginez que votre programme soit une application de demande de prêt. "Vous n'avez pas été approuvé, car votre cote de crédit est médiocre" est beaucoup plus instructif que "Désolé, vous ne pouvez pas obtenir de prêt, réessayez !" Pour Lucky Dice Roller, vous pouvez attribuer un message informatif différent aux utilisateurs s'ils ont perdu. Pour ce faire, utilisez plusieurs instructions else if.

  1. Ajoutez des instructions else if pour imprimer un message différent pour chaque lancer. Si nécessaire, reportez-vous au format utilisé lors de la tâche précédente.
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    if (rollResult == luckyNumber) {
        println("You win!")
    } else if (rollResult == 1) {
        println("So sorry! You rolled a 1. Try again!")
    } else if (rollResult == 2) {
        println("Sadly, you rolled a 2. Try again!")
    } else if (rollResult == 3) {
        println("Unfortunately, you rolled a 3. Try again!")
    } else if (rollResult == 5) {
        println("Don't cry! You rolled a 5. Try again!")
    } else {
        println("Apologies! You rolled a 6. Try again!")
    }
}

Dans le code ci-dessus, réalisez les actions suivantes :

  • Vérifiez si rollResult est bien luckyNumber.
  • Si rollResult est luckyNumber, imprimez le message de réussite.
  • Sinon, vérifiez si rollResult est défini sur 1 et, le cas échéant, imprimez un message invitant l'utilisateur à réessayer.
  • Sinon, vérifiez si rollResult est défini sur 2 et, le cas échéant, imprimez un message alternatif qui invite à réessayer.
  • Sinon, continuez à vérifier jusqu'à obtenir le chiffre 5.
  • Si le nombre n'est pas compris entre 1 et 5, la seule option possible est 6. Vous n'avez donc pas besoin d'un autre test avec else if, et vous pouvez simplement obtenir cette dernière option avec l'instruction else finale.

Avoir plusieurs cas else if est très courant. Kotlin simplifie donc leur écriture.

4. Utiliser une instruction "when"

En programmation, il est très courant de tester de nombreux résultats différents. Ces résultats sont appelés des "cas". Parfois, la liste des résultats possibles peut être très longue. Par exemple, si vous lancez un dé à 12 faces, vous obtenez 11 instructions else if entre la réussite et l'instruction else finale. Pour faciliter l'écriture et la lecture de ce type d'instructions et ainsi éviter les erreurs, Kotlin propose une instruction when.

Vous allez modifier votre programme pour utiliser une instruction when. Une instruction when commence par le mot clé when, suivi de parenthèses (). La valeur à tester se trouve entre les parenthèses. Ensuite, des accolades {} sont nécessaires pour que le code s'exécute dans différentes conditions.

  1. Dans votre programme, dans main(), sélectionnez le code de la première instruction if jusqu'à l'accolade } qui ferme la dernière instruction else et supprimez-le.
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4
}
  1. Dans main(), sous la déclaration de luckyNumber, créez une instruction when. Étant donné que votre when doit être testé par rapport au résultat du lancer de dés, placez rollResult entre les parenthèses (). Ajoutez des accolades {} avec un espacement supplémentaire, comme illustré ci-dessous.
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {

    }
}

Comme précédemment, commencez par vérifier si rollResult est identique à luckyNumber.

  1. À l'intérieur des accolades {} de l'instruction when, ajoutez une instruction qui teste rollResult par rapport à luckyNumber. Si elles sont identiques, imprimez le message de réussite. L'instruction se présente comme suit :
luckyNumber -> println("You win!")

Autrement dit :

  • Vous devez d'abord placer la valeur que vous comparez à rollResult. Il s'agit de la valeur luckyNumber.
  • Pour ce faire, utilisez une flèche (->).
  • Ajoutez ensuite l'action à effectuer en cas de correspondance entre les deux valeurs.

Voici comment lire ceci : "Si rollResult est luckyNumber, imprimez le message "You win!"".

Votre code main() se présente comme suit :

fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {
        luckyNumber -> println("You win!")
    }
}
  1. Utilisez la même méthode pour ajouter des lignes et des messages pour les résultats de lancer possibles de 1 à 6, sauf 4, comme illustré ci-dessous. Votre fonction main() terminée devrait se présenter comme suit.
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {
        luckyNumber -> println("You won!")
        1 -> println("So sorry! You rolled a 1. Try again!")
        2 -> println("Sadly, you rolled a 2. Try again!")
        3 -> println("Unfortunately, you rolled a 3. Try again!")
        5 -> println("Don't cry! You rolled a 5. Try again!")
        6 -> println("Apologies! You rolled a 6. Try again!")
    }
}
  1. Exécutez votre programme. La sortie ne présente aucune différence, mais votre code est beaucoup plus compact et plus facile à lire.

Félicitations ! Vous avez appris deux façons d'imprimer des messages en fonction d'une condition. Il s'agit d'un puissant outil qui vous permet de rédiger des programmes intéressants.

5. Code de solution

fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {
        luckyNumber -> println("You won!")
        1 -> println("So sorry! You rolled a 1. Try again!")
        2 -> println("Sadly, you rolled a 2. Try again!")
        3 -> println("Unfortunately, you rolled a 3. Try again!")
        5 -> println("Don't cry! You rolled a 5. Try again!")
        6 -> println("Apologies! You rolled a 6. Try again!")
   }
}

class Dice(val numSides: Int) {
    fun roll(): Int {
        return (1..numSides).random()
    }
}

6. Résumé

  • Utilisez une instruction if pour définir une condition permettant d'exécuter certaines instructions. Par exemple, si l'utilisateur obtient le chiffre porte-bonheur, imprimez un message de réussite.
  • Le type de données Boolean comporte les valeurs true et false et peut être utilisé pour la prise de décision.
  • Comparez les valeurs à l'aide d'opérateurs tels que "supérieur à" (>), "inférieur à" (<) et "égal à" (==).
  • Utilisez une chaîne d'instructions else if pour définir plusieurs conditions. Par exemple, imprimez un message différent pour chaque résultat de lancer.
  • Utilisez une instruction else à la fin d'une chaîne de conditions pour identifier les cas qui ne sont peut-être pas explicitement couverts. Si vous couvrez les cas pour un dé à 6 faces, une instruction else intercepte les numéros 7 et 8 obtenus à l'aide d'un dé à 8 faces.
  • Utilisez une instruction when, comme une forme compacte permettant d'exécuter du code, basée sur la comparaison d'une valeur.

Forme générale de if-else :

if (condition-is-true) {
    execute-this-code
} else if (condition-is-true) {
    execute-this-code
} else {
    execute-this-code
}

Quand :

when (variable) {
    matches-value -> execute-this-code
    matches-value -> execute-this-code
    ...
}

7. En savoir plus

8. Pour s'entraîner

Action à effectuer :

  1. Modifiez myFirstDice de sorte qu'il comporte huit faces et exécutez votre code. Que se passe-t-il ?

Astuce : Lorsque vous augmentez le nombre de faces, l'instruction when ne couvre plus l'ensemble des cas. Par conséquent, rien ne s'affiche pour les cas non couverts.

  1. Corrigez l'instruction when pour tenir compte des huit faces. Pour ce faire, vous pouvez ajouter des cas supplémentaires. Défi : Au lieu d'ajouter un cas pour chaque chiffre, utilisez une instruction else pour identifier tous les cas qui ne sont pas couverts explicitement.

Astuce : Vous pouvez ajouter d'autres cas pour couvrir davantage de faces. C'est une bonne façon de procéder, si vous souhaitez afficher un message différent pour chaque numéro qui peut être lancé. Vous pouvez également utiliser une instruction else et imprimer le même message pour toutes les faces supérieures aux six faces couvertes actuellement par votre code.

  1. Modifiez myFirstDice pour n'avoir que quatre faces. Que se passe-t-il ?

Astuce : Limiter le nombre de faces du dé à une valeur inférieure à celle prévue par l'instruction when n'a pas d'effets notables, car tous les cas pouvant se produire sont couverts.