Niveau : 1ère générale, enseignement de spécialité NSI
Cliquez sur l'image ci-dessous pour jouer
Début
On choisira de séparer le code javascript du fichier html pour plus de lisibilité
La variable grille contient les chiffres de chaque case de la grille c'est un tableau à 2 dimensions dont le format est format :
var grille = [[val1,val2,..],[val5,..],[...],[...]];
Dans la zone texte, initialisez la variable grille qui se trouvera dans le code javascript, en mettant un 0 dans chaque case
Pour vérifier si le code ne comporte pas d'erreurs, appuyez sur F12 du clavier et afficher la console
Modifier la variable grille en y stockant des 2, 4, 8 ou 16 ... puis testez une nouvelle fois pour vérifier le fonctionnement
Copier-coller le code javascript suivant dans la fenêtre ci-dessous pour activer la prise et traiter les évènement du clavier :
window.addEventListener("keydown", function(event) {detection_touches(event);}, true); function detection_touches(event){ // Traite les touches de direction enfoncées // Appelle les fonctions du jeu et contrôle la fin de la partie var x = event.key; //event.preventDefault() // à n'enlever qu'à la fin du TP !! var direction={'ArrowLeft':0,'ArrowRight':2,'ArrowDown':1,'ArrowUp':3}; console.log(direction[x]); }
Enregistrez le code javascript, puis appuyer sur F12 et sélectionner console. Cliquer sur la page html pour donner le "focus", puis appuyer sur les touches directionnelles pour vérifier le fonctionnement
Expliquer pourquoi la console affiche des chiffres. Pour vous aider vous pouvez insérer une commande console.log(x)
Il s'agit de la fonction centrale du jeu
Etat avant
2 | 2 | 0 | 4 |
4 | 2 | 0 | 2 |
4 | 0 | 0 | 8 |
0 | 4 | 4 | 0 |
Etat après
4 | 4 | 0 | 0 |
4 | 4 | 0 | 0 |
4 | 8 | 0 | 0 |
8 | 0 | 0 | 0 |
La méthode est de traiter les données ligne par ligne : prenons la 1ère ligne [2,2,0,4]
fonction decale_zeros(ligne) paramètre d'entrée : une ligne de la grille paramètre de sortie: la variable ligne début pour n variant de 2 à 0 faire si ligne[n]==0 alors enlever cet élément de la ligne ajouter 0 à la fin de la ligne fin si fin pour retourne ligne fin
Exemple
var n=2; var tab=[1,2,3,4]; if (tab[n]==3){ ligne.splice(n,1); console.log(tab); ligne.push(3); console.log(tab); }
1,2,4 1,2,4,3
Au début de la page mettre la variable var grille=[[2,2,0,4],[4,2,0,2],[4,0,0,8],[0,4,4,0]]; un peu plus bas cliquer sur "enregistrer les codes" puis tester la fonction decale_zeros
Algoritme de la fonction addition(ligne)
fonction addition(ligne) paramètre d'entrée : une ligne de la grille avec les zéros décalés à droite paramètre de sortie: la variable ligne début pour n variant de 0 à 2 faire si ligne[n]==ligne[n+1] alors ligne[n] ← ligne[n]+ligne[n+1] ligne[n+1] ← 0 fin si fin pour retourne ligne fin
Remarque : Si on clique plusieurs fois sur le bouton Tester, on remarque que le la ligne du tableau grille[0] change et est remplacé par le contenu de la variable ligne.
La variable ligne utilisée dans la fonction pointe directement vers les adresses mémoire de grille[0].
On peut le mettre en évidence en ajoutant deux lignes console.log(String(grille[0])); juste avant les lignes for et return et afficher la console F12
On pourrait presque se passer du return, mais laissez-le à cause des tests qui les utilisent
Pour éviter de faire une nouvelle fonction on peut imaginer de faire une rotation de la matrice grille de -90° puis appliquer l'algorithme précédent permettant de décaler les tuiles vers la gauche
Exemple
Etat initial :
2 | 2 | 0 | 4 |
4 | 2 | 0 | 2 |
4 | 0 | 0 | 8 |
0 | 4 | 4 | 0 |
Rotation de -90° :
0 | 4 | 4 | 2 |
4 | 0 | 2 | 2 |
4 | 0 | 0 | 0 |
0 | 8 | 2 | 4 |
Décalage à gauche
8 | 2 | 0 | 0 |
4 | 4 | 0 | 0 |
4 | 0 | 0 | 0 |
8 | 2 | 4 | 0 |
Rotation de 90° (ou -270°)
0 | 0 | 0 | 0 |
0 | 0 | 0 | 4 |
2 | 4 | 0 | 2 |
8 | 4 | 4 | 8 |
Afin d'utiliser qu'une seule fonction de rotation de -90°, on procède de la manière suivante :
Ecrire en javascript la fonction constituée de 2 boucles "pour" permettant de faire pivoter la matrice de -90°
Algorithme :
fonction rotation_matrice
matrice ← [[],[],[],[]] pour x variant de 0 à 3 pour y variant de 0 à 3 matrice[?][?] ← grille[x][y] fin pour fin pour retourne matrice
fin de la fonction
Traduire l'algorithme en JavaScript et remplacer les ? par les variables x ou y ou par une soustraction
Après avoir détecté la touche directionnelle du clavier, appelle la fonction deplace_tuiles en passant le chiffre correspondant à la touche enfoncée en paramètre.
AlgorithmeFonction deplace_tuiles(direction) paramètre d'entrée : le chiffre représentant la direction (0, 1, 2 ou 3) début si direction >0 alors pour i variant de 0 à direction grille ← rotation_matrice fin pour fin si pour i variant de 0 à 3 ligne ← decale_zeros de grille[i] grille[i] ← additionner grille[i] ligne ← decale_zeros de grille[i] fin pour si direction >0 alors pour i variant de 0 à (4-direction) grille ← rotation_matrice fin pour fin si fin de la fonction
Fonction maximum() début max ←2 parcourir toutes les cases de la grille avec 2 boucle pour si max < valeur de la tuile sélectionnée alors max = valeur de la tuile retourne max fin de la fonction
function place_tuile_aleatoire(){ //Permet de placer une nouvelle tuile de manière aléatoire var occupe= true; var choix=[2,2,2,2,4]; while (occupe){ x=(Math.random()*3).toFixed(0); y=(Math.random()*3).toFixed(0); if (grille[x][y]==0){ grille[x][y]=choix[(Math.random()*4).toFixed(0)]; occupe=false } } }
Justifier l'emploi des variables choix=[2,2,2,2,4] et occupe
function verifie_fin(){ //boucle 1 for (var ligne=0;ligne<4;ligne++){ for (var col=0;col<3;col++){ if (grille[ligne][col]==grille[ligne][col+1]){ return (false); } } } //boucle 2 for (var col=0;col<4;col++){ for (var ligne=0;ligne<3;ligne++){ if (grille[ligne][col]==grille[ligne+1][col]){ return (false); } } } //boucle 3 for (var i=0;i<4;i++){ var rangee=grille[i]; for (var j=0;j<4;j++){ if (rangee[j]==0){ return (false); } } } return (true) }
Le script ci-dessus permet de vérifier horizontalement et verticalement si deux tuiles sont égales et vérifier s'il reste des cases contenant des zéros.
Indiquer quelle boucle réalise les fonctions citées ci-dessus
Ecrire la fonction que permet de commencer le jeu
algorithme:
fonction commence_jeu() Placer des zéross dans la variable grille placer 2 tuiles aléatoires dessiner la grille fin Appeler la fonction commence_jeuVoir le résultat en cliquant ici
Il ne reste plus qu'à appeler les fonctions dans la fonction de détection des touches, vérifier la fin de la partie et un déplacement impossible. Remplacer la ligne console.log(direction[x]); le code suivant:
grille_avant=String(grille); deplace_tuiles(direction[x]); if (verifie_fin()==true){ if (confirm('Tu as perdu, essaye encore')){ commence_jeu(); } } if (grille_avant!=String(grille)){ place_tuile_aleatoire() } dessine_grille() if (maximum()==2048){ if (confirm('Tu as gagné, recommence une nouvelle partie ?')){ commence_jeu(); } }
Répondre aux questions suivantes :
Remplacer la ligne de code console.log(direction[x]) ici
Les touches directionnelles haut et bas du clavier font défiler la page, ce qui n'est pas agréable pour jouer. C'est le moment d'enlever les 2 "/" du début de la ligne //event.preventDefault() // à n'enlever qu'à la fin du TP !! de la fonction detection_touches
Fond : Texte : Tables :
Contenu
sous licence CC BY-NC-SA 3.0
Pascal Hassenforder 18/05/2020