Code source du jeu de Memory

Voir le résultat   Retour à la page du projet

Afficher/Masquer les commentaires

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"/>
<title>Memory</title>

En CSS, on peut définir la forme du pointeur de la souris avec la propriété cursor.

Dans notre programme, lorsque le pointeur de la souris passe sur un élément img, il prend l'aspect de la main d'indicateur de lien.

<style>
	img{
		cursor:pointer;
	}
</style>
</head>
<body>

L'interface utilisateur est un élément table qui contient 20 images qui correspondent aux différentes cartes du jeu.

<table id="tapis">
<tr>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
</tr>
<tr>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
</tr>
<tr>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
</tr>
<tr>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
	<td><img src="fondcarte.png"/></td>
</tr>
</table>

Le code source du programme en JavaScript débute ici.

<script>

Le jeu comporte 10 motifs différents qui sont numérotés de 1 à 10.

Le tableau est initialisé avec les numéros de motifs qui se suivent.

var motifsCartes=[1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10];

Le codage utilisé pour l'état des cartes est le suivant :

Au départ toutes les cartes sont présentées de dos.

var etatsCartes=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; 

Tableau contenant les numéros des cartes retournées à un moment donné du jeu.

var cartesRetournees=[];

Cette variable contient le nombre de paires de cartes qui ont déjà été trouvées.

var nbPairesTrouvees=0;

Le tableau imgCarte contient les objets des éléments img de l'interface utilisateur.

var imgCartes=document.getElementById("tapis").getElementsByTagName("img");		

On parcourt le tableau des objets des éléments img, chacun d'eux reçoit une fonction déclenchée par l'événement onclick.

La fonction ainsi définie est exécutée à chaque fois que l'utilisateur clique sur l'image son rôle est d'appeller controleJeu avec le numéro de l'image cliquée.

for(var i=0;i<imgCartes.length;i++){
	imgCartes[i].noCarte=i; //Ajout de la propriété noCarte à l'objet img
	imgCartes[i].onclick=function(){
		controleJeu(this.noCarte);
	}                      
}

Appel de la fonction initialiseJeu pour mélanger les cartes.

initialiseJeu();

La fonction majAffichage met à jour l'affichage de la carte dont on passe le numéro en paramètre.

L'affichage rendu dépend de l'état actuel de la carte (donné par le tableau etatsCartes) :

function majAffichage(noCarte){
	switch(etatsCartes[noCarte]){
		case 0:
			imgCartes[noCarte].src="fondcarte.png";
			break;
		case 1:
			imgCartes[noCarte].src="carte"+motifsCartes[noCarte]+".png";
			break;
		case -1:
			imgCartes[noCarte].style.visibility="hidden";
			break;
	}
}

La fonction rejouer affiche un message de félicitations et permet de jouer à nouveau en rechargeant la page dans le navigateur.

function rejouer(){
	alert("Bravo !");
	location.reload();
}

La fonction initialiseJeu mélange les numéros de motif des cartes.

Pour cela un algorithme de mélange est utilisé : [explications de l'algorithme](/programmation-en-javascript/melanger-les-elements-d-un-tableau/6)

function initialiseJeu(){
	for(var position=motifsCartes.length-1; position>=1; position--){
		var hasard=Math.floor(Math.random()*(position+1));
		var sauve=motifsCartes[position];
		motifsCartes[position]=motifsCartes[hasard];
		motifsCartes[hasard]=sauve;
	}
}

C'est la fonction controleJeu qui contient le coeur du programme : elle est appelée chaque fois que l'utilisateur clique sur une carte en passant en paramètre le numéro de la carte cliquée.

function controleJeu(noCarte){

Il est impossible d'avoir plus de deux cartes retournées en même temps, ce test évite que cela arrive, par exemple, si un utilisateur clique à toute vitesse sur plusieurs cartes.

	if(cartesRetournees.length<2){

Si la carte cliquée est de dos (état 0) :

On notera que rien n'est fait pour les états 1 et -1 : cliquer sur une carte déjà retournée ne change rien et cliquer sur une zone de carte enlevée non plus.

		if(etatsCartes[noCarte]==0){
			etatsCartes[noCarte]=1;
			cartesRetournees.push(noCarte);
			majAffichage(noCarte);
		}

Si on se retrouve avec deux cartes retournées, il faut déterminer si elles ont le même motif :

		if(cartesRetournees.length==2){
			var nouveauEtat=0;
			if(motifsCartes[cartesRetournees[0]]==motifsCartes[cartesRetournees[1]]){
				nouveauEtat=-1;
				nbPairesTrouvees++;
			}

			etatsCartes[cartesRetournees[0]]=nouveauEtat;
			etatsCartes[cartesRetournees[1]]=nouveauEtat;

Afin que le joueur ait le temps de voir ce qu'il se passe, on différe la mise à jour de l'affichage des cartes de 750 ms.

Enfin au cas où toutes les paires ont été trouvées, on appelle la fonction rejouer

			setTimeout(function(){
				majAffichage(cartesRetournees[0]);
				majAffichage(cartesRetournees[1]);
				cartesRetournees=[];
				if(nbPairesTrouvees==10){
					rejouer();
				}
			},750);
		}
	}
}
</script>
</body>
</html>