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 :

Demineur erreur de segmentation.


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Demineur erreur de segmentation.
    Salut,

    Je code un démineur en console, et j'utilise la récursivité (en taous cas j'essaye), j'ai une erreur de segmentation dans la fonction qui dévoile les cases, je la post ici.
    J'utilise 2 tableaux, pour l'instant ils sont initialisés normalement donc je dois tester à chaque fois les bords, les coins et les côtés pour éviter justement ce genre d'erreur, mais je ne comprend pas pourquoi ça ne fonctionne pas.

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x)
    {
    	if(tableauMine[y][x] == 0)
    	{
    		tableauJeu[y][x] = VIDE;
     
    		if(x == 0 && y == 0)
    		{
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    		}
    		else if(x == 0 && (y > 0 && y < TAILLE))
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    		}
    		else if(x == 0 && y == TAILLE)
    		{
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    		}
    		else if((x > 0 && x < TAILLE) && y == 0)
    		{
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    		}
    		else if((x > 0 && x < TAILLE) && y == TAILLE)
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    		}
    		else if(x == TAILLE && (y > 0 && y < TAILLE))
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    		}
    		else if(x == TAILLE && y == 0)
    		{
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    		}
    		else if(x == TAILLE && y == TAILLE)
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    		}
    		else
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    		}
    	}
     
    	if(tableauMine[y][x] == 1)	tableauJeu[y][x] = '1';
    	if(tableauMine[y][x] == 2)	tableauJeu[y][x] = '2';
    	if(tableauMine[y][x] == 3)	tableauJeu[y][x] = '3';
    	if(tableauMine[y][x] == 4)	tableauJeu[y][x] = '4';
    	if(tableauMine[y][x] == 5)	tableauJeu[y][x] = '5';
    	if(tableauMine[y][x] == 6)	tableauJeu[y][x] = '6';
    	if(tableauMine[y][x] == 7)	tableauJeu[y][x] = '7';
    	if(tableauMine[y][x] == 8)	tableauJeu[y][x] = '8';
    	if(tableauMine[y][x] == 9)	tableauJeu[y][x] = '9';
    }
    Merci.

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    Bonjour,
    tu peux beaucoup simplifier ta fonction en englobant tout son contenu dans un test pour savoir si tu es dans le tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x)
    {
    	if (x >= 0 && x <TAILLE && y >= TAILLE && y < TAILLE) {
    		/* Dévoiler la case */
    	}
    }
    Comme ça tu n'as pas besoin de particulariser ton code si tu te trouves au bord du damier. Tu auras plus de facilité à trouver ton erreur de seg si elle y est toujours. Et dans ce cas, n'hésite pas à utiliser valgrind pour trouver ton bug (ou gdb, mais c'est moins simple).

    Plus précisément, concernant ton erreur, je sui à peu près sûr que tu as oublié un cas, ou que tu t'es trompé en traitant un cas. Donc si tu les supprime tous, ça devrait marcher .

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Oui mais si j'execute ce code, je testerais les cases qu'il y a à l'interieur du tableau, donc les bords et les coins je les oublies, et ils ne sont jamais dévoilé ??

    Sinon ce que j'avais pensé à faire c'est initialiser tous les bords et les coins en case vide et par conséquent je peux utiliser ta méthode.

  4. #4
    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
    Sinon, ceci devrait fonctionner, non ?

    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
    if (x > 0)
    {
        if (y > 0)
             devoileCase(tableauJeu, tableauMine, y-1, x-1);
     
        devoileCase (tableauJeu, tableauMine, y, x-1);
     
        if (y < TAILLE)
             devoileCase(tableauJeu, tableauMine, y+1, x-1);
    }
     
    if (x < TAILLE)
    {
        if (y > 0)
             devoileCase(tableauJeu, tableauMine, y-1, x+1);
     
        devoileCase (tableauJeu, tableauMine, y, x+1);
     
        if (y < TAILLE)
             devoileCase(tableauJeu, tableauMine, y+1, x+1);
    }
     
    if (y > 0)
    {
        devoileCase (tableauJeu, tableauMine, y-1, x);
    }
     
     
    if (y < TAILLE)
    {
        devoileCase (tableauJeu, tableauMine, y+1, x);
    }

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Non ce code ne fonctionne pas, toujours une erreur de segmentation, j'ai regardé ton code et il n'y as pas l'air d'avoir d'erreur dans les appels de fonctions donc la non plus je ne sais pas d'ou ça viens.

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    @ezano ajouter une ligne autour, ça devrait marcher très bien. C'est pas optimal côté occupation mémoire, mais c'est pas monstrueusement grave dans ce genre de cas...

    En revanche, si on reprend mon algo, que je détaille un peu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    dévoiler(x, y)
        si dans le damier et non dévoilée
            découvrir(x,y)
            si mine alors
                boom
            sinon si nombre nul alors
                pour chaque case(X,Y) autour
                    dévoiler(X,Y)
                    /* Les cases autour sont (x+1,y), (x+1,y+1), (x,y+1) ... 8 en tout */
    (X,Y) c'est les coordonnées d'une case autour de celle qu'on était en train de dévoiler et découvrir c'est la fonction qui te fait afficher ce qu'il y avait dans la case.
    ma solution devrait fonctionner elle aussi, exemple, on considère le damier suivant :

    On suppose que rien n'est découvert. Si on clique sur la case de coordonnées (3, 0) (abscisse, ordonnée).
    On considère qu'on tourne dans le sens des aiguilles d'une montre à partir de la case à droite, on obtient :
    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
    dévoiler(3,0)  /* Nombre non nul donc on découvre autour */
        découvrir(3,0)
        dévoiler(4,0) /* Nombre non nul donc on découvre autour */
            découvrir(4,0) 
            dévoiler(5,0)  /* Nombre nul donc on ne découvre pas autour */
                découvrir(5,0)
            dévoiler(5,1)
                découvrir(5,1)
            dévoiler(4,1)
                découvrir(4,1)
            dévoiler(3,1)
                découvrir(3,1)
            dévoiler(3,0) /* rien ne se passe car déjà découverte */
            dévoiler(3,-1) /* rien ne se passe car hors damier */
            dévoiler(4,-1) /* rien ne se passe car hors damier */
            dévoiler(5,-1) /* rien ne se passe car hors damier */
        dévoiler(4,1) /* rien ne se passe car déjà découverte */
        dévoiler(3,1) /* rien ne se passe car déjà découverte */
        dévoiler(2,1)
            découvrir(2,1)
        dévoiler(2,0)
            découvrir(2,0)
        dévoiler(2,-1) /* rien ne se passe car hors damier */
        dévoiler(3,-1) /* rien ne se passe car hors damier */
        dévoiler(4,-1) /* rien ne se passe car hors damier */
    Sinon pour tes erreurs de ség, compile avec les informations de débogage (flag -g de gcc) et utilise valgrind.

  7. #7
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    @-ezano-
    Ton code est illogique dans ses tests :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x)
    {
    	if(tableauMine[y][x] == 0)
    	{
    		tableauJeu[y][x] = VIDE;
     
    		if(x == 0 && y == 0)
    ....
    		else if(x == 0 && (y > 0 && y < TAILLE))
    ....
    D'après la dernière ligne montrée ici où on teste y > 0 et y < TAILLE (et plus loin dans le code, on teste x < TAILLE et x > 0), on peut entrer dans cette fonction avec y (et/ou x) négatif ou y (et/ou x) égal à TAILLE.

    Dans ces cas, tableauMine[y][x] == 0 accède et tableauJeu[y][x] = VIDE modifie des "éléments" hors des tableaux -> plantage.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  8. #8
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Avec ton code tu fais tout simplement exploser la pile.
    Je m'explique:
    Tu appelles ta fonction avec (x, y), une fois dans ta fonction tu appelles la fonction avec (x-1, y) et ensuite tu rappelles ta fonction avec (x+1, y) qui est égal à (x, y) du coup tu fais une récursion infinie et tu fais exploser ta pile
    Plus tu pédales moins fort, moins t'avances plus vite.

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    Oui, je proposais donc de découvrir la case avant de dévoiler les cases autour. Ça devrait éviter ce problème.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    On m'a aidé sur un autre forum, j'ai compris ce que tu voulais dire et j'ai coder de cette manière, mais j'ai encore et toujours une erreur de segmentation du encore à la pile, j'ai tester avec gdb.

    Le code complet, si ça peux vous aider à me debugger le voici.

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    /***************************/
    /*   Programmed by ezano   */
    /***************************/
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
     
    /*
     *	Les constantes
     */
     
    #ifdef WIN32
    	#define CLEANSCREEN() system("cls");
    #else
    	#define CLEANSCREEN() system("clear");
    #endif	//Macro qui met efface l'ecran
     
     
    #define PAUSE() puts("Appuyer sur Entrée pour continuer..."); \
    				getchar(); \
    				getchar();	//Macro qui met en pause l'ecran
     
    #define TAILLE 10
    #define NBMINE 10
    #define CASEVIDE TAILLE * TAILLE
    #define VIDE ' '
    #define BOMBE 'B'
    #define INITIAL 'X'
     
    void initJeu(char tableauJeu[TAILLE][TAILLE]);
    void afficheJeu(char tableauJeu[TAILLE][TAILLE]);
    void afficheTableauMine(char tableauMine[TAILLE][TAILLE]);
    void placerMine(char tableauMine[TAILLE][TAILLE]);
    void jeu(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE]);
    void chercheMine(char tableauMine[TAILLE][TAILLE]);
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x);
     
    int main(void)
    {
    	char tableauJeu[TAILLE][TAILLE], tableauMine[TAILLE][TAILLE];
    	int choix;
     
    	srand(time(NULL));
     
    	do
    	{
    		CLEANSCREEN()
     
    		//On affiche le menu
    		puts("\t\t\t\t>>Demineur<<\n");
    		puts("1. Nouvelle partie\t\t2. Quitter");
    		printf("Votre choix:\n> ");
    		scanf("%d", &choix);
     
    		switch(choix) //Selon le choix on joue, on quitte le jeu ou on a taper une mauvaise valeur
    		{
    			case 1:
    				initJeu(tableauJeu);
    				placerMine(tableauMine);
    				chercheMine(tableauMine);
    				jeu(tableauJeu, tableauMine);
    				break;
     
    			case 2:
    				CLEANSCREEN()
    				exit(EXIT_SUCCESS);
    			default:
    				puts("Veuillez entrer une valeur correcte");
    				PAUSE()
    		}
    	} while(choix != 2);
     
    	return EXIT_SUCCESS;
    }
     
    /*
     *	Fonction d'initialisation du tableau de jeu
     */
    void initJeu(char tableauJeu[TAILLE][TAILLE])
    {
    	int i, j;
     
    	for(i = 0; i < TAILLE; i++)
    		for(j = 0; j < TAILLE ; j++)
    			tableauJeu[i][j] = INITIAL;
    }
     
    /*
     *	Fonction qui affiche le champ de mine
     */
    void afficheJeu(char tableauJeu[TAILLE][TAILLE])
    {
    	int i, j;
    	CLEANSCREEN()
     
    	printf("   ");
     
    	for(i = 0; i < TAILLE; i++)		//On affiche les coordonnée
    		printf("%d ", i);
     
    	puts("");
     
    	for(i = 0; i < TAILLE; i++)
    	{
    		printf("%2d ", i);	//On affiche les coordonnée
    		for(j = 0; j < TAILLE; j++)
    			printf("%c ", tableauJeu[j][i]);	//On affiche le jeu
     
    		puts("");
    	}			
    }
     
    /*
     *	Fonction qui affiche l'emplacement de toute les mines
     */
    void afficheTableauMine(char tableauMine[TAILLE][TAILLE])
    {
    	int i, j;
    	CLEANSCREEN()
     
    	printf("   ");
     
    	for(i = 0; i < TAILLE; i++)		//On affiche les coordonnée
    		printf("%d ", i);
     
    	puts("");
     
    	for(i = 0; i < TAILLE; i++)
    	{
    		printf("%2d ", i);	//On affiche les coordonnée
    		for(j = 0; j < TAILLE; j++)
    			printf("%c ", tableauMine[j][i]);	//On affiche le jeu
     
    		puts("");
    	}
    }
     
    /*
     *	Fonction qui place les mine dans le tableau de jeu
     */
    void placerMine(char tableauMine[TAILLE][TAILLE])
    {
    	int i, j, k = 0, x, y;
     
    	for(i = 0; i < TAILLE; i++)
    		for(j = 0; j < TAILLE; j++)
    			tableauMine[i][j] = VIDE;	//On initialise le tableauMine à VIDE
     
    	//On place les mines dedans
    	while(k < NBMINE)
    	{	
    		x = rand() % TAILLE;
    		y = rand() % TAILLE;
     
    		if(tableauMine[y][x] == VIDE)
    		{
    			tableauMine[y][x] = BOMBE;
    			k++;
    		}
    	}
    }
     
    /*
     *	Fonction qui gère une partie
     */
    void jeu(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE])
    {
    	int perdu = 0, nbCaseNonMine = 0, x, y;	//Declaration d'une variable coordonee de type Coordonnee
     
    	puts("");
     
    	while(perdu == 0 && nbCaseNonMine != CASEVIDE)	//On continue le jeu tant qu'on a pas perdu ou qu'on a pas gagné
    	{	
    		do
    		{
    			afficheJeu(tableauJeu);
     
    			printf("Abscisse:\n> ");
    			scanf("%d", &x);
    			printf("Ordonnée:\n> ");
    			scanf("%d", &y);
    		}while((x < 0 || x > 11) || (y < 0 || y > 11));	//On redemande les coordonnée si elles sont mal entrée
     
    		if(tableauMine[y][x] == BOMBE)	//Si on tombe sur une bombe on a perdu
    		{
    			afficheTableauMine(tableauMine);
    			puts("Game Over");
    			perdu--;
    			PAUSE()
    		}
    		else if(tableauJeu[y][x] != INITIAL)	//Si on a entré les coordonnée d'une case deja decouverte on le signale
    		{
    			puts("Vous avez déjà déminée cette zone");
    			PAUSE()
    		} 
    		else
    		{
    			devoileCase(tableauJeu, tableauMine, y, x);
    			nbCaseNonMine++;
    		}
    	}
    }
     
    /*
     *	Fonction de recherche de mine adjacente. Pour chaque case, on attribue le nombre de mine qu'il y a autour dans tableauMine
     */
    void chercheMine(char tableauMine[TAILLE][TAILLE])
    {
    	int x, y, compteur;
     
    	for(y = 0; y < TAILLE; y++)
    	{
    		for(x = 0; x < TAILLE; x++)
    		{
    			compteur = 0;
     
    			if(tableauMine[y][x] == BOMBE)
    				break;
     
    			if (x > 0) {
    				if (tableauMine[y][x-1] == BOMBE)
    					compteur++;
    				if (y > 0)
    					if (tableauMine[y-1][x-1] == BOMBE)
    						compteur++;
    				if (y < TAILLE - 1)
    					if (tableauMine[y+1][x-1] == BOMBE)
    						compteur++;
    			}
    			if (y > 0) {
    				if (tableauMine[y-1][x] == BOMBE)
    					compteur++;
    			}
    			if (x < TAILLE - 1) {
    				if (tableauMine[y][x+1] == BOMBE)
    					compteur++;
    				if (y > 0)
    					if (tableauMine[y-1][x+1] == BOMBE)
    						compteur++;
    				if (y < TAILLE - 1)
    					if (tableauMine[y+1][x] == BOMBE)
    						compteur++;
    			}
    			if (y < TAILLE - 1) {
    				if (tableauMine[y+1][x] == BOMBE)
    					compteur++;
    			}
     
    			tableauMine[y][x] = compteur;
    		}
    	}
    }
     
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x)
    {
    	int i;
     
    	if(tableauMine[y][x] == VIDE)
    	{
    		tableauJeu[y][x] = VIDE;
     
    		if (x > 0)
    		{
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			if (y > 0)
    				devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			if (y < TAILLE - 1)
    				devoileCase(tableauJeu, tableauMine, y+1, x-1);
    		}
    		if (y > 0)
    			devoileCase(tableauJeu, tableauMine, y-1, x);
     
    		if (x < TAILLE - 1) 
    		{
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			if (y > 0)
    				devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			if (y < TAILLE - 1)
    				devoileCase(tableauJeu, tableauMine, y+1, x);
    		}
    		if (y < TAILLE - 1)
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    	}
     
    	for (i = 1; i < 10; i++)
    		if(tableauMine[y][x] == i)
    			tableauJeu[y][x] = '0' + i;
    }
    Merci

  11. #11
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Avec le code que je t'ai fourni ça ne change pas le problème
    Tu as toujours un problème de récursion infinie.
    Regarde ce qu'a dit huit_six plus haut
    Plus tu pédales moins fort, moins t'avances plus vite.

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    Bonjour,
    Je confirme, un test rapide avec valgrind indique bien une explosion de la pile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stack overflow in thread 1: can't grow stack to 0xbe45cffc
    Je n'ai pas trop le temps d'aller plus en profondeur, mais quelques remarques rapides :
    * Dans devoileCase, ceci me parait surprenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	for (i = 1; i < 10; i++)
    		if(tableauMine[y][x] == i)
    			tableauJeu[y][x] = '0' + i;
    Je pense que ça pourrait se remplacer par quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (tableauMine[y][x] < 10 && tableauMine[y][x] > 0) tableauJeu[y][x] = '0' + tableauMine[x][y];
    Ça me parait plus clair et ça doit même pouvoir encore se simplifier suivant les valeurs possibles de tableauMine.

    * Ensuite, cette partie de code, qui si j'ai bien compris, sert à dévoiler le contenu de la case, devrait se trouver avant l'appel récursif, car dans le cas contraire, tu dévoile plusieurs fois la même case, ce qui te provoque ta récursion infinie.

    * Enfin, tu exclues les lignes du bord (x > 0, x < TAILLE - 1 ...). Pourquoi pas, mais à ce compte là, il te faut ne pas y mettre de mine et il faut les masquer au joueur, car sinon, il essaye de les dévoiler et il ne comprend pas pourquoi ça ne marche pas.

    Sinon, perso je trouve ce code plutôt propre, lisible, indenté, commenté mais pas à l'excès et surtout, sans warning.
    Mais comme j'en parlais plus haut, on doit pouvoir beaucoup simplifier devoilerCase en mettant un seul test pour vérifier que la case qu'on dévoile est dans le damier.

    Un autre "truc" que je trouve pratique : précalculer (éventuellement de manière automatique) les déplacements pour parcourir les cases autour par ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int dep[8][2] = {{1,0}, {1,1}, {0,1}, ...}; /* ou un tableau struct */
    ça permet de dévoiler les cases autour avec une simple boucle for du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i = 0; i < 8; i++) devoilerCase(x + depl[i][0], y + depl[i][1]);
    Ce tableau peut même se calculer automatiquement avec des cos et sin.

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    C'est bon j'ai trouvé la solution grâce à vous bien entendu, mais j'ai finis par comprendre le principe et tous à coulé de source ensuite.
    J'ai aussi modifier le principe de l'incrementation des cases autours des bombes, j'ai utilisé une methode moins naïve, tous simplement en posant une bombe à un endroit j'increment toute les cases autours en faisant attention à ne pas depasser le tableau et au fait que la case à incrémenté ne soit pas une bombe.

  14. #14
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    Cool !
    Un petit résolu ?

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

Discussions similaires

  1. Erreurs de segmentation !
    Par anti-conformiste dans le forum Applications et environnements graphiques
    Réponses: 16
    Dernier message: 18/10/2005, 12h11
  2. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 19h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 14h42
  4. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 15h25
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 12h18

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