Les dev ont du talent #5 – les mots clés pour les variables : var, let et const

On révise les déclarations de variables et on réorganise le code pour notamment utiliser des objets.

→ Challenge Correction: Avengers

Bienvenue dans ce nouveau corrigé remonté par une dev ! On innove un peu et on propose quelques pistes d’optimisation vis à vis du code fourni.

Avant le corrigé, je te propose un rappel des différentes déclarations de variables possibles en javascript.

Sommaire

La structure var en javascript

Historiquement, Javascript permettait, grâce à var de créer une variable accessible de façon globale. C’est à dire accessible, dans le programme principal, dans une fonction, etc. La valeur pouvait être modifiée tout au long du programme.

Cette structure étant trop permissive, de nouvelles structure sont apparues avec ES6 : let et const.

Les structures let et const en javascript

Il est désormais recommandé d’utiliser let et const pour un code mieux structuré.

let permet de déclarer une variable accessible dans un bloc donné : fonction, boucle, etc. La valeur de la variable pourra être modifiée tout au long du programme.

const, comme let, a une portée dans un bloc donné mais sa valeur ne pourra pas être modifiée, elle sera constante. Attention, si const est utilisé pour stocker l’instance d’une classe, les propriétés de cette classe pourront tout de même être modifiées.

En général, pour avoir un code propre, il est recommandé d’utiliser const par défaut, et let lorsque tu sais qu’une variable pourra être réaffectée. L’utilisation de var est par contre déconseillée dans le code moderne.

Le corrigé du challenge

Merci beaucoup à Céline de nous avoir fourni ce corrigé !

(pour comprendre à quoi fait référence game.gameData, eu peux te référer à la documentation javascript de résolution des challenges)

// sert à savoir quel est le super héros suivant
const dico = {
    "ironman" : "spiderman",
    "spiderman" : "captainamerica", 
    "captainamerica" : "thor", 
    "thor" : "ironman"
}

function resolve() {

    // Copies des constantes pour pouvoir les modifier
    let letIronman = game.gameData.ironman;
    let letSpiderman = game.gameData.spiderman;
    let letCaptainamerica = game.gameData.captainamerica;
    let letThor = game.gameData.thor;

    // initialisé à 1 car l'incrémentation du compteur de tours se fait à la fin de la boucle
    let result = 1;

    let next = "ironman";

    // on calcule la puissance de départ des Avengers
    let puissanceAvengers = (letIronman * 3 + 10) + (letSpiderman * 4 + 5) + (letCaptainamerica * 3 + 7) + (letThor * 4 + 20);

    while (puissanceAvengers <= game.gameData.thanos) {

        switch (next) {

            case "ironman" : letIronman += 1;
            break;

            case "spiderman" : letSpiderman += 1;
            break;

            case "captainamerica" : letCaptainamerica += 1;
            break;

            case "thor" : letThor += 1;
            break;
        }

        // on recalcule la puissance des Avengers maintenant que l'un d'entre eux a augmenté sa puissance
        puissanceAvengers = (letIronman * 3 + 10) + (letSpiderman * 4 + 5) + (letCaptainamerica * 3 + 7) + (letThor * 4 + 20);

        // donne le prochain Avenger qui va augmenter sa puissance
        next = dico[next];

        result+=1;
    }

    return result;
}

// Pour repondre au challenge
game.output({data: resolve()});

Ce code résout le challenge ! Bravo !

Quelles améliorations possibles de ce code javascript ?

En observant ce code, on peut voir quelques éléments qui peuvent être optimisés :

Utiliser des objets pour stocker les données plutôt que des variables individuelles

const superHeros = {
  ironman: { force: game.gameData.ironman, multiplicateur: 3, base: 10 },
  spiderman: { force: game.gameData.spiderman, multiplicateur: 4, base: 5 },
  captainamerica: { force: game.gameData.captainameria, multiplicateur: 3, base: 7 },
  thor: { force: game.gameData.thor, multiplicateur: 4, base: 20 },
};

Un peu d’explications :

  • On définit un objet javascript « superHeros » qui contient 4 propriétés.
  • Chaque propriété est elle même un objet javascript avec 3 propriétés :
    • force
    • multiplicateur
    • base
  • La force change à chaque execution du code car les valeurs proviennent du jeu de données, contenu dans game.gameData
  • Le multiplicateur et la base sont fixes car issus de l’énoncé

Créer des objets en javascript est une bonne façon d’organiser des données.

Le chainage avec le point « . » permettra d’atteindre n’importe quelle valeur. Par exemple pour atteindre « multiplicateur » :

superHeros.spiderman.multiplicateur

Créer des fonctions javascript

Pour calculer la puissance d’un avenger :

function calculerPuissance(force, multiplicateur, base) {
  return force * multiplicateur + base;
}

Pour calculer la puissance de tous les avengers :

function calculerPuissanceAvengers(superHeros) {
  let puissance = 0;

  for (let nom in superHeros) {
    const heros = superHeros[nom];
    puissance += calculerPuissance(heros.force, heros.multiplicateur, heros.base);
  }

  return puissance;
}

Un peu d’explications :

  • Le paramètre superHeros est un objet (cf. section + haut dédiée)
  • On utilise let pour la variable puissance car sa valeur va évoluer au cours de la fonction
  • On utilise let pour la variable nom car elle change à chaque itération de la boucle for
  • A l’intérieur de la boucle on utilise const car pour une itération, sa valeur ne change pas. A chaque nouvelle itération, la variable est réassignée.

Gestion d’index pour passer à l’avenger suivant

Voici le programme principal, et les différents index qui permettent de passer d’un Avenger à l’autre :

const superHeros = {
  ironman: { force: game.gameData.ironman, multiplicateur: 3, base: 10 },
  spiderman: { force: game.gameData.spiderman, multiplicateur: 4, base: 5 },
  captainamerica: { force: game.gameData.captainamerica, multiplicateur: 3, base: 7 },
  thor: { force: game.gameData.thor, multiplicateur: 4, base: 20 },
};

function calculerPuissance(force, multiplicateur, base) {
  return force * multiplicateur + base;
}

function calculerPuissanceAvengers(superHeros) {
  let puissance = 0;

  for (let nom in superHeros) {
    const heros = superHeros[nom];
    puissance += calculerPuissance(heros.force, heros.multiplicateur, heros.base);
  }

  return puissance;
}

const ordreAugmentation = ["ironman", "spiderman", "captainamerica", "thor"];

function resolve() {
  let result = 1;
  // Index pour parcourir le tablea ordreAugmentation
  let indexAugmentation = 0;

  while (calculerPuissanceAvengers(superHeros) <= game.gameData.thanos) {
    const nomHeros = ordreAugmentation[indexAugmentation];
    superHeros[nomHeros].force += 1;

    // Incrémentation de l'index
    // Le modulo permet de ne jamais dépasser le nombre d'éléments
    indexAugmentation = (indexAugmentation + 1) % ordreAugmentation.length; 
    result += 1;
  }

  return result;
}

// Pour répondre au challenge
game.output({data: resolve()});

Un peu d’explications :

Ici au lieu d’avoir pour chaque avenger son suivant dans un tableau, on a les avengers dans un tableau et on se déplace de 1 en 1 dans l’index. Le modulo ramène à zéro si nécessaire.

Merci 🙂

Encore merci à Céline de nous avoir remonté ce corrigé !

N’hésite pas à nous soumettre le tien en passant par la page de contact 😉

Keep learning

Other content to discover