Applications Javascript

Licence Informatique 1e année

Alexandre NiveauJean-Marc Lecarpentier

Enseignement des technologies du Web

 

Travail personnel

Objectifs

Notes de cours

Exercice 1 — Jeu de memory #

Cet exercice fait partie de ceux qui seront évalués. La page doit être accessible et fonctionnelle à l'URL suivante :

https://dev-NUMETU.users.info.unicaen.fr/TW2/TP09/ex1/memory.html
(en remplaçant NUMETU par le numéro correspondant). Pensez à vérifier la validité W3C de votre page !

D'autre part, l'élément head doit contenir le code suivant :

<meta name="author" content="NUMETUS" />
en remplaçant NUMETUS par les numéros des étudiant·e·s qui ont travaillé sur cette page, séparés par des virgules. (Il faut laisser name="author" tel quel, par contre !) Par exemple, si 21012343 et 20922462 ont travaillé ensemble, ils mettent <meta name="author" content="21012343,20922462" /> dans le head de leur page. Ça permettra à notre script de savoir qui a travaillé avec qui.

Il est conseillé de vérifier que l'exercice a été correctement rendu en utilisant l'application evalweb.

Vous avez jusqu'au 15 avril pour terminer l'exercice.

Cet exercice compte pour les TPs 9 (parties 1à 5) et 10 (parties 6 à 8) et doit être terminé avant le 15 avril

Utiliser cette archive pour démarrer le TP. Sont fournis un fichier HTML, CSS, un fichier JS à compléter et 32 images carrées pour les cartes du jeu.

On veut créer un jeu de Memory en Javascript. Rappel des règles sur Wikipedia. La version que nous allons réaliser pour commencer se joue seul.

Partie 1 : choix des cartes

On souhaitera pouvoir choisir la disposition des cartes en N rangées et M colonnes, il faut donc N*M cartes. Chaque carte étant représentée par une image i.jpg, il y a 32 types de cartes possibles.

On veut choisir les N*M images des cartes au hasard parmi les 32 possibles, et on acceptera qu'une même paire soit présente plusieurs fois. Les images étant nommées sous la forme i.jpg, il suffit de choisir des entiers entre 1 et 32.

Créer un tableau de N*M d'entiers compris entre 1 et 32 mais attention il faut N*M/2 paires puis mélanger cette liste sur place à l'aide de l'algorithme de Fisher-Yates (rappel : en Javascript les tableaux sont passés par référence, de même qu'en Python).

Partie 2 : placement des cartes

La page HTML dispose d'une division d'identifiant jeu qui contiendra les cartes. Cette division occupe tout l'espace. On souhaite pouvoir choisir la disposition en N rangées et M colonnes et faire que l'affichage du jeu se fait sans apparition de scrollbars, c'est à dire que la taille des cartes doit être adaptée en fonction de la taille du jeu et du nombre de colonnes et de rangées.

Les cartes sont modélisées par des éléments div qui contiennent une image. Lorsque la carte est face invisible, l'image utilisée est js-logo.jpg.

Pour chaque division représentant une carte, on utilisera un attribut data-numero qui stocke le numéro de son image correspondant.

Écrire le code qui crée les N*M cartes avec faces invisibles.

Indication : pour calculer la largeur du côté de chaque carte, il faut connaître la taille de la division jeu. Pour cela, on pourra utiliser window.getComputedStyle(), calculer ensuite la taille à utiliser et mettre les propriétés grid-template-columns et grid-template-rows aux bonnes valeurs.

On doit alors obtenir le jeu avec les cartes retournées :

Cartes retournées

Partie 3 : jouer

Compléter le code pour que chaque divison représentant une carte capte le clic

Compléter le code pour que, lorsque 2 cartes sont visibles, leur images soient comparées. On mettra un timer pour que les cartes restent visibles 1 ou 1,5 secondes.

Si les images sont identiques, on doit alors enlever les cartes (càd que la division ne contient plus d'image et ne capte plus le clic).

Si les images sont différentes, il faut les retourner à nouveau.

Attention il faut bloquer le jeu tant que les cartes n'ont pas été enlevées ou retournées.

Partie 4 : affichages

Afficher dans la section de haut de page le nombre de coups joués et le nombre de paires trouvées.

Afficher quand la partie est terminée.

On considère qu'un coup manqué vaut -1 et un coup réussi +3. Afficher le compteur de score de la partie.

La figure ci-dessous montre un exemple d'interface possible.

Partie 5 : paramètres du jeu

Ajouter deux champs input pour laisser l'utilisateur choisir le nombre de rangées N et colonnes M pour l'affichage du jeu (vérifier que N*M est pair). On pourra mettre des valeurs par défaut pour la taille du jeu (6 et 4 par exemple).

Ajouter un bouton pour démarrer une nouvelle partie.

La figure ci-dessous montre un exemple d'interface possible.

Scores et nombre de coups
Exemple d'interface avec affichage du nombre de coups, du score et choix du nombre de colonnes et rangées pour le jeu

Partie 6 : mémorisation des meilleurs scores

On souhaite pouvoir garder en mémoire les meilleurs scores réalisés, même lorsque la page web est rechargée ou lorsque le navigateur a été fermé. Pour cela on va utiliser le localStorage qui permet au navigateur d'enregistrer des informations simples sous la forme clé-valeur (un peu comme dans un objet Javascript, mais à un seul niveau).

Commencer par regarder ce qu'est localStorage et comment l'utiliser.

Note on peut voir ce que le navigateur stocke dans l'onglet stockage des outils de développement web de Firefox (des outils similaires sont présents dans Chrome et Safari).

Ajouter une colonne meilleurs scores au-dessus du jeu.

Compléter le code pour garder en mémoire le meilleur score et l'afficher. Au chargement de la page, l'application doit d'abord vérifier si ces données sont stockées dans localStorage et si oui les afficher. À chaque fin de partie il faudra regarder si le meilleur score est battu.

Pour que la notion de meilleur score ait un sens, les parties doivent avoir le même nombre de cartes. On choisit donc de ne conserver que les meilleurs scores pour des parties à 6x4 cartes.

Partie 7 : enregistrer une partie

Ajouter un bouton pour enregistrer la partie (par exemple sous le titre memory) et lui faire capter le clic.

Écrire le code qui permet d'enregistrer l'état de la partie dans le localStorage.

Indication : il suffit d'enregistrer le nombre de coups, le score, le nombre de paires trouvées, le nombre de colonnes et rangées et la liste des cartes, par exemple les numéros des cartes pour celles non encore trouvées et la valeur -1 pour les cartes déjà trouvées et retirées du jeu. On pourra modéliser cela avec un objet Javascript de la forme :

{
"coups": 7,
"score": 13,
"paires": 6,
"pairesRestantes": 8,
"nbColonnes": 7,
"nbRangees": 4,
"jeu": [2, 7, -1, 6, 2, ...]
}

On pourra ensuite utiliser JSON.stringify qui permet de sérialiser un objet Javascript en une chaîne de caractères que l'on peut ensuite stocker dans le localStorage. On supposera que si une partie est déjà en mémoire alors le programme l'écrase.

Utiliser les outils de développenet (onglet Stockage) poiur vérifier ce qui a été enregistré dans le navigateur.

Partie 8 : reprendre une partie

Écrire le code qui permet de reprendre la partie engistrée. On considère que lorsque l'on (re)charge la page, l'application regarde si une partie est enregistrée. Si oui elle reprend celle-ci et sinon elle démarre normalement.

Indication pour extraire les données du localStorage stockées en JSON, utiliser JSON.parse qui désérialise des données JSON.

On peut remarquer qu'il suffit d'adapter le code déjà écrit pour afficher le jeu à partie de la liste enregistrée en localStorage au lieu de la liste générée et mélangée (début du TP précédent).