Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Problème] Codage Démineur débutant (avec p5.js).

Besoin d'aide pour une récursivité lors du codage d'un Démineur

Sujet résolu
Anonyme
    13 avril 2018 à 21:44:54

    Bonjour, Bonsoir,

    J'ai pour projet en ISN cette année de réaliser un démineur afin de le présenter à un jury. J'ai commence juste l'apprentissage en JavaScript alors forcément je suis arrivé à un stade où je ne sais plus comment avancer. Mon prof m'a conseillé de faire le codage en "p5" et j'ai donc suivi son choix. J'ai quasiment tout fini mais je suis rendu au moment où lorsque le joueur clique sur une case dite "vide", celle ci ce découvre et toutes les cases voisines qui sont vides doivent à leur tour se découvrir. Cependant, j'ai beau avoir chercher sur des forums les solutions réalisées pour ce problème mais je n'ai toujours pas réussi..

    Voici mon sketch.js:

    var terrainVisible = new Array(576);
    var terrainCache = new Array(576);
    var terrainJoueur = new Array(576);
    var taux = 0.15;
    var listImage;
    var gameOver = 0;
    console.log(0);
    
    function preload() {
    	console.log(1);
        b = loadImage('Images/bomb.png');
        bp = loadImage('Images/bombperte.png');
        bc = loadImage('Images/bombcroix.png');
        p = loadImage('Images/inter.png');
        pvide = loadImage('Images/intervide.png');
        c = loadImage('Images/cache.png');
        v = loadImage('Images/vide.png');
        d = loadImage('Images/drapeau.png');
        n1 = loadImage('Images/n1.png');
        n2 = loadImage('Images/n2.png');
        n3 = loadImage('Images/n3.png');
        n4 = loadImage('Images/n4.png');
        n5 = loadImage('Images/n5.png');
        n6 = loadImage('Images/n6.png');
        n7 = loadImage('Images/n7.png');
        n8 = loadImage('Images/n8.png');
        console.log(2);
        listImage = [v, n1, n2, n3, n4, n5, n6, n7, n8, d, c, b, bp, bc, p, pvide];
        
        for (var i = 0; i < 576; i++) {
          terrainVisible[i]=0;          //Que des 0 dans terrainVisible à cette étape
          terrainCache[i]=0;            //Que des 0 dans terrainCache à cette étape
          terrainJoueur[i]=10;          //Que des 10 dans terrainJoueur à cette étape
        } 
        for (var x = 1; x < 23; x++) {		 
    		for (var y = 1; y < 23; y++) {
    		  terrainVisible[x+24*y]=11*(random()<taux);
            }
        } 
        console.log(terrainVisible)
        
        
        for (var x = 1; x < 23; x++) {		 
    		for (var y = 1; y < 23; y++) {
    			if (terrainVisible[x+24*y]==11) {
    				terrainCache[x+24*y]=11
    			}
    			else {
    		        terrainCache[x+24*y]=(terrainVisible[x-1+24*y]+terrainVisible[x+1+24*y]+terrainVisible[x+24*(y+1)]+terrainVisible[x+24*(y-1)]+terrainVisible[x+1+24*(y+1)]+terrainVisible[x-1+24*(y-1)]+terrainVisible[x-1+24*(y+1)]+terrainVisible[x+1+24*(y-1)])/11;
    		    }
            }        
        }
        console.log(3);
    }
    
    function setup() {
      createCanvas(800, 800);
    }
    
    function draw() {
        background(189,195,199);
        affiche();
        console.log(floor(mouseX/height*24),floor(mouseY/height*24));
    
    }
    
    function affiche() {
        for (var x = 1; x < 23; x++) {		 
    		for (var y = 1; y < 23; y++) {
    		  imagetmp=listImage[terrainJoueur[x+24*y]];
    		  image(imagetmp, height/24*x, height/24*y,height/24,height/24);
    		}
    	}
    }
    
    function mouseClicked() {
    	indice=int(mouseX/height*24)+24*int(mouseY/height*24);
    	if (mouseButton === CENTER) {
    		terrainJoueur[indice]=9;
        }
    	if (mouseButton === LEFT) {
    		if (gameOver==0) {
    			terrainJoueur[indice]=terrainCache[indice];
    			if (terrainCache[indice]==11) {
    			     terrainJoueur=terrainCache
    			     terrainJoueur[indice]=12
    			     gameOver=1
    		    }
                if (terrainCache[indice]==0) { //c'est ici que je suis bloqué 
                }
            }
        }
    }

    Pour afficher le résultat j'utilise un HTML "vide" juste pour voir les résultats. Mes collègues s'occupent du site final qui "hébergera" le démineur.

    J'espère que vous saurez m'aider. Merci d'avance!

    Cordialement,

    -
    Edité par Anonyme 13 avril 2018 à 21:47:15

    • Partager sur Facebook
    • Partager sur Twitter
      13 avril 2018 à 22:10:24

      Bonjour,

      Mauvais forum

      Le sujet est déplacé dans le forum approprié : Javascript

      • Partager sur Facebook
      • Partager sur Twitter

      Pas d'aide concernant le code par MP, le forum est là pour ça :)

        13 avril 2018 à 23:37:43

        Un peu de la triche, mais voilà une super vidéo (en anglais) où tu peux voir le développement d'un démineur en p5 de A à Z :

        https://www.youtube.com/watch?v=LFU5ZlrR21E

        En gros, la meilleur façon de faire est d'utiliser des objets.
        Chaque case est un objet qui :

        • stock sa valeur (vide, bombe, numéro)
        • stock un tableau qui liste ses cases voisines
        • a une méthode pour être "révélée"
        • a une méthode pour être "flaguée"

        Dès que tu cliques sur une case, elle utilise sa méthode pour se révéler. Elle déclenche ensuite cette même méthode sur ses cases voisines. Ses cases voisines vides déclenchent ensuite cette méthodes sur leur propres voisines et ainsi de suite.

        Et forcément :

        • une bombe ne peut pas être révélée par une case voisine, seulement au clic
        • si tu révèles une bombe, tu as perdu
        • si toutes les cases ont été révélées ou flagées, tu as gagné

        -
        Edité par Syltaen 13 avril 2018 à 23:44:19

        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          14 avril 2018 à 16:31:16

          J'ai regardé la vidéo et en effet elle est super! Cependant, je dois finir mon codage avec celui que j'ai commencé, j'ai pas le droit de "refaire" un codage tout neuf (qui en plus de cela est copié sur une vidéo). Ce que je veux dire c'est que mon prof (qui fait partit du jury et qui a suivi mon travail de A à Z) connaît mon code et donc s'il remarque que j'ai tout changer il va se douter que je me suis inspiré de quelqu'un d'autre (étant donné que je ne pourrais "inventer" un code comme ça du jour au lendemain avec mon niveau) et ça ne passera pas..
          Il n'y a donc pas d'autres solutions?

          Sinon je vous remercie de votre réponse rapide et complète! :)

          • Partager sur Facebook
          • Partager sur Twitter
            14 avril 2018 à 20:44:16

            Salut,

            C'est un problème de codage ou d'algorithme qui vous fait défaut ?

            • Partager sur Facebook
            • Partager sur Twitter
              14 avril 2018 à 23:18:55

              voir, à titre d'exemple ce scipt qui utilise une fonction récurrente pour dévoiler les cases voisines http://julien-de-prabere.fr/divers/demineur.htm
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                15 avril 2018 à 19:42:24

                GannoN a écrit:

                Salut,

                C'est un problème de codage ou d'algorithme qui vous fait défaut ?

                C'est un problème d'algorithme et donc je ne sais pas comment le coder, parce que j'imagine que c'est avec function mouseClicked() qui faut continuer, en faisant en sorte que si la case sélectionnée est égale à 0 alors il faut la dévoiler et interroger les cases autour de cette dernière pour voir lesquelles sont aussi égales à 0 et ayant pour limites les cases étant égales à des chiffres.

                007julien a écrit:

                voir, à titre d'exemple ce scipt qui utilise une fonction récurrente pour dévoiler les cases voisines http://julien-de-prabere.fr/divers/demineur.htm

                J'ai déjà mené mes recherches et j'ai déjà étudier le code de ce démineur, cependant ça ne correspond pas à ce que je recherche étant donné que le code s'appuie sur une toute autre méthode et que je dois continuer avec ce que j'ai déjà fait. Merci quand même de ta réponse et de ton aide! :)

                -
                Edité par Anonyme 15 avril 2018 à 19:48:56

                • Partager sur Facebook
                • Partager sur Twitter
                  15 avril 2018 à 20:23:26

                  C'est exactement ça, un pseudo algo :

                  const decouverte_case = function (x, y) {
                  	const caseValue = getValueCase(x, y)
                  	afficher_case(x, y)
                  	if (caseValue === VIDE) {
                  		const offsetCaseAdjacent = [
                  			[-1, 0], [1, 0], [0, -1], [0, 1]
                  		]
                  		for (let offset of offsetCaseAdjacent) {
                  			const newX = x + offset[0]
                  			const newY = y + offset[1]
                  			// Attention au bordure ( < 0 || >= size )
                  			const value = getValueCase(newX, newY)
                  			if (value === VIDE) {
                  				decouverte_case(newX, newY)
                  			}
                  		}
                  	}
                  	
                  }



                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    16 avril 2018 à 20:37:36

                    GannoN a écrit:

                    C'est exactement ça, un pseudo algo :

                    const decouverte_case = function (x, y) {
                    	const caseValue = getValueCase(x, y)
                    	afficher_case(x, y)
                    	if (caseValue === VIDE) {
                    		const offsetCaseAdjacent = [
                    			[-1, 0], [1, 0], [0, -1], [0, 1]
                    		]
                    		for (let offset of offsetCaseAdjacent) {
                    			const newX = x + offset[0]
                    			const newY = y + offset[1]
                    			// Attention au bordure ( < 0 || >= size )
                    			const value = getValueCase(newX, newY)
                    			if (value === VIDE) {
                    				decouverte_case(newX, newY)
                    			}
                    		}
                    	}
                    	
                    }



                    GannoN je vous remercie pour votre grande aide, cependant j'ai beau essayer avec votre code, rien ne change, quand je clique sur une case "vide" (ayant pour valeur 0) aucune case à côté ne se dévoile est-ce normal? (j'ai l'impression de paraître incapable de faire quelque chose mais faut dire que j'ai tendance à perdre espoir après tous les essais que j'ai réaliser ces derniers jours.. :')

                    Est-ce que ce n'est pas aussi à cause du fait que j'ai créé plusieurs "terrains"?

                    -
                    Edité par Anonyme 16 avril 2018 à 20:43:35

                    • Partager sur Facebook
                    • Partager sur Twitter
                      17 avril 2018 à 15:59:13

                      Pouvais vous poster votre code sur plunker (http://plnkr.co) ou autre codepen, ... ?

                      Avec ça, je serrais plus en mesure de vous guider.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        17 avril 2018 à 19:30:18

                        GannoN a écrit:

                        Pouvais vous poster votre code sur plunker (http://plnkr.co) ou autre codepen, ... ?

                        Avec ça, je serrais plus en mesure de vous guider.

                        Je ne peux pas mettre les images sur plunker ni sur codepen.. Alors je l'ai fait sur Thimble! (J'espère que ça le fait ^^')
                        Voici le lien: https://thimbleprojects.org/haxtrale/460774/ il suffit de cliquer sur la case "Remixer" pour avoir accès à tout le code et aux images utilisées! Je vous remercie pour votre générosité :)



                        • Partager sur Facebook
                        • Partager sur Twitter
                          17 avril 2018 à 22:32:47

                          function decouverteCase(x, y) {
                            const indice = x + 24 * y
                          
                            // Si la case est deja decouverte, ne rien faire
                            if (terrainJoueur[indice] !== 10) {
                              return
                            }
                            
                            const caseDecouverte = terrainCache[indice]
                            terrainJoueur[indice] = caseDecouverte
                            
                            // Si la case est vide
                            if (caseDecouverte === 0) {
                              const caseAdjacenteIndex = []
                              // On regarde les case adjacente valide
                              if (x !== 1) { caseAdjacenteIndex.push([x - 1, y])}
                              if (x !== 22) { caseAdjacenteIndex.push([x + 1, y])}
                              if (y !== 1) { caseAdjacenteIndex.push([x, y - 1])}
                              if (y !== 22) { caseAdjacenteIndex.push([x, y + 1])}
                              // et pour chaque case qui est aussi vide
                              // relance la function decouverte sur cette case
                              for (let i of caseAdjacenteIndex) {
                                const caseValue = terrainCache[ i[0] + 24 * i[1] ]
                                if (caseValue === 0) {
                                  decouverteCase(i[0], i[1])
                                }
                              }
                            // Si on tombe sur une bombe !
                            // C'est game over
                            } else if (caseDecouverte === 11) {
                              terrainJoueur = terrainCache
                              terrainJoueur[indice] = 12
                              gameOver = 1
                            }
                            
                          }
                          
                          function mouseClicked() {
                          	indice=int(mouseX/height*24)+24*int(mouseY/height*24);
                          	if (mouseButton === CENTER) {
                          		terrainJoueur[indice]=9;
                              }
                          	if (mouseButton === LEFT) {
                          		if (gameOver==0) {
                                decouverteCase(int(mouseX/height*24), int(mouseY/height*24))
                              }
                            }
                          }
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            18 avril 2018 à 13:54:25

                            GannoN a écrit:

                            function decouverteCase(x, y) {
                              const indice = x + 24 * y
                            
                              // Si la case est deja decouverte, ne rien faire
                              if (terrainJoueur[indice] !== 10) {
                                return
                              }
                              
                              const caseDecouverte = terrainCache[indice]
                              terrainJoueur[indice] = caseDecouverte
                              
                              // Si la case est vide
                              if (caseDecouverte === 0) {
                                const caseAdjacenteIndex = []
                                // On regarde les case adjacente valide
                                if (x !== 1) { caseAdjacenteIndex.push([x - 1, y])}
                                if (x !== 22) { caseAdjacenteIndex.push([x + 1, y])}
                                if (y !== 1) { caseAdjacenteIndex.push([x, y - 1])}
                                if (y !== 22) { caseAdjacenteIndex.push([x, y + 1])}
                                // et pour chaque case qui est aussi vide
                                // relance la function decouverte sur cette case
                                for (let i of caseAdjacenteIndex) {
                                  const caseValue = terrainCache[ i[0] + 24 * i[1] ]
                                  if (caseValue === 0) {
                                    decouverteCase(i[0], i[1])
                                  }
                                }
                              // Si on tombe sur une bombe !
                              // C'est game over
                              } else if (caseDecouverte === 11) {
                                terrainJoueur = terrainCache
                                terrainJoueur[indice] = 12
                                gameOver = 1
                              }
                              
                            }
                            
                            function mouseClicked() {
                            	indice=int(mouseX/height*24)+24*int(mouseY/height*24);
                            	if (mouseButton === CENTER) {
                            		terrainJoueur[indice]=9;
                                }
                            	if (mouseButton === LEFT) {
                            		if (gameOver==0) {
                                  decouverteCase(int(mouseX/height*24), int(mouseY/height*24))
                                }
                              }
                            }

                            Un grand merci à toi GannoN !! C'est parfait! J'espère ne pas avoir été trop dérangeant et je vous remercie pour votre gentillesse et votre aide! :)
                            Par ailleurs juste une autre question, vous pensez qu'avec ce code je peux directement ajouter le moyen de faire que lorsque on clique sur une case "vide" toutes les cases adjacentes vides se découvrent mais aussi les chiffres qui sont adjacents à ces mêmes cases vides? (Comme sur cette image: http://prntscr.com/j6v6ey)



                            -
                            Edité par Anonyme 18 avril 2018 à 14:09:16

                            • Partager sur Facebook
                            • Partager sur Twitter
                              18 avril 2018 à 14:59:47

                              Tout est possible :)

                              Dans le bout de code envoyer, ajoute un else a la ligne 26 et ajoute le code manquant.

                              Bonne chance

                              • Partager sur Facebook
                              • Partager sur Twitter
                              Anonyme
                                18 avril 2018 à 22:07:39

                                Aha yeah alors! :)
                                Pas de soucis je vais travailler cela! Encore merci pour votre aide gracieuse! :p
                                • Partager sur Facebook
                                • Partager sur Twitter

                                [Problème] Codage Démineur débutant (avec p5.js).

                                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                • Editeur
                                • Markdown