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

C Discussion :

Problème de fonction qui plante


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Problème de fonction qui plante
    Bonjour à tous,
    Je suis en train de créer un démineur en langage C, j'essaye de réaliser une fonction qui dévoile automatiquement toutes les cases sans bombes à proximité lorsqu'on la sélectionne.

    Je regarde donc la case en haut, à droite, en bas et à gauche et je le propage en répétant la fonction. Lorsque j'utilise seulement deux conditions, par exemple haut gauche ou bas gauche. Mais quand je fais des conditions opposées comme haut bas et droite gauche ça plante. Donc la fonction est inutilisable.

    Je vous donne le code:
    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
     
    void caseVide(int x, int y, int grilleValeur[XMAX+2][YMAX+2], int grilleUser[XMAX][YMAX], int *compteurVictoire, int *j)
    {
     
     
        //Condition
        //Case du dessus
        if(x>0 && grilleUser[x-1][y]==0) //On regarde si ça ne dépasse pas du tableau et si la case a déjà était dévoilé
        {
            if(grilleValeur[x][y+1]==0) //Je regarde si la case est un 0
            {
                caseVide(x-1,y,grilleValeur,grilleUser,&*compteurVictoire,&*j);//Je répète la fonction
                *j=*j+1;//J'incrément ma boucle de 1;
            }
            grilleUser[x-1][y]=1; //Je dévoile la case
            *compteurVictoire = *compteurVictoire+1; //J'incrémente le compteur de victoire de 1
     
        }
        //Case de droite
        if(y<YMAX-1 && grilleUser[x][y+1]==0)
        {
            if(grilleValeur[x+1][y+2]==0)
            {
                caseVide(x,y+1,grilleValeur,grilleUser,&*compteurVictoire,&*j);
                *j=*j+1;
            }
            grilleUser[x][y+1]=1;
            *compteurVictoire = *compteurVictoire+1;
        }
        //Case du bas
        if(x<XMAX-1 && grilleUser[x+1][y]==0)
        {
            if(grilleValeur[x+2][y+1]==0)
            {
                caseVide(x+1,y,grilleValeur,grilleUser,&*compteurVictoire,&*j);
                *j=*j+1;
            }
            grilleUser[x+1][y]=1;
            *compteurVictoire = *compteurVictoire+1;
        }
        //Case de gauche
        if(y>0 && grilleUser[x][y-1]==0)
        {
            if(grilleValeur[x+1][y]==0)
            {
                caseVide(x,y-1,grilleValeur,grilleUser,&*compteurVictoire,&*j);
                *j=*j+1;
            }
            grilleUser[x][y-1]=1;
            *compteurVictoire = *compteurVictoire+1;
        }
     
    }
    Cordialement Airox

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 559
    Points
    10 559
    Par défaut
    Et avec des tests de façon classique

    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
    #define TEST_BOMB(POS_X, POS_Y) \
        if (grilleUser[POS_X][POS_X] == 0) { \
             \
            grilleUser[POS_X][POS_Y] = 1; /*<- à tester mais dévoiler avant de lancer la récursivité*/ \
             \
            if(grilleValeur[(POS_X + 1)][(POS_Y + 1)] == 0) { \
                caseVide((POS_X, POS_Y, grilleValeur, grilleUser, compteurVictoire, j); \
            } \
             \
            (*compteurVictoire) = ((*compteurVictoire) + 1); \
        }
     
     
    //  ...
     
    void caseVide(int x, int y, int* grilleValeur, int* grilleUser, int* compteurVictoire, int* j) {
        if (x > 0) {
            if (y > 0) {
    //          left - bottom
                TEST_BOMB((x - 1), (y - 1))
     
    //          middle - bottom
                TEST_BOMB(x, (y - 1))
            }
     
    //      left - middle
            TEST_BOMB((x - 1), y)
     
            if (y < (YMAX - 1)) {
    //          left - top
                TEST_BOMB((x - 1), (y + 1))
     
    //          middle - top
                TEST_BOMB(x, (y + 1))
            }
        }
     
    //  middle - middle
        TEST_BOMB(x, y)
     
     
        if (x < (XMAX - 1)) {
            if (y > 0) {
    //          right - bottom
                TEST_BOMB((x + 1), (y - 1))
     
    //          middle - bottom if not yet done
    //          TEST_BOMB(x, (y - 1))
            }
     
    //      middle - right
            TEST_BOMB((x + 1), y)
     
            if (y < (YMAX - 1)) {
    //          top - right
                TEST_BOMB((x + 1), (y + 1))
     
    //          middle - top if not yet done
    //          TEST_BOMB(x, (y + 1))
            }
        }
    }

    Édit 1: j'arrive après la bataille , mais il faut inverser 2 lignes. On marque la case visitée et ensuite on lance la récursivité

    Édit 2: Mes tests sont à vérifier quand même , mais c'est l'idée du truc: on teste si le point à un côté gauche et ensuite s'il a un côté droit. Et pour chaque côté, on teste s'il a un (y - 1) et un (y + 1)

    On peut inverser mes tests. On teste si le point à un (y - 1) et ensuite s'il a un (y + 1). Et pour haut/ bas, on teste s'il a un côté gauche et un côté droit

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Sans regarder le code quand on me dit:

    - J'ai une fonction récursive et j'ai quatre directions
    - Cela ne plante pas quand je regarde dans les directions non opposées
    - Cela plante quand je regarde dans des directions opposées

    Tout de suite, cela hurle: récursivité infinie...

    Et ce que je suppose:
    - La fonction va regarder à gauche, la fonction va regarder à droite, la fonction va regarder à gauche, la fonction va regarder à droite...

    Et donc je me dis: ça doit être parce que la personne ne garde pas en mémoire les cases visitées.

    Enfin, je regarde ton code: je vois une variation de la visite d'une case (donc mieux que ce que je pensais ) mais l'ordre n'est pas bon:

    - Marque ta case comme dévoilé
    - Ensuite regarde autour

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Merci c'est exactement ça ! J'y ai pensé pendant la nuit (oui je rêve de mon code ). En tout cas merci pour ta réponse. Foetus je savais pas qu'on pouvais faire un if comme ça. Je vais pouvoir compacter mon code Merci à toi aussi.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Deuxième passage dans une fonction qui plante
    Par sempere dans le forum ActionScript 3
    Réponses: 0
    Dernier message: 05/11/2013, 05h57
  2. [2.x] Fonction qui plante Apache
    Par blugeen dans le forum Symfony
    Réponses: 5
    Dernier message: 26/06/2013, 12h22
  3. fonction qui plante
    Par étoile de mer dans le forum Débuter
    Réponses: 3
    Dernier message: 19/09/2008, 09h42
  4. fonction qui plante mon programme
    Par étoile de mer dans le forum Débuter
    Réponses: 21
    Dernier message: 22/08/2008, 15h08
  5. [Problème] Requête ping qui plante !
    Par magicbisous-nours dans le forum VB.NET
    Réponses: 1
    Dernier message: 14/12/2007, 17h04

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