Bonjour à tous,
Je vous écris ce message pour vous demander de l'aide au sujet d'un problème .
Je programme un jeu de morpion de taille variable.
J’ai une version qui fonctionne parfaitement.
Je voulais apporter une modification pour simplifier un peu le code et maintenant, le programme ne fonctionne plus correctement.
Voici l’idée générale :
Je définis mes variables, définie 3 tableaux dynamiques
Dans le main, si je clique sur ModifierLesDimensions, cela m’ouvre une nouvelle page dans laquelle je peux modifier les dimensions. Pour sortir de cette page, soit je clique Annuler, soit je clique Valider.
Lorsque je veux valider, je reviens dans le main, vide mes tableaux avec leurs anciennes dimensions, redimensionne les tableaux aux nouvelles dimensions, vide les plateaux avec les nouvelles dimensions puis joue normalement.
Voici mon code qui fonctionne
Avec
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 int main(int argc, char **argv) { SDL_Surface *ecran=NULL; int N=3; int M=3; int NbJetonsAAligner=3; int AncienN=N; int AncienM=M; int AncienNbJetonsAAligner=NbJetonsAAligner;//on aligne 3 jetons au depart Case *plateau;//les Case étant Vide, Crois, Rond int *HistoriqueJeton= FonctionAllocation1D(N*M);//Ce tableau doit etre dynamique, efectue le test de bonne attribution int *ListeCasesVides= FonctionAllocation1D(N*M);//Tableau qui contient les numeros de toutes les cases vides au debut puis -1 pour les cases occupées. int NbCasesJouees=0; ... ... videJeu(plateau, N, M, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu switch(...) { case CONFIGDIMENSION: joueurEnCours=ListeJoueurs[NbCasesJouees%2]; AncienN=N; AncienM=M; AncienNbJetonsAAligner=NbJetonsAAligner; ConfigDimension(ecran, police,TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours, &Jeton, &N, &M, &NbJetonsAAligner, &ConfigModifiee);//on ouvre la configuration pour determiner le nombre de lignes et de colonnes du plateau de jeu et le nombre de jetons a aligner pour gagner if(ConfigModifiee==OUI)//si on modifie les dimensions du plateau de jeu { videJeu(plateau, AncienN, AncienM, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu APRES d'avoir modifier les dimensions, pour tout remettre a zero free(plateau); plateau=NULL; plateau=malloc(N*M*sizeof(*plateau));//on realloue un plateau aux nouvelles dimensions if(plateau==NULL)//si erreur d'allocation { free(plateau);//liberation du plateau fprintf(stderr, "Erreur de creation du tableau plateau"); exit(EXIT_FAILURE);//quitter le programme } free(HistoriqueJeton);//on libere HistoriqueJeu HistoriqueJeton=NULL; HistoriqueJeton= FonctionAllocation1D(N*M);//Ce tableau doit etre dynamique, efectue le test de bonne attribution free(ListeCasesVides);//on libere HistoriqueJeu ListeCasesVides=NULL; ListeCasesVides= FonctionAllocation1D(N*M);//Tableau qui contient les numeros de toutes les cases vides au debut puis -1 pour les cases occupées. videJeu(plateau, N, M, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu AVANT d'avoir modifier les dimensions, sinon, on ne vide pas tout le tableau PlateauJeuLarg=PlateauLarg/maximumEntre(N, M)*N;//Dimension reelle de la zone de jeu quand on personnalise les dimensions PlateauJeuHaut=PlateauHaut/maximumEntre(N, M)*M; ConfigModifiee=NON; } ... } ... }
et
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 void videJeu(Case *plateau, int N, int M, Joueur ListeJoueurs[], Joueur *joueurEnCours, int *PartieFinie, int *NbCasesJouees, int *HistoriqueJeton, int *ListeCasesVides)//Fonction pour vider le plateau de jeu { int i; for(i=0; i<N*M; i++)//On vide le plateau { plateau[i] = Vide;//toutes les cases sont vides HistoriqueJeton[i] = -1;//on reinitialise le tableau a -1 ListeCasesVides[i]=i;//on liste toutes les cases vides du tableau, c'est a dire toute les cases } *joueurEnCours=ListeJoueurs[0]; *NbCasesJouees = 0; *PartieFinie = NON;//On commence une nouvelle partie }
J’ai voulu remplacer une partie entre les lignes 27 et 52 par une fonction qui gère tout cela (car j’aurai besoin de la réutiliser dans une autre fonction, donc je voulais simplifier plutôt que de réécrire la vingtaine de lignes)
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 int *FonctionAllocation1D(int dimension) { int *tableau=malloc(dimension*sizeof(*tableau));//Ce tableau doit etre dynamique int i; if(tableau==NULL)//si erreur d'allocation { free(tableau);//liberation du tableau fprintf(stderr, "Erreur de creation du tableau "); exit(EXIT_FAILURE);//quitter le programme } for (i=0; i<dimension; i++) //On initialise le tableau avec 0 { tableau[i]=0; } return tableau; }
Le main que j’obtiens deviens …
avec
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 case CONFIGDIMENSION: joueurEnCours=ListeJoueurs[NbCasesJouees%2]; AncienN=N; AncienM=M; AncienNbJetonsAAligner=NbJetonsAAligner; ConfigDimension(ecran, police,TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours, &Jeton, &N, &M, &NbJetonsAAligner, &ConfigModifiee);//on ouvre la configuration pour determiner le nombre de lignes et de colonnes du plateau de jeu et le nombre de jetons a aligner pour gagner if(ConfigModifiee==OUI)//si on modifie les dimensions du plateau de jeu { ModificationConfigDimension(AncienN, AncienM, N,M, plateau, ListeJoueurs,&joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides); ConfigModifiee=NON; PlateauJeuLarg=PlateauLarg/maximumEntre(N, M)*N;//Dimension reelle de la zone de jeu quand on personnalise les dimensions PlateauJeuHaut=PlateauHaut/maximumEntre(N, M)*M; }
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 void ModificationConfigDimension(int AncienN,int AncienM,int NouveauN,int NouveauM,Case *plateau, Joueur ListeJoueurs[], Joueur *joueurEnCours, int *PartieFinie, int *NbCasesJouees, int *HistoriqueJeton, int *ListeCasesVides) { //si seul le NbJetonAAligner a changé, alors on vide le plateau //si N ou M a changé, il faut tout vider et faire les realloc puis vider le jeu if((AncienN !=NouveauN)||(AncienM!=NouveauM)) { videJeu(plateau, AncienN, AncienM, ListeJoueurs, joueurEnCours, PartieFinie, NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu AVANT d'avoir modifier les dimensions, pour tout remettre a zero free(plateau); plateau=NULL; plateau=malloc(NouveauN*NouveauM*sizeof(*plateau));//on realloue un plateau aux nouvelles dimensions if(plateau==NULL)//si erreur d'allocation { free(plateau);//liberation du plateau fprintf(stderr, "Erreur de creation du tableau plateau"); exit(EXIT_FAILURE);//quitter le programme } free(HistoriqueJeton);//on libere HistoriqueJeu HistoriqueJeton=NULL; HistoriqueJeton= FonctionAllocation1D(NouveauN*NouveauM);//Ce tableau doit etre dynamique free(ListeCasesVides);//on libere ListeCasesVides ListeCasesVides=NULL; ListeCasesVides= FonctionAllocation1D(NouveauN*NouveauM);//Tableau qui contient les numeros de toutes les cases vides au debut puis -1 pour les cases occupées. } videJeu(plateau, NouveauN, NouveauM, ListeJoueurs, joueurEnCours, PartieFinie, NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu APRES d'avoir modifier les dimensions, sinon, on ne vide pas tout le tableau }
Je n’ai pas d’alerte au moment de la compilation.
Sauf que lorsque je redimensionne, j’ai parfois quelques jetons qui se placent sur le plateau et certaines cases ne sont pas accessibles.
Mais surtout, lorsque je redimensionne encore une fois, ou lorsque je vide le jeu suite à une nouvelle partie, le programme plante.
Il semblerait qu’il y ait des erreurs au niveau de free(HistoriqueJeton) et free(ListeCasesVides).
Je pencherai au niveau d'un problème de passage de paramètres/pointeurs à la fonction videJeu ou au moment de la création des tableaux avec les nouvelles dimensions.
Je vous remercie de l'aide que vous pourrez m'apporter.
Cordialement
Ludovic
Partager