Introduction à JavaScript

Licence Informatique, semestre 6

Alexandre NiveauJean-Marc Lecarpentier — Judith Jeyafreeda Andrew

Enseignement des technologies du Web

 

Introduction à JavaScript

Notes de cours

Travail personnel

Objectifs

Ce TP propose des exercices de base pour apprendre à manipuler le langage JavaScript (sans pour l'instant se préoccuper de l'interaction avec le HTML et le navigateur en général).

Exercice 1 — Prise en main de JavaScript et callbacks #

Un corrigé de cet exercice est disponible (archive) : Hello world, étoiles, chanson.

Cet exercice vise à vous faire manipuler une des choses les plus importantes en JavaScript, l'utilisation de fonctions comme callbacks, et rencontrer les problèmes des clôtures. Les débutant·e·s découvriront au passage les fondamentaux du langage (instructions de contrôle, variables et fonctions, tableaux…), mais les autres doivent aussi faire l'exercice pour de vrai (il y a des aspects pas évidents).

Hello world

  1. Créer un fichier HTML avec le contenu suivant :
    <!DOCTYPE html>
    <html>
    <head>
    <title>Hello world</title>
    <script>
    "use strict";
    
    alert("Hello, world!");
    console.log("Im in ur console");
    
    </script>
    </head>
    <body><p>Ouvrir la console pour voir le résultat</p></body>
    </html>
  2. Ouvrir la page HTML avec un navigateur (depuis le web ou en local, ça devrait fonctionner de manière identique) : vous devriez avoir un message pop-up, et si vous ouvrez la console (control-shift-K sous Firefox), vous devriez voir le message correspondant.
  3. Ajouter à la fin du script le code suivant :
    x = 3;
    console.log(x);
    Pourquoi cela ne marche-t-il pas ? Que faut-il faire pour que ça marche ?
  4. Supprimer le contenu du script, et écrire une fonction saluer qui écrit « Hello, world! » dans la console.
  5. Appeler la fonction saluer 100 fois à l'aide d'une boucle : vous devriez constater que la console n'affiche pas le message 100 fois, mais se contente d'incrémenter un compteur (en rouge à droite), pour dire « ce message est apparu tant de fois ».
  6. Faire en sorte que le script attende 3 secondes avant d'appeler la fonction saluer.
  7. Faire en sorte que le script affiche un autre message (de votre choix) au bout de 5 secondes.
  8. Si ce n'est déjà fait, utiliser une fonction anonyme pour faire la question précédente.

Étoiles

  1. Dans un nouveau script (reprendre le fichier HTML précédent — ne pas oublier l'utilisation du mode strict !), écrire une fonction etoiles(n) qui affiche n astérisques dans la console (par exemple ****** pour n=6).
  2. Faire en sorte que le script attende 5 secondes puis affiche 17 astérisques dans la console. Si vous avez du mal, inspirez-vous de ce que vous avez fait dans la partie précédente.

Chanson

  1. Dans un nouveau script, créer un tableau chanson contenant quelques paroles d'une chanson, sous forme de plusieurs chaînes de caractères (une par vers). Ajouter une chaîne pour l'artiste à la fin du tableau.
  2. Faire en sorte que le script affiche le premier vers au bout d'une seconde, le second au bout de deux secondes, etc., mais n'affiche pas l'artiste. Si vous avez des problèmes, vérifiez comment vous avez déclaré la variable qui parcourt le tableau : avec let ou avec var ?

Exercice 2 — Manipulations d’objets JS : jeu de bataille #

Une proposition de correction est disponible (code JS).

Pour vous faire manipuler les objets en JavaScript, cet exercice prend comme prétexte le passionnant jeu de cartes appelé la bataille. Créer un fichier bataille.html avec un script (penser à utiliser le mode strict). On va utiliser la console pour simuler un jeu de bataille.

  1. Créer deux tableaux de chaînes de caractères : un tableau couleurs contenant les quatre couleurs d'un jeu de 32 cartes (pique, cœur, trèfle, carreau), et un tableau valeurs contenant les huit valeurs d'un jeu de 32 cartes (sept, huit, neuf, dix, valet, dame, roi, as).
  2. En guise d'échauffement, utiliser ces deux tableaux pour afficher dans la console chacune des 32 cartes comme suit :
    sept de pique
    huit de pique
    […]
    roi de carreau
    as de carreau
    
  3. On va maintenant faire les choses plus proprement. Créer une fonction creerCarte(v, c) qui renvoie un objet avec une propriété valeur valant v et une propriété couleur valant c. Tester :
    let test = creerCarte("neuf", "trèfle");
    console.log(test.valeur, "de", test.couleur);
    
  4. Pour simplifier l'affichage des cartes, écrire une fonction afficherCarte(carte) qui écrit le nom de la carte dans la console. Exemple :
    let dp = creerCarte("dame", "pique");
    afficherCarte(dp);  // affiche "dame de pique" dans la console
    
  5. Écrire une fonction creerJeuDeCartes() qui renvoie un tableau des 32 cartes sous forme d'objets. On doit pouvoir ensuite exécuter des instructions comme
    let testJeu = creerJeuDeCartes();
    afficherCarte(testJeu[4]);
    • Écrire une fonction combat(carte, autreCarte), qui simule un affrontement entre deux cartes. Elle doit afficher dans la console les deux cartes qui s'affrontent ainsi que la carte gagnante. Exemple de résultat :
      Combat entre:
      dame de carreau
      sept de trèfle
      Carte gagnante:
      dame de carreau
      
      (Indice : pour décider quelle carte est la plus forte, vous pouvez utiliser le tableau valeurs, avec la méthode indexOf().)
    • Tester la fonction sur diverses cartes ; exemple :
      let testJeu = creerJeuDeCartes();
      combat(testJeu[4], testJeu[14]);
      
      Essayer avec plusieurs paires de cartes différentes, pour tester tous les cas !
    • Modifier la fonction combat pour que, en plus d'afficher le déroulement du combat, elle retourne une indication sur ce qui s'est passé : elle doit renvoyer 1 si c'est la première carte qui gagne, 2 si c'est la seconde, et 0 s'il y a égalité.
  6. Écrire une fonction tirerCarte(jeu), qui sélectionne une carte aléatoirement dans le jeu donné en paramètre, puis la renvoie après l'avoir retirée du jeu. (Indice : Math.random() et Math.floor() peuvent servir à choisir un entier aléatoire, et tableau.splice(i, 1) retire la carte en position i dans le tableau tableau).
  7. Écrire une fonction distribuerMain(nb, jeu), qui prend en entrée un entier nb et un tableau de cartes jeu, et qui renvoie une « main » de nb cartes aléatoires du jeu.
  8. On commence à programmer le jeu proprement dit. Pour simplifier l'énoncé, on va donner des noms aux deux joueurs : Toto et Mimi.

    Écrire une fonction jouerTour(mainDeToto, mainDeMimi), qui prend en paramètres deux tableaux de cartes, qui sont les cartes de Toto et celles de Mimi. La fonction va comparer la première carte de la main de Toto avec la première carte de la main de Mimi (indice : regarder shift()). Si la carte de Toto est plus forte, il remporte les deux cartes (elles sont placées à la fin de sa main, la plus forte en premier), et de même si c'est Mimi qui gagne. En cas d'égalité, pour simplifier, on tirera à chaque fois au sort qui de Toto ou Mimi remporte les deux cartes. Dans tous les cas, la fonction doit afficher qui a remporté le pli.

  9. Créer une fonction jouerPartie() qui déroule une partie entière :
    • création d'un jeu de cartes
    • distribution des deux mains
    • exécution de tours de jeu jusqu'à ce que soit Toto soit Mimi n'ait plus de cartes.
    La fonction doit afficher dans la console qui a gagné, et doit renvoyer le nombre de tours qu'a comptés la partie.
  10. Lancer quelques parties et calculer le nombre moyen de tours par partie.

Attention : si les parties ne semblent pas finir, vérifiez que vous avez respecté la contrainte de rangement des cartes gagnées, qui influence énormément le résultat. D'autre part, il peut être une bonne idée d'abandonner une partie si elle a duré plus de 1000 tours (les parties infinies sont rares, mais possibles).

Questions optionnelles

Si vous voulez prolonger un peu l'exercice, vous pouvez faire les questions suivantes, mais assurez-vous d'avoir fini les parties non optionnelles de tous les TP auparavant…

  1. Implémenter la vraie bataille : lors d'une égalité, on ignore la carte suivante de Toto et Mimi, et on regarde celle qui suit ; le ou la gagnant·e remporte toutes les cartes (donc six en tout). S'il y a à nouveau égalité, on applique encore le mécanisme (le ou la gagnant·e remportera donc dix cartes), etc.
  2. Modifier le code pour qu'il n'y ait plus de variables/paramètres mainDeToto et mainDeMimi, mais un tableau mains qui contient les mains de tou·te·s les participant·e·s. Créer une fonction distribuer(n, jeu) qui distribue le jeu à n personnes.
  3. Estimer la longueur moyenne d'une partie en fonction du nombre de participant·e·s.