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 :

redimensionnement d'un tableau dynamique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2019
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 59
    Par défaut redimensionnement d'un tableau dynamique
    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

    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;
                   }
    ...
        }
       ...
    }
    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
     
    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
    }
    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
    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;
    }
    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)
    Le main que j’obtiens deviens …

    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;
     
                        }
    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
     
    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

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Ton code me parait bien confus. Avec tes "et je vide avec l'ancienne dimension, et je vide avec les nouvelles dimensions" et autres.

    Il faut que tu sois clair dans tes idées. Est-ce que tu veux changer les dimensions en cours de partie ou bien (ce que je crois) proposer simplement le choix de la dimension au début de la partie. Dans ce cas, ce n'est pas un "redimensionnement" qu'il te faut mais simplement un "dimensionnement". Si par exemple tu veux que le programme boucle avec à chaque tour un choix de jeu aux dimensions N, alors il te faut le coder ainsi
    1. début de boucle
    2. proposition du choix des dimensions (avec éventuellement une valeur par défaut)
    3. allocation (et pour ça calloc() ou au pire malloc() + memset() seraient peut-être plus approprié que ton malloc() avec ensuite ta boucle =0)
    4. jeu
    5. libération (et il n'y a aucun souci avec le free())
    6. fin de boucle


    Le "redimensionnement" permet d'agrandir un tableau déjà utilisé sans perdre son contenu. Et pour ça il y a realloc() qui fait tout tout seul (soit agrandissement de ce qui existe déjà, soit allocation ailleurs et recopie de ce qui existe déjà puis libération du vieux). Mais parler de "redimensionnement" quand il s'agit juste de vider ce qui existe (ce qui déjà est un non-sens car une mémoire ne peut pas être "vide") puis allouer un tableau neuf et le mettre à 0 (on se demande alors pourquoi s'être cassé le luc à "vider" l'ancien)...

    Quelques remarques générales: on ne quitte pas un programme au beau milieu d'une fonction. Seul le main() a le droit de faire exit(). Si malloc() échoue, alors ta fonction qui l'utilise doit soit gérer le souci, soit le remonter à l'appelant qui devra lui-même soit gérer le souci, soit le remonter à son propre appelant et etc jusqu'au main. Parce que si tu alloues tableau1, que tu alloues tableau2 et que l'allocation de tableau3 échoue, ben tu quittes benoitement ton code et tu te laves les mains de ce qui peut arriver à tableau1 ou tableau2 (certes les OS modernes libèrent eux-mêmes mais ça reste dégueu).
    Ensuite si malloc() échoue alors c'est idiot de faire un free() (ligne 15 de ton nouveau code) qui montre donc que tu ne "ressens" pas réellement ce que tu écris. En plus ça ne marche que parce que free(NULL) a été codé pour être autorisé mais si tu appliques la même politique au fopen() (style si ça échoue alors je fais fclose()) alors c'est le crash assuré.
    Et enfin tu as beaucoup trop de paramètres 'listeJoueurs", "joueurEnCours", "partieFinie", etc. Tu ne connais pas les structures qui te permettent de regrouper plein de trucs ensembles et de les passer d'un coup aux fonctions qui en ont besoin ? D'autant plus que si tu as n tableaux liés (par exemple "liste des cases" lié à "liste des cases vides" et autre), tu regroupes ça dans une structure que tu peux allouer d'un coup => un seul malloc() au lieu de 3 ce qui aide grandement la gestion des échecs).

    Désolé, tu as peut-être fait un truc qui, comme tu dis, "fonctionne parfaitement" mais comme tu l'as mal bâti dès le départ, tu te retrouves coincé pour le faire évoluer. Et tu te retrouves maintenant à rajouter des verrues bancales qui peut-être finiront par fonctionner mais ça aura élevé sa complexité au carré pour le cas où tu voudrais encore le faire évoluer ensuite. Mieux vaudrait repartir sur des bases saines...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2019
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 59
    Par défaut
    Bonjour Sve@r, merci de m'avoir répondu.

    Pour répondre à la 1ere partie de ton message, je te donne quelques précisions car je n'aiposté qu'une version condensée du min.

    - Je lance mon jeu de morpion de dimension 3*3, avec 3 jetons à aligner pour gagner avec le mode humain contre humain.
    - En aucun cas, le jeu demande les dimensions souhaitées
    - La partie de déroule "normalement", en cliquant dans les cases voulue.
    - J'ai défini plusieurs boutons que je peux activer en cliquant de dessus ou alors en saisissant au clavier une lettre : annuler le dernier coup, nouvelle partie, aide, modifier mode de jeu (humain-humain, ou humain-ordi, ou ordi-ordi), modification des dimensions (largeur, hauteur, nombre de jetons à aligner).
    - J'ai deux boucles : la principale pour quitter le jeu (si on a cliqué sur la croix, ou echap, ou bouton quitter), une secondaire pour recommencer une partie (partie finie, ou bouton nouvelle partie).
    - Lorsque je clique sur le bouton ModifierLesDimensions, cela m’ouvre une nouvelle page dans laquelle je peux modifier les dimensions. Pour sortir de cette page, soit je clique Annuler (je conserve les anciennes données), soit je clique Valider (et là, il faut que je recommence avec une nouvelle partie).
    Je t'avais écris que "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."
    En fait je pensais que si je passais d'un "grand" tableau 5*6 à un "petit" tableau 3*4 par exemple (donc plus petit), les valeurs "en trop" n'étais pas libérées c'est pour cela que je vidais avec les anciennes dimensions (l29), puis je redéfinissais mon tableau et pour être sûr qu'il soit bien vide, je refaisais un vidage avec les nouvelles dimensions.
    - Comment me conseilles- tu de procéder ?


    Pour les erreurs de fichiers, je sais que ma méthode n'est pas correcte car il y a des exit à plusieurs endroits, mais je ne sais pas comment faire et je ne me sis aps vraiment penché sur la question :
    - Est-ce que je dois rajouter un pointeur Erreur et le passer à chaque fonction qui peut le modifier, et mettre un test du style "si erreur= non, alors ... sinon sortir de la fonction",
    - Faut-il que je je fasse une liste de code d'erreurs erreur_1 (erreur initialisation de cran), erreur_2(erreur initialisation de sdl), erreur_3(erreur initialisation de police),... et traiter les cas avec un switch : si erreur_1 alors libère écran, si erreur_2 alors libère écran+sdl, si erreur_3 alors libère écran+sdl+police,...
    Avec la 20aine d'images que j'ai plus les tableaux, cela me fais beaucoup de cas a envisager.
    - je suis entièrement d'accord avec mon étourderie de la ligne 15 (si malloc() échoue alors c'est idiot de faire un free())

    Merci beaucoup
    Ludovic

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par chamludo Voir le message
    - En aucun cas, le jeu demande les dimensions souhaitées
    ...
    - Lorsque je clique sur le bouton ModifierLesDimensions, cela m’ouvre une nouvelle page dans laquelle je peux modifier les dimensions. Pour sortir de cette page, soit je clique Annuler (je conserve les anciennes données), soit je clique Valider (et là, il faut que je recommence avec une nouvelle partie).
    Ca me semble pas mal. Imagine alors une fonction qui a pour seul but d'allouer tout le jeu en n * n. Cette fonction pourrait être appelée en début de partie pour allouer en 3*3. Ensuite, si ton joueur clique sur "modifier les dimensions" ça alloue le jeu en n * n.
    Et quand la partie est finie, ça libère le jeu avant d'offir au joueur la possibilité de rejouer (donc d'allouer de nouveau en 3*3). Reste à savoir si le joueur peut modifier les dimensions en cours de partie (ce qui obligerait à libérer le jeu avant la fin naturelle) mais même ça ça peut se régler si par exemple tu préviens le joueur que le redimensionnement entrainera l'annulation de la partie en cours. Donc quand le jeu est redimensionné, ça le libère (puisque le redimensionnement en cours de partie suppose que le dimensionnement initial a été fait) puis ça appelle la fonction dont je te parle...

    Citation Envoyé par chamludo Voir le message
    Pour les erreurs de fichiers, je sais que ma méthode n'est pas correcte car il y a des exit à plusieurs endroits, mais je ne sais pas comment faire et je ne me sis pas vraiment penché sur la question :
    - Est-ce que je dois rajouter un pointeur Erreur et le passer à chaque fonction qui peut le modifier, et mettre un test du style "si erreur= non, alors ... sinon sortir de la fonction",
    - Faut-il que je je fasse une liste de code d'erreurs erreur_1 (erreur initialisation de cran), erreur_2(erreur initialisation de sdl), erreur_3(erreur initialisation de police),... et traiter les cas avec un switch : si erreur_1 alors libère écran, si erreur_2 alors libère écran+sdl, si erreur_3 alors libère écran+sdl+police,...
    Avec la 20aine d'images que j'ai plus les tableaux, cela me fais beaucoup de cas a envisager.
    Ouais, là je sais pas trop quoi dire; C'est vrai que la gestion d'erreurs en C n'est pas évidente. Pour l'instant on peut laisser ça de côté et présumer que tout marche ; et rajouter la gestion des erreurs plus tard...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2019
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 59
    Par défaut
    Bonjour,
    je te poste la totalité de mon main afin que tu puisses bien voir la logique que j'avais : (aucune modification effectuée depuis le début de notre discussion)

    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
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>//pour les nombres aleatoires
    #include <SDL/SDL.h>// pour utiliser la sdl
    #include <SDL/SDL_image.h>// pour coller autre que des bmp
    #include <SDL/SDL_ttf.h>
     
    #include "Define.h"//Il est deja dans Main.h
    //#include "Main.h"
    #include "Jeu.h"
    #include "Affichage.h"//et pas #include "Jeu.h"
    #include "Init.h"
    #include "Aide.h"
    #include "ia.h"
     
    /*
    Reste a faire :
     
     
     
    3. créer code erreur : 10001 : pour chaque chargement. Puis boucle : si erreur = 00000 (pas erreur) alors jeu, sinon (chaque est une erreur)
    selon chiffre 1 ou 0 liberation de tel ou tel tableu ou autre
     
     
    5. Etudier les symetries et rotations pour limiter les recherches?
     
    4. bouton tournoi :
    a. afficher la ligne de titre
    b. afficher les lignes suivantes
    c. modification et zones de clic, definir des zones ?
     
     
    6. augmenter le nombre de joueurs?
     
    7. Integrer le son
     
    On peut remplacer tous les "ecran" par SDL_GetVideoSurface et éviter de passer "ecran" en parametre.
     
    */
     
     
    //on doit fournir "&Jeton" et modifier "*Jeton" pour modifier le pointeur dans la fonction
     
    int main(int argc, char **argv)
    {
        SDL_Event event;//pour gérer les évenements souris et clavier
        SDL_Surface *ecran=NULL;
        TTF_Font *police = NULL;//police d'ecriture
        int JeuFini = NON;//[NON : on continue][OUI : on arrête le jeu], pour la boucle de jeu
        int PartieFinie = NON;//[NON :on continue la partie][OUI : on vide le jeu et recommence une nouvelle partie]
        int N=3;
        int M=3;
        int NbJetonsAAligner=3;
        int AncienN=N;
        int AncienM=M;
        int AncienNbJetonsAAligner=NbJetonsAAligner;//on aligne 3 jetons au depart
        int PlateauJeuLarg=PlateauLarg;//Dimension reelle de la zone de jeu quand on personnalise les dimensions
        int PlateauJeuHaut=PlateauHaut;
        Case *plateau;
        Info InfoZoneDeRecherche= {0, N, M,0, N, M};
        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;
        Images Jeton = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //On initialise toutes les images à NULL
        int ClicX=0;
        int ClicY=0;
        int posX=0;
        int posY=0;
        int SourisCachee=NON;//[NON : Souris visible][OUI : Souris cachée]
        int NbAlignements=0;//Compte le nombre d'alignements gagnants
     
        jeu TypeJeu=HH;//HH, HO, OH, OO; puis rajouter N si 3 jetons ou plus
        Joueur ListeJoueurs[2]= {{H, Rond}, {H, Croix}};//2 joueurs humains pur commencer puis on changera en appuyant sur le bouton Config
        Joueur joueurEnCours=ListeJoueurs[0];//il faut trouver un moyen de modifier la liste des joueur lorsque l'on modifie la config
        int ConfigModifiee=NON;//[NON : ne pas actualiser si echap lors de ConfigDim][OUI : actualiser les tableaux lors de ConfigDim]
    // int NumMatch=0;//indique le numero du match que l'on est en train de jouer
    //char numMatch[2]="";//pour afficher les numéros du texte en chaine de caracteres
        zone ZoneEvenement = MARGE;
     
        //  MancheTournoi MancheInitiale= {11,{H, Rond}, {H, Croix},3,3,3}; //tournoi de 10 manches au maximum
        MancheTournoi Tournoi[10];/*=
        {
            {1,{H, Rond}, {H, Croix},3,3,3},
            {2,{H, Rond}, {H, Croix},3,3,3},
            {3,{H, Rond}, {H, Croix},3,3,3},
            {4,{H, Rond}, {H, Croix},3,3,3},
            {5,{H, Rond}, {H, Croix},3,3,3},
            {6,{H, Rond}, {H, Croix},3,3,3},
            {7,{H, Rond}, {H, Croix},3,3,3},
            {8,{H, Rond}, {H, Croix},3,3,3},
            {9,{H, Rond}, {H, Croix},3,3,3},
            {10,{H,Rond}, {H, Croix},3,3,3}
        };*///tournoi de 10 manches au maximum
        int MaxMancheTournoi=10;
        InitTournoi(Tournoi,  &MaxMancheTournoi);
     
        /**********************/ //debut du programme
     
        initSDL(&ecran);
     
        SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);//ignore tous les clics. A reactiver apres le titre avec SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
     
        police = TTF_OpenFont("times.ttf", 30);//chargement de la police d'ecriture et de la taille
        if(police==NULL)//si erreur d'allocation de police
        {
            fprintf(stderr, "Erreur de chargement de la police: %s\n", SDL_GetError());
            exit(EXIT_FAILURE);//quitter le programme
        }
     
        plateau=malloc(N*M*sizeof(*plateau));//Ce tableau doit etre dynamique
        if(plateau==NULL)//si erreur d'allocation
        {
            free(plateau);//liberation de la 1ere dimension
            fprintf(stderr, "Erreur de creation tableau plateau: %s\n", SDL_GetError());
            exit(EXIT_FAILURE);//quitter le programme
        }
     
        if(ChargementImages(&Jeton)==NON)//Si l'initialisation retourne faux
        {
            fprintf(stderr, "Problème pour charger les images : %s\n", SDL_GetError());//Si l'initialisation de la SDL a échoué, on retourne faux
            exit(EXIT_FAILURE);//quitter le programme
        }//alors, nous sortons de la fonction main et mettons fin au programme.
     
        SDL_ShowCursor(SDL_DISABLE);//on cache le pointeur de la souris
        SourisCachee=OUI;//la souris est cachée
     
        AfficheTitre(ecran);//Affiche le titre du jeu sur fond marron
        AfficheBoutons(ecran, police, &Jeton,  TypeJeu, EcranJeu);
     
        SDL_Delay(1000);//attend 1000ms = 1 seconde avant de passer a la suite
     
        srand(time(NULL)*1000); //
     
        PlateauJeuLarg=PlateauLarg/maximumEntre(N, M)*N;//Dimension reelle de la zone de jeu
        PlateauJeuHaut=PlateauHaut/maximumEntre(N, M)*M;
     
        while(JeuFini==NON)//Maintenant que l'initialisation est valide, on entre dans la boucle de jeu
        {
            videJeu(plateau, N, M, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu
            AfficheJeu(ecran, plateau, N, M, &Jeton);//affiche le jeu vide
            AfficheBoutons(ecran, police, &Jeton,  TypeJeu, EcranJeu);
     
            SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);//reactive les clics
     
            while(PartieFinie==NON)
            {
                if(joueurEnCours.joueur==O)//Si c'est a l'ordi de jouer
                {
                    DefinirZoneEtendue(&InfoZoneDeRecherche, N, M, &NbCasesJouees, NbJetonsAAligner, HistoriqueJeton);//determine la zone a etudier
                    DefinirListeCaseVide(&InfoZoneDeRecherche, N, M, &NbCasesJouees, HistoriqueJeton, /* HistoriqueJetonClasse, */ ListeCasesVides);//Détermine la TableauCaseVide
                    OrdiJoue(plateau, N, M,&InfoZoneDeRecherche, ListeJoueurs, &NbCasesJouees, &PartieFinie, NbJetonsAAligner, HistoriqueJeton, ListeCasesVides);
                    if(NbCasesJouees>=2*NbJetonsAAligner-1)//on verifie s'il y a alignement au bout du 5eme jeton rond posé, (Jouées = 3*o+2*x)
                    {
                        verifFini(plateau, N, M, HistoriqueJeton[NbCasesJouees-1], ListeJoueurs, &PartieFinie, &NbCasesJouees, NbJetonsAAligner, &NbAlignements); //Fonction pour vérifier si la partie est terminée
                    }
                    AfficheJeu(ecran, plateau, N, M, &Jeton);
                    joueurEnCours= ListeJoueurs[NbCasesJouees%2];//joueur suivant
                    SDL_Delay(500);
                }
     
                while(SDL_PollEvent(&event))//Traiter les évènements
                {
                    switch(event.type)
                    {
                    case SDL_QUIT://Si on a cliqué sur la croix
                        ZoneEvenement=QUITTER;
                        break;
                    case SDL_KEYUP://Si touche du clavier enfoncée
                        switch (event.key.keysym.sym)//selon la touche enfoncée
                        {
                        case SDLK_ESCAPE: // Appui sur la touche Echap, on va arrêter le jeu
                        case SDLK_a: // Appui sur la touche q (Attention a<->q avec les claviers qwerty-azerty), on va arrêter le jeu
                            ZoneEvenement=QUITTER;
                            break;
                        case SDLK_q: // Appui sur la touche a (Attention a<->q avec les claviers qwerty-azerty), on va annuler le dernier coup
                            ZoneEvenement=ANNULER;
                            break;
                        case SDLK_n: //si on presse le n de nouveau
                            ZoneEvenement=NOUVEAU;
                            break;
                        case SDLK_t: //si on presse le t de Tournoi
                            ZoneEvenement=TOURNOI;
                            break;
                        case SDLK_i: //si on presse le i de aIde
                            ZoneEvenement=AIDE;
                            break;
                        case SDLK_v: //si on presse le v de Valider
                            ZoneEvenement=VALIDER;
                            break;
                        case SDLK_d: //si on presse le d de configDim
                            ZoneEvenement=CONFIGDIMENSION;
                            break;
                        default ://sinon rien pour eviter message d'alerte lors de la compilation
                            break;
                        }
                        break;
                    case SDL_MOUSEMOTION://Si souris déplacée
                        posX=event.motion.x;
                        posY=event.motion.y;
                        GestionPointeur(posX, posY, &SourisCachee, ecran, plateau, PlateauJeuLarg, PlateauJeuHaut, N, M, &Jeton, ListeJoueurs, &joueurEnCours, &NbCasesJouees); //Fonction pour gerer l'affichage du pointeur
                        break;
                    case SDL_MOUSEBUTTONUP://Si clic souris
                        ClicX=event.button.x;
                        ClicY=event.button.y;
                        ZoneEvenement = QuelleZoneCliquee(ClicX, ClicY,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours);
                        break;
                    default: //Sinon on ne fait rien
                        break;
                    }
     
                    switch(ZoneEvenement)
                    {
                    case JEU :
                        HumainJoue(ClicX, ClicY, plateau, N, M, ListeJoueurs, &NbCasesJouees, HistoriqueJeton);//gestion du clic souris
                        if(NbCasesJouees>=2*NbJetonsAAligner-1)//on verifie s'il y a alignement au bout du 5eme jeton rond posé, (Jouées = 3*o+2*x)
                        {
                            verifFini(plateau, N, M, HistoriqueJeton[NbCasesJouees-1], ListeJoueurs, &PartieFinie, &NbCasesJouees, NbJetonsAAligner, &NbAlignements); //Fonction pour vérifier si la partie est terminée
                        }
                        AfficheJeu(ecran, plateau, N, M, &Jeton);
                        AffichePointeur(ecran, &Jeton, ListeJoueurs, &joueurEnCours, &NbCasesJouees, ClicX, ClicY);//pour afficher le pointeur quand on clique et que l'on ne bouge pas
                        ZoneEvenement=MARGE;
                        break;
                    case NOUVEAU:
                        videJeu(plateau, N, M, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);
                        PartieFinie=OUI;//On met PartieFinie a OUI pour quitter la boucle secondaire*/
                        ZoneEvenement=MARGE;
                        break;
                    case ANNULER:
                        if(ListeJoueurs[(NbCasesJouees-1)%2].joueur==O)//si le joueur precedent est l'ordi, alors il faut annuler 2 jetons
                        {
                            AnnulerCoup(plateau, ListeJoueurs, &joueurEnCours, &NbCasesJouees, HistoriqueJeton);//on annule le coup supplementaire
                        }
                        AnnulerCoup(plateau, ListeJoueurs, &joueurEnCours, &NbCasesJouees, HistoriqueJeton);//on annule le coup obligatoire et on actualise le joueurEnCours
                        AfficheJeu(ecran, plateau, N, M, &Jeton);//on affiche la modification
                        AffichePointeur(ecran, &Jeton, ListeJoueurs, &joueurEnCours, &NbCasesJouees, posX, posY);//pour afficher le pointeur quand on clique et que l'on ne bouge pas
                        AfficheBoutons(ecran, police, &Jeton,  TypeJeu, EcranJeu);
                        ZoneEvenement=MARGE;//pour eviter de boucler et de renouveller ANNULER
                        break;
                    case CONFIGTYPE:
                        TypeJeu=ConfigType(ecran, TypeJeu, &Jeton, ClicX-BoutonX, ClicY-BoutonYConfigType, ListeJoueurs/*, 2*/);//Les coordonnéees envoyées sont relatives au coin superieur gauche du bouton Config
                        joueurEnCours=ListeJoueurs[NbCasesJouees%2];//il faut actualiser le joueurEnCours
                        ZoneEvenement=MARGE;
                        break;
                    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 AVANT 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 APRES 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;*/
     
                            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;
     
                        }
                        AfficheJeu(ecran, plateau, N, M, &Jeton);
                        AfficheBoutons(ecran, police, &Jeton,  TypeJeu, EcranJeu);
                        ZoneEvenement=MARGE;
                        break;
                    case TOURNOI:
                        DetermineTournoi(ecran, police, &Jeton, TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours, Tournoi,10, &MaxMancheTournoi);//determine els composante du tournoi
                        AfficheJeu(ecran, plateau, N, M, &Jeton);
                        AfficheBoutons(ecran, police, &Jeton,  TypeJeu, EcranJeu);
                        ZoneEvenement=MARGE;
                        break;
                    case AIDE:
                        Aide(ecran, police, &Jeton,TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours);//on ouvre le menu d'aide
                        AfficheJeu(ecran, plateau, N, M, &Jeton);
                        ZoneEvenement=MARGE;//pour eviter de boucler su le menu AIDE
                        break;
                    case QUITTER:
                        JeuFini=OUI; //On met JeuFini a OUI pour quitter la 1ere boucle principale
                        PartieFinie=OUI;//On met PartieFinie a OUI pour quitter la 2eme boucle principale
                        ZoneEvenement=MARGE;
                        break;
                    case MARGE:
                        break;
                    default: //Sinon on ne fait rien
                        break;
                    }
                }
                SDL_Flip(ecran);//Rafraichissement de l'écran. Il faut le sortir du while car sinon il attend de bouger la souris pour faire jouer le joueur suivant
            }
            SDL_Delay(1000);//Attendre avant de fermer ou de commencer une nouvelle partie : 1000 ms = 1 s
        }
     
        free(ecran);//liberation de lecran
        free(plateau);//liberation du plateau de jeu
        plateau=NULL;
        free(HistoriqueJeton);
        HistoriqueJeton=NULL;
        free(ListeCasesVides);
        ListeCasesVides=NULL;
     
        LiberationImages(&Jeton);
        TTF_CloseFont(police); // Fermeture de la police, doit être fermée avant TTF_Quit()
        TTF_Quit();
        SDL_Quit();
     
        return EXIT_SUCCESS;//on quitte le jeu avec succes
    }
    Nom : aa-01.png
Affichages : 1711
Taille : 28,6 Ko
    Nom : aa-02.png
Affichages : 1653
Taille : 32,9 Ko
    Ainsi que 2 images pour illustrer.
    Mon but étais de remplacer la partie entre les lignes 250 à 278 par la ligne 279. Au départ je les avais incluses dans ma fonction ConfigDimension, mais cela ne fonctionnait pas. Surtout lorsque je n'enregistre pas les modifications pas de problème, mais si je valide les modification, alors de dois ajouter plein de variables (ecran, police, &Jeton, TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours, Tournoi,10, &MaxMancheTournoi).
    C'est pour cela que je voulais faire une fonction qui valide les modification : fonction ModificationConfigDimension.
    C'est cette fonction qui beugue dont j'ai parlé dans mon 1er message.

    De plus, le bouton Tournoi n'est pas encore opérationnel car lorsque je clique dessus, cela m'ouvre un nouvel écran.
    Mon but est de pouvoir choisir au maximum 10 parties avec le mode que je veux (humain-humain, humain-ordi,...) avec les dimensions que je souhaite (3*3 puis 5*12,... avec le nombre de jetons à aligner variable, parfois 3 , parfois 5).

    Lorsque du me dis : "Imagine alors une fonction qui a pour seul but d'allouer tout le jeu en n * n. Cette fonction pourrait être appelée en début de partie pour allouer en 3*3. Ensuite, si ton joueur clique sur "modifier les dimensions" ça alloue le jeu en n * n."
    Est-ce que tu me conseilles d'inclure les lignes 110-116 dans ma fonction videJeu (ligne 139) ? N'est-ce pas gênant de réallouer à chaque nouvelle partie même lorsque cela est inutile ? Moi je ne pensais le faire que lorsque les dimensions étaient modifiées.

    Dans ton 1er message tu me parlais de structures. Est-ce que tu me conseilles de passer largeur N, hauteur M et peut-être NbjetonsAAligner comme une seule structure ? J'y avais pensé car N et M sont toujours ensemble, et parfois NbJetonsAAligner, donc autant les séparer. Cela me fait juste un peu peur de changer tous mes N et M par une structure car j'en ai énormément.
    Ensuite je pourrais regrouper HistoriqueJeton et ListeCasesVides car l'un est le complément de l'autre.



    Pour la gestion des erreurs, je pensais rajouter un else aux lignes 109-119-123, sachant que dans la fonction ChargementImages, j'ai 23 images à charger. Et à rajouter les free correspondant
    Dans la fonction initSDL (ligne 99), j'initialise SDL_INIT_VIDEO, ecran et TTF_Init.
    Si je gère toutes erreurs de chargements, je vais avoir une indentation de fou. C'est pour cela que je voulais le faire à la fin du jeu.

    Ou alors j'initalise une variable Erreur à 0.
    Remplacer la ligne 107 par Erreur =1.
    Remplacrer la ligne 107 par Erreur = 2 ou Erreur=Erreur+10
    Remplacrer la ligne 107 par Erreur =3 ou Erreur=Erreur+100. car ces initialisations sont indépendantes les unes des autres.
    Avant de lancer le jeu ligne 137 , Erreur vaut 0 ou 10 ou 11 ou 100 ou 110 ou 101 ou 111 selon les erreurs rencontrées.
    Puis un petit si Erreur ==0 alors lancer le jeu sinon (si chiffre des unités =0 alors bonne initialisation de la line103 et free(), si chiffre des dizaines, ...si chiffres des centaines, ...)
    Sauf que si j'ai trop d'initialisation, mon Erreur sera trop long.

    Ou créer un tableau listant toutes les erreurs possibles et cocher celle qui ont eu lieu. Puis faire free() selon les erreurs rencontrées



    Toujours est-il que je n'arrive pas à remplacer les lignes 250 à 278 par la ligne 279 et c'est cela mon problème principal.
    Merci
    Ludovic

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par chamludo Voir le message
    je te poste la totalité de mon main afin que tu puisses bien voir la logique que j'avais : (aucune modification effectuée depuis le début de notre discussion)
    Oui, je l'ai lu. J'ai même tenté de le compiler (j'ai installé SDL pour ça, sisi je t'assure, mais t'inquiète pas, je l'ai fait sur une machine virtuelle dont le disque système est immuable => au prochain reboot ma machine sera comme neuve) mais il manque les "Define.h" et autres. Donc je ne peux que faire une analyse succinte. Et le souci c'est que ta logique me parait correcte(nettoyage du jeu avant modification, même si c'est inutile ça doit fonctionner ; puis allocation de nouvelles dimensions là aussi ça doit fonctionner, puis nettoyage du jeu après modification là aussi ça doit fonctionner).
    Peut-être me montrer ConfigDimension et videJeu (ou carrément tout le projet complet)...

    Citation Envoyé par chamludo Voir le message
    Lorsque du me dis : "Imagine alors une fonction qui a pour seul but d'allouer tout le jeu en n * n. Cette fonction pourrait être appelée en début de partie pour allouer en 3*3. Ensuite, si ton joueur clique sur "modifier les dimensions" ça alloue le jeu en n * n."
    Est-ce que tu me conseilles d'inclure les lignes 110-116 dans ma fonction videJeu (ligne 139) ?
    Maintenant que je vois ton source non. Tu alloues au début du projet, tu libères à la fin la logique est bonne. Et même si au milieu tu fais un free+malloc la logique reste bonne. Ce que je proposais était une autre façon de voir qui me correspond plus et qui était plus du style "je rapproche le plus possible les ouvertures/fermetures du travail qui en dépend"

    Citation Envoyé par chamludo Voir le message
    N'est-ce pas gênant de réallouer à chaque nouvelle partie même lorsque cela est inutile ? Moi je ne pensais le faire que lorsque les dimensions étaient modifiées.
    Perso j'essaye toujours de penser "petites fonctions toutes simples utilisables de partout", un peu comme un atome qu'on peut combiner à un autre pour former une molécule ou du "diviser pour régner".
    C'est vrai que si ton truc tournait 100000 fois par secondes, alors mettre dans le bouzin "allocation+travail+libération" effectivement ça ne serait pas optimisé. Mais pour une partie dont la durée se compte en secondes (minutes ?), ce n'est pas une allocation (même inutile) au début de la partie puis une libération à la fin qui va vraiment se faire sentir.
    Et puis plus tard, dans un second temps, rien n'interdit de modifier ta fonction qui alloue en n * n pour qu'elle teste si la nouvelle dimension est différente de l'ancienne et dans ce cas ne rien faire (ou même ne pas l'appeler)...

    Citation Envoyé par chamludo Voir le message
    Dans ton 1er message tu me parlais de structures. Est-ce que tu me conseilles de passer largeur N, hauteur M et peut-être NbjetonsAAligner comme une seule structure ? J'y avais pensé car N et M sont toujours ensemble, et parfois NbJetonsAAligner, donc autant les séparer. Cela me fait juste un peu peur de changer tous mes N et M par une structure car j'en ai énormément.
    Ensuite je pourrais regrouper HistoriqueJeton et ListeCasesVides car l'un est le complément de l'autre.
    Hé oui. Principe des fondations. C'est vrai que tu as énormément de variables (joueuEnCours, partieFinie, typeJeu, EcranJeu, etc etc etc) et que ça n'aide pas à faire évoluer. Est-ce que par exemple certaines variables ne pourraient pas être calculées ? Oui ça va peut-être à contresens où justement on mémorise un résultat dans une variable pour ne pas avoir à le recalculer justement mais parfois il faut essayer de "sentir" quand une variable est nécessaire et quand el;e ne l'est pas. Si par exemple je devais faire une boucle et traiter strlen(s) dans la boucle, il est certain que j'utiliserais une variable pour mémoriser strlen(s) pour ne pas avoir à la recalculer dans la boucle. Mais mettre une variable pour mémoriser un truc calculable dont tu va te servir une fois de temps en temps ça a l'effet inverse: ça complexifie sans aider vraiment. Je sais plus qui sur ce forum a une signature qui dit "une variable en moins c'est un bug en moins".

    Bon, on va continuer. de tenter de t'aider Il me faudrait maintenant voir videJeu()...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. [XL-2010] Redimensionnement d'un tableau dynamique et perte de données VBA
    Par awa123 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 11/08/2014, 22h54
  2. [Free Pascal] Redimensionner un tableau dynamique en un tableau statique
    Par tekthoninks dans le forum Free Pascal
    Réponses: 5
    Dernier message: 22/03/2009, 22h38
  3. Réponses: 1
    Dernier message: 03/05/2007, 08h15
  4. Redimensionner un tableau dynamique
    Par WebPac dans le forum Delphi
    Réponses: 6
    Dernier message: 18/01/2007, 16h23
  5. Comment redimensionner un tableau dynamique ?
    Par Mickey.jet dans le forum Langage
    Réponses: 13
    Dernier message: 07/09/2006, 18h16

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