IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Sortie de boucle prématurée


Sujet :

JavaScript

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Sortie de boucle prématurée
    Bonjour,

    J'essaie de programmer un démineur en JS à base d'une table html de 10x10, fonctionnant sur le modèle du démineur windows, à savoir lorsqu'une case est cliquée par un joueur si la case ne contient pas de mine et si la détection du nombre de mines à sa périphérie est =0, les 8 cases adjacentes sont découvertes, c'est l'objet de la fonction uncoverAdjacent().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    function uncoverAdjacent(tab){
    	var tableDomTd = document.getElementsByTagName("td");
    	while(tab.length >0){
    		var el=tab.pop();
    		var X=getX(el);
    		var Y=getY(el);		
    		//boucle sur tous les TD de la grille et on decouvre les cases
    		//adjacentes de la case dont la valeur nombre de mines est à "0" 			
    		for(var i=0;i<=tableDomTd.length;i++){
    			var Xtd=getX(tableDomTd[i]);
    			var Ytd=getY(tableDomTd[i]);
    			var distance=Math.pow((Y-Ytd),2)+Math.pow((X-Xtd),2);
    			if (distance<=2){
    				var tdAdjacent=uncoverCase(tableDomTd[i]);
    				if(getNbMine(Xtd,Ytd)==0)tab.push(tdAdjacent);
    				alert(tab.length);
    			}
    		}
    	}
    }
    cette fonction reçoit en parametre un tableau : "tab" qui contient un élément de type <td>. lorsque le test de la ligne 14 s'effectue "tab" est bien incrémenté et le message alert de la ligne 17 affiche le bon résultat.

    Or quelle que soit la valeur de "tab.length", la boucle "while" ne fonctionne pas.
    J'aimerais comprendre pourquoi. D'ailleurs quelle que soit l'action j'essaie de réaliser après la sortie de la boucle "for" à la ligne 19, celle-ci est ignorée.
    Ainsi un simple alert("hello") n'est pas interprété, alors que le script continue de s'exécuter...
    Une interruption que je juge un peu bizarre, pas très subtil observerez-vous,
    Pour info voici le code des fonctions appelées :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    function uncoverCase(el){
    	if (el.className!="uncovered"){	
    		var X=getX(el);
    		var Y=getY(el);
    		var nbMines=getNbMine(X,Y);
    		//var classeEl=el.className;
    		nouveauTd=document.createElement("td");
    		nouveauTd.id=el.id;
    		nouveauTd.className="uncovered";
    		nouveauTd.style.backgroundColor="cyan";
    		nouveauTd.innerHTML=nbMines;
    		el.parentNode.replaceChild(nouveauTd,el);
    		//alert(nouveauTd.id);
    		return nouveauTd;
    	}
    	//return false;
    	return el;
    		//el.style.backgroundColor="cyan";
    		//el.innerHTML=nbMines;
    }
     
    //extrait l'abscisse à partir de l'id
    function getX(el){
    	var idCase = el.id;
    	var numCase = parseFloat(idCase.substring(4));
    	var X;
    	if(numCase<10){X=numCase; return X;}
    	if(numCase%10==0){X=10; return X;}
    	X=numCase%10;
    	return X;
    }
     
    //extrait l'ordonnée à partir de l'id
    function getY(el){
    	var idCase = el.id;
    	var numCase = parseFloat(idCase.substring(4));
    	var Y;
    	if(numCase<10){Y=1;return Y};
    	if(numCase%10==0){Y=Math.floor(numCase/10); return Y}
    	Y=Math.floor(numCase/10)+1;
    	return Y;
    }
     
    //retourne le nombre de mines autour de la case
    function getNbMine(col,lin){
    	var compteurMine=0;
    	if (isMine(col-1,lin+1))compteurMine++;
    	if (isMine(col,lin+1))compteurMine++;
    	if (isMine(col+1,lin+1))compteurMine++;
    	if (isMine(col-1,lin))compteurMine++;
    	if (isMine(col+1,lin))compteurMine++;
    	if (isMine(col-1,lin-1))compteurMine++;
    	if (isMine(col,lin-1))compteurMine++;
    	if (isMine(col+1,lin-1))compteurMine++;
    	return compteurMine;
    }
     
    //retourne true si mine sur la case
    function isMine(col,lin){
    	for (var j=0;j<nbMine;j++){
    		if ((col==xMines[j])&&(lin==yMines[j])){
    	//			alert(col+" "+lin);
    			return true;
    		}
    	}
    	return false;
    }
    Voila ce que j'ai essayé jusqu'à présent ne fonctionne pas car une notion m'échappe. J'espère que vous comprendrez d'où cette interruption provient.
    Merci.

  2. #2
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut
    Je ne sais pas si ça répondra à ton problème car je l'ai survolé à l'arrache, mais quand j'ai codé un démineur sur ma calculatrice Casio en 1998. J'avais fait un algo tout con.
    La case du jeu était un tableau de X*Y comme toi, et les cases ou il y avait des bombes étaient remplies d'un 1, et les cases vides était remplies d'un 0.

    Et lorsque je cliquait sur une case, si c'était un 1, boum!
    Si c'était un 0, alors je lançait simplement 2 boucles imbriques

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // xp est la position du la case cliquée sur les colonnes
    // yp est la position de la case cliquée sur les lignes
     
    var bombesAutour = 0;
    for (var i=xp-1; i++; i<=xp+1) {
       for (var j=yp-1; j++; j<=yp+1) {
           bombesAutour+=case[i][j];
       }
    }
    Voila la méthode toute conne pour connaitre le nombre de bombe autour de la case cliquée.

    Je pense que ça pourrait un peu t'aider à simplifier ton calcul du nombre de bombe autour, mais malheureusement ça ne t'aidera pas à régler ton problème principal.

  3. #3
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Citation Envoyé par remidurand Voir le message
    cette fonction reçoit en parametre un tableau : "tab" qui contient un élément de type <td>
    Je pense que tu as dû te mélanger les pinceaux entre tableau HTML (<table>) et tableau JavaScript ([]).

    Ici, tab est un élément HTML, il n'a donc pas de propriété qui s'appelle length. JavaScript est assez vicieux sur le coup, car il considère qu'il n'y a pas d'erreur… En effet, tab.length renvoie undefined, et la comparaison de undefined avec n'importe quel nombre renvoie toujours false. Donc on n'entre jamais dans le while, mais JavaScript considère que c'est parfaitement normal

    En revanche, en tant que tableau, il a une propriété rows qui pointe vers une collection d'éléments <tr>, et cette collection a une propriété length qui correspond au nombre de lignes du tableau.
    Tu as également moyen de connaître le nombre de cellules (<td> ou <th>) dans la ligne n :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab.rows[n].cells.length
    Pour résumer : explorer un <table> en JavaScript se fait toujours comme ceci : on accède d'abord à la ligne, puis à la cellule.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  4. #4
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Arnogues ton algo est correct mais je n'utilise pas de tableau à 2 dimensions donc pour ce cas précis je ne pense pas que cela puisse correspondre à mon problème. Merci de ta réponse.

    Watilin tab est bien un array() javascript qui contient des éléments html et plus précisément des éléments <td>.

    Autre point tab.length renvoie la bonne longueur, celle de l'array javascript au moyen de la méthode alert() si je la place juste avant la fermeture de la boucle for comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for(var i=0;i<=tableDomTd.length;i++){
    	var Xtd=getX(tableDomTd[i]);
    	var Ytd=getY(tableDomTd[i]);
    	var distance=Math.pow((Y-Ytd),2)+Math.pow((X-Xtd),2);
    	if (distance<=2){
    		var tdAdjacent=uncoverCase(tableDomTd[i]);
    		if(getNbMine(Xtd,Ytd)==0)tab.push(tdAdjacent);
    			alert(tab.length);
    	}
    }
    * mais pas si je la place juste après alors que je suis toujours dans ma boucle while.

    merci de ta réponse, pas de solution pour le moment, j'y retourne.

  5. #5
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Je vois que tu utilises alert pour mettre au point ton script. Tu devrais utiliser les outils de développement offerts par la plupart des navigateurs actuels. Par exemple sous Firefox depuis quelques versions, tu as un débogueur JavaScript en faisant Ctrl+Maj+S
    Autrement, j'ai regardé ton code, et là comme ça, je vois pas où ça coince.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  6. #6
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 4
    Points
    4
    Par défaut enfin trouvé :)
    l'erreur venait de cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(var i=0;i<=tableDomTd.length;i++)
    fallait juste mettre "<" au lieu de "<=". Effectivement l'indice de la boucle commençant à 0, ça faisait une boucle de plus sur un element non défini du tableau.
    sinon j'ai utilisé la console de firebug et j'ai vu ça en 30sec.

    ouf !

Discussions similaires

  1. sortie de boucle
    Par fred33 dans le forum Langage
    Réponses: 5
    Dernier message: 27/05/2008, 07h51
  2. Données d'Entrée - Sortie - Test - Boucle
    Par edmond dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 20/12/2007, 08h58
  3. probleme de resultat en sortie de boucle for
    Par afssaLERH dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 31/10/2007, 16h16
  4. sortie de boucle
    Par peldaine dans le forum VBScript
    Réponses: 4
    Dernier message: 18/07/2007, 13h59
  5. Sortie de boucle par validation O/N
    Par kOrt3x dans le forum Ada
    Réponses: 7
    Dernier message: 08/12/2006, 03h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo