Bug d'execution d'un demineur [Résolu]

Signaler
Messages postés
165
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
24 octobre 2007
-
julien_boss
Messages postés
165
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
24 octobre 2007
-
Bonjour,

je suis entrain de reproduire un demineur. Je crée dynamiquement un tableau tridimensionnel ; tridimensionnel car ce tableau contient 2 "grilles" de demineur - de 2 dimensions chacune. L'une des grilles contient l'emplacement des bombes, et l'autre est celle que le joueur voit (le nombre de bombes entourant telle case, si cette case est une bombe, si elle est vide, si le joueur n'a pas encore cliqué dessus...).

J'en suis à l'algorithme de clique sur une case. Je vérifie d'abord si la case est une bombe, puis si le joueur a déjà cliqué sur la case, auxquels cas je retourne la fonction. Ensuite je vérifie combien de bombes sont situés autour de la case, et je change l'état de cette case en fonction du nombre trouvé.
S'il n'y a aucune bombe aux alentours, je simule des cliques sur toutes les cases aux alentours par récursivité (comme cela se passe dans le vrai demineur, enfaite). C'est là que ca coince à l'éxécution, j'obtiens un message d'erreur et le programme plante. Je ne pense pas que ce soit du à une surcharge de la pile.
Voici le code de la fonction qui simule un clique sur une case (x;y) :

bool Deminor_ClickleftGrid(int ***grid, int gx, int gy, int x, int y)
{
    //Vérifie qu'on a pas cliqué en dehors de la grille
    if(x>gx || y>gy || x<0 || y<0) return false;
   
    //Verifie qu'on a pas cliqué sur une bombe
    if(Deminor_IsBomb(grid, gx, gy, x, y))
    {
        grid[1][x][y]=DEMPLAYER_BOMBON;
        return false;
    }
   
    //Vérifie qu'on a pas déjà cliqué sur cette case
    if(grid[1][x][y] != DEMPLAYER_UNKNOWN) return false;
   
    /****  Calcule le nombre de mines aux alentours  ****/
    int bombArround = DEMPLAYER_0;
   
    if(Deminor_IsBomb(grid, gx, gy, x-1, y-1)) bombArround++;
    if(Deminor_IsBomb(grid, gx, gy, x, y-1))   bombArround++;
    if(Deminor_IsBomb(grid, gx, gy, x+1, y-1)) bombArround++;
    if(Deminor_IsBomb(grid, gx, gy, x+1, y))   bombArround++;
    if(Deminor_IsBomb(grid, gx, gy, x+1, y+1)) bombArround++;
    if(Deminor_IsBomb(grid, gx, gy, x, y+1))   bombArround++;
    if(Deminor_IsBomb(grid, gx, gy, x-1, y+1)) bombArround++;
    if(Deminor_IsBomb(grid, gx, gy, x-1, y))   bombArround++;
   
    grid[1][x][y] = bombArround;
   
    if(bombArround == DEMPLAYER_0)     /*\ BUG LA \*/
    {
        Deminor_ClickleftGrid(grid, gx, gy, x-1, y-1);
        Deminor_ClickleftGrid(grid, gx, gy, x, y-1);
        Deminor_ClickleftGrid(grid, gx, gy, x+1, y-1);
        Deminor_ClickleftGrid(grid, gx, gy, x+1, y);
        Deminor_ClickleftGrid(grid, gx, gy, x+1, y+1);
        Deminor_ClickleftGrid(grid, gx, gy, x, y+1);
        Deminor_ClickleftGrid(grid, gx, gy, x-1, y+1);
        Deminor_ClickleftGrid(grid, gx, gy, x-1, y);
    }
    /****************************************************/
   
    return true;
}

Voilà, en esperant que vous y voyez plus clair que moi :)
Merci

8 réponses

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
10
J'adore ton message d'erreur... Très instructif... normalement on peut tirer au moins quelque chose du code d'erreur, mais là, 3806...

Mais je crois que j'ai trouvé.

Remplace ça :

   if(x>gx || y>gy || x<0 || y<0) return false;

par ça :

   if(x>=gx || y>=gy || x<0 || y<0) return false;

La dernière case de ton tableau à l'indice gx - 1 s'il est de taille gx.
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Question stupide mais t'as bien  DEMPLAYER_UNKNOWN différent de DEMPLAYER_0 en valeur ? Sinon c'est normal que ça plante.
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
10
Salut,

Si tu mets :
if(bombArround == DEMPLAYER_0)     /*\ BUG LA \*/
{ ...}

En commentaire, ça plante pas ?

Tu as bien un message d'erreur, non ? Peux-tu le donner ?

Eventuellement, montre nous comment tu alloues ce que tu passe comme argument grid, mais j'imagine que tu l'initialise donc le problème se manifesterais avant...

Zarb.
Messages postés
165
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
24 octobre 2007

juju12> oui les deux define ont des valeurs différentes

rt15> en effet si je mets tout ce passage en commentaire le programme ne plante plus. Comme erreur lors de l'exécution j'ai un message du "visual studio just-in-time debugger", qui me dit que "an unhandled win32 exception occurred in Demineur-console.exe [3608]" (c'est bien un message d'erreur qui apparait lors de l'execution hein, pas de prob à la compilation).

Voilà comment j'initialise ma grille :
    int ***grid;
    grid = new int**[2];
   
    grid[0] = new int*[x];
    grid[1] = new int*[x];
   
    for(int i=0; i<x; i++)
    {
        grid[0][i] = new int[y];
        grid[1][i] = new int[y];
    }

Je ne sais d'ailleurs pas si la méthode est la bonne, j'ai galéré pour arriver à ca ; mais visiblement ca marche puisque je peux afficher la grille (j'ai créé une fonction printGrid() qui fonctionne).
Messages postés
165
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
24 octobre 2007

Oui merci pour la correction, je n'y avais pas fait attention, mais le problème reste le même
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
10




Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
10
Erf...
Je recommence.
Ta fonction Deminor_IsBomb doit être protégée de la même manière.
Ton IDE as pas de débugueur permettant de voir le contenu des variables ?
Messages postés
165
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
24 octobre 2007

Mais vui quel con :D
Ca m'apprendra à faire plus attention, merci bcp