Problème de detections de déplacement dans le jeu du taquin.

Résolu/Fermé
Naraka77 Messages postés 10 Date d'inscription jeudi 15 novembre 2012 Statut Membre Dernière intervention 9 janvier 2014 - 15 nov. 2012 à 18:49
Naraka77 Messages postés 10 Date d'inscription jeudi 15 novembre 2012 Statut Membre Dernière intervention 9 janvier 2014 - 16 nov. 2012 à 11:13
Bonjour,

J'ai, dans le cadre de mes études, un projet a réaliser qui consiste a créer le jeu du "Taquin".

Lors de la conception j'ai rencontré une erreur de segmentation que je n'arrives pas du tout a résoudre.

Je vais commencer par vous présenter la partie qui me fais perdre mes cheveux en ce moment :

- J'ai créer un tableau dynamique à deux dimensions (qui me sert de plateau de jeu) que j'ai remplis avec des nombres allant de 0 à la taille maximum du plateau -1 (si c'est un plateau 5*5 je le rempli donc de 0 à 24). Le "0" symbolisant le trou permettant le déplacement des pièces.

- Je veux ensuite, qu'une fonction parcourt ce tableau, et, lorsqu'elle a trouvée le 0 dans le plateau, elle me renvoie le nombre de déplacements possible (que j'afficherai par la suite.... si je m'en sors d'abord avec cette fonction). Mon problème est donc dans cette fonction. Celle-ci fonctionne très bien lorsque la case vide se trouve entourée de 4 cases non vide. Mais ! Lorsqu'elle se trouve sur le coté du plateau, c'est la catastrophe... Le programme bug. Je ne procède pourtant qu'a de simples vérifications (donc des if...).

Après ces quelques explications, je vous montre maintenant la fonction "detection" qui fais les tests sur les déplacements possibles :

int detection(int **plateau, int nb_ligne, int nb_colonne){
    int i, j, nb_deplacements = 4; /* 4 car dans le cas général, 4 déplacements sont possibles. */

    for(i = 0; i < nb_ligne; i++) {
        for(j = 0; j < nb_colonne; j++) {
            cout << "tab[" << i << "][" << j << "] = " << plateau[i][j] << endl;

            //cas en haut à gauche.
            if(plateau[i][j] == 0 && ( ( (j-1) < 0 ) && ( (i-1) < 0 ) ) ) { nb_deplacements--; }

            //cas sur le coté haut.
            else if(plateau[i][j] == 0 && ( ( (i-1) < 0 ) ) ) { nb_deplacements--; }

            //cas en haut à droite.
            else if(plateau[i][j] == 0 && ( ( (j+1) > (nb_colonne-1) ) && ( (i-1) < 0 ) ) ) { nb_deplacements--; }

            //cas sur le coté gauche.
            else if(plateau[i][j] == 0 && ( ( (j-1) < 0 ) ) ) { nb_deplacements--; }

            //cas sur le coté droit.
            else if(plateau[i][j] == 0 && ( ( (j+1) > (nb_colonne-1) ) ) ) { nb_deplacements--; }

            //cas en bas à gauche.
            else if(plateau[i][j] == 0 && ( ( (j-1) < 0 ) && ( (i+1) > (nb_ligne-1) ))  ) { nb_deplacements--; }

            //cas sur le coté bas.
            else if(plateau[i][j] == 0 && ( ( (i+1) < 0 ) ) ) { nb_deplacements--; }

            //cas en bas à droite.
            else if(plateau[i][j] == 0 && ( ( (j+1) > (nb_colonne-1) ) && ( (i+1) > (nb_ligne-1) ))  ) { nb_deplacements--; }

    return nb_deplacements;
}


Et je vous montre aussi, la manière dont j'ai crée le plateau de jeu :
void creer_plateau(int **plateau, int nb_ligne, int nb_colonne){
    int i, j;
    int tmp = 0, randval_i = 0, randval_j = 0;

    for (i = 0; i < nb_colonne; i++) plateau[i] = new int[nb_colonne];
    for(i = 0; i < nb_ligne; i++)
        for (j = 0; j < nb_colonne; j++) plateau[i][j] = i * nb_colonne + j;

    for(i = 0; i < nb_ligne; i++) {
        for(j = 0; j < nb_colonne; j++) {
            /* On choisit une i et une j aléatoirement */
            randval_i = rand() % nb_ligne;
            randval_j = rand() % nb_colonne;
            /* On permute */
            tmp = plateau[i][j];
            plateau[i][j] = plateau[randval_i][randval_j];
            plateau[randval_i][randval_j] = tmp;
        }
    }
}


J'aimerais, savoir pourquoi mes tests font planter le programme, s'il vous plait.

Je vous remercie d'avance.

Naraka,

A voir également:

1 réponse

Utilisateur anonyme
16 nov. 2012 à 08:48
Bonjour

Comment est définie et initialisée la variable plateau que tu passes à creer_plateau ? Je suis prêt à parier que c'est un simple int ** non initialisé. Dans ce cas, normal que ça plante dès que tu fais plateau[i]...
Si c'est bien ça, tu aurais dû le passer par référence et l'allouer dans creer_plateau. Je n'ai pas l'habitude du C++, je ne suis pas sûr de l'écriture du passage par référence ni de l'allocation d'un tableau d'int *, mais ça doit ressembler à :

void creer_plateau(int **&plateau, int nb_ligne, int nb_colonne){
int i, j;
int tmp = 0, randval_i = 0, randval_j = 0;
plateau=new int*[nb_colonne];
for (i = 0; i < nb_colonne; i++) plateau[i] = new int[nb_colonne];

De plus...

Dans l'initialisation de ton tableau, tu mélanges les indices :
for (i = 0; i < nb_colonne; i++) plateau[i] = new int[nb_colonne]; i est l'indice de colonne

for(i = 0; i < nb_ligne; i++)
for (j = 0; j < nb_colonne; j++) plateau[i][j] = i * nb_colonne + j;

i est devenu l'indice de ligne
Note que si ton plateau est carré, ça ne doit pas gêner.

Remarque sur ton calcul de nb_deplacements : il est faux, il n'y a que 2 déplacements dans les coins.
Il est inutilement compliqué : tu n'as pas besoin de variable nb_deplacements, il suffit de faire return 4, return 3 ou return 2 selon les cas ; ça évite les else qui alourdissent l'écriture. Personnellement, je n'aurais pas fait de fonction, mais initialisé un tableau du nombre de déplacements en même temps que le tableau initial, plus qu'à "piocher" dedans en cours de partie.
0
Naraka77 Messages postés 10 Date d'inscription jeudi 15 novembre 2012 Statut Membre Dernière intervention 9 janvier 2014
16 nov. 2012 à 11:13
Bonjour Le père,

Tout d'abord, merci d'avoir pris la peine de me répondre !

Ensuite, merci, il est claire que maintenant, le programme marche beaucoup mieux, du moins, il ne plante plus pour l'instant.

Pour ce qui est des déplacements, oui, j'avoue que je me suis un peux compliqué la vie, mais j'ai changé tellement de fois mon code, car je croyais que le problème venait de cette fonction, que j'en ai fais quelques erreurs du coup. Je vais donc prendre en considération ce que tu m'as dis.

Merci encore une fois !
0