Jeu du morpion (fonction détection)

Jeu du morpion (fonction détection) - C - Programmation

Marsh Posté le 29-09-2011 à 19:59:30    

Bonjour, ou bonsoir celà dépend bien évidement de l'heure à laquelle vous allez lire ce topic et/ou de l'endroit où vous vous situez !
 
Donc comme dit dans le titre mon problème concerne donc un jeu du morpion, je vais donc vous en dire un peu plus:
 
Ce jeu donc se déroule sur un tableau 11x11 où les joueurs doivent aligner 5 pion (ou chiffre puisque nous sommes dans une application console).
Etant débutant en C j'ai tout de même réussi à afficher le tableau et à faire jouer les 2 joueurs.
 
Pour le joueur 1 c'est donc un 1 qui s'affiche lorsqu'il entre les coordonnées où il souhaite jouer, pour le joueur 2 ce sera un 3.
Il me reste donc la fonction, je dirais la plus difficile à coder, celle de la détection d'un suite de 5 "pion".
 
Ce n'est pas un code tout cracher que j'attend (quoique je ne le refuserais pas) mais plutot une piste pour pouvoir orienté mes recherche, le temp m'etant compté. L'idée serait de parcourir le tableau (à l'aide d'un pointeur je suppose) pour détecter une suite de 5 "pion" et ensuite en changer la couleur (ou le chiffre dans notre cas)... enfin voilà
 
Je vous laisse quand même un aperçu de mon code, soyez aimable je suis débutant :)
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(int argc, char *argv[])
  4. {
  5. /* DEBUT */
  6. int NCASE = 11;
  7. int i,j;
  8. int tab[NCASE][NCASE];
  9. int x_j1=0;
  10. int y_j1=0;
  11. int x_j2=0;
  12. int y_j2=0;
  13. int k=0;
  14. for (i=0; i<NCASE; i++) {                /*Affichage*/
  15.     for (j=0; j<NCASE; j++) {
  16.         tab[i][j] = 0;
  17. }
  18. }
  19. i=0;
  20. int p=0;
  21. while (k<NCASE){
  22.           printf("     0  1  2  3  4  5  6  7  8  9  10\n\n" ); /*Affichage des coordonnées utile pour que le joueurs tappe les coordonées */
  23. for (i=0; i<NCASE; i++) {
  24. if (i<10){
  25. printf("%d%d | ", p, i);
  26. } else {
  27. printf("%d | ", i);}
  28.                                             /*Affichage*/
  29.     for (j=0; j<NCASE; j++) {               /*du*/
  30.         printf("%d |", tab[i][j]);            /*tableau*/
  31.      }
  32.     printf("\n" );
  33. }
  34.               /*Demande des coordonnées au joueur 1*/
  35.     printf("\nJoueur 1, veuillez entrez l'abscisse :\n" );
  36.     scanf("%d", &x_j1);
  37.     printf("\nJoueur 1, veuillez entrez l'ordonnee :\n" );
  38.     scanf("%d", &y_j1);
  39.     tab[x_j1][y_j1] = 1;
  40.  
  41.     k++;
  42.    
  43.    
  44.    
  45.    
  46.          /*Demande des coordonnées au joueur 1*/
  47.     printf("\nJoueur 2, veuillez entrez l'abscisse :\n" );
  48.     scanf("%d", &x_j2);
  49.     printf("\nJoueur 2, veuillez entrez l'ordonnee :\n" );
  50.     scanf("%d", &y_j2);
  51.     tab[x_j2][y_j2] = 3;
  52.  
  53.     k++;
  54. }
  55.   return EXIT_SUCCESS;
  56. }


 
 
Cordialement !

Reply

Marsh Posté le 29-09-2011 à 19:59:30   

Reply

Marsh Posté le 29-09-2011 à 20:38:29    

Salut,
 
L'algo intuitif pourrait être :  
 
Pour chaque case  
 
si la case est un pion d'un joueur quelconque  
 regarder horizontalement si les 4 suivantes ( si possible ) sont aussi de ce même joueur
 regarder verticalement si les 4 suivantes ( si possible ) sont aussi de ce même joueur
fin si
fin pour  
 
Ensuite, tu peux améliorer l'algo en ne faisant pas toutes les cases du tableau , mais en t'arrêtant 4 cases avant ( en effet, inutile de tester la 8ème case horizontalement puisqu'il n'en reste que 3 pour finir ).
 
On peut encore améliorer l'algo de recherche , mais ce n'est surement pas le but ici. ( ex : effectuer le test à chaque coup joué, non pas sur la totalité du tableau, mais à partir de la pièce jouée, car seule la pièce jouée déterminera la victoire ou non, en considérant que la fois précédente, il n'y a pas eu de victoire ).


Message édité par xilebo le 29-09-2011 à 20:40:50
Reply

Marsh Posté le 29-09-2011 à 20:46:12    

Merci mais au niveau de l'algo je prefere choisir la 1ere, c'est à dire parcourir tout le tableau parait que c'est facile.
Justement a-t-on forcement besoin de pointeurs?
 
Merci d'avance :)

Reply

Marsh Posté le 29-09-2011 à 20:59:54    

Tu peux travailler directement avec ton tableau , et le parcourir avec une double boucle ( comme tu le fais déjà pour l'initialiser ) .
 
Par contre, si tu veux faire une fonction pour effectuer ce test, il te faudra passer l'adresse du tableau ( du premier élément) en paramètre, que tu récupéreras dans un pointeur ( car passer le tableau entier en paramètre c'est mal :o ). Tu pourras travailler à partir du pointeur dans ce cas.

Reply

Marsh Posté le 30-09-2011 à 00:09:06    

Bonsoir,
j'avais fait un puissance 4 il y a quelques temps, le problème est similaire je pense . Voici la fonction de vérification tel que dans mon code:

Code :
  1. struct Case
  2. {
  3. int dg; // la case diagonale gauche : indique le nombre de pion de même couleur dans cette direction
  4. int vert; // verticale
  5. int dd; //diagonale droite
  6. int horz; // horizontale
  7. //  selon le schéma:
  8. //  horz      t[x][y]     
  9. //  dd          vert      dg
  10. };
  11. ...
  12. bool CPuissance4Dlg::check()
  13. /*
  14. Principe:
  15. Additioner le contenu de la case adjacente correcte (->meme couleur)
  16. au contenu de la case courante.
  17. */
  18. {
  19. Case game[NB_COLONNES][NB_LIGNES]; // tableau pour la vérification
  20.        // en variable de classe tableau[colonne][ligne]: le tableau de jeu, la valeur peut être 'FREE'= case non jouée ou  un nombre représentant une couleur
  21.         //initialisation
  22. for (int ligne = 0; ligne < NB_LIGNES ; ligne++)
  23. {
  24.  for (int colonne = 0; colonne < NB_COLONNES; colonne++)
  25.  {
  26.   /*
  27.   Par defaut il y a 1 pion sur 4 d'aligner correctement
  28.   */
  29.   game[colonne][ligne].horz=1;
  30.   game[colonne][ligne].vert=1;
  31.   game[colonne][ligne].dg=1;
  32.   game[colonne][ligne].dd=1;
  33.  }
  34. }
  35. // pour le horizontal
  36. for (int ligne = 0; ligne < NB_LIGNES ; ligne++)
  37. {
  38.  for (int colonne = 1; colonne < NB_COLONNES; colonne++)
  39.  {
  40.   if ((tableau[colonne][ligne]==tableau[colonne-1][ligne])&&(tableau[colonne][ligne]!=FREE))
  41.    // meme couleur mais pas couleur libre
  42.   {
  43.    game[colonne][ligne].horz=game[colonne-1][ligne].horz+1;
  44.    if (game[colonne][ligne].horz==4) // si on arrive à compter jusqu'a 4, on a gagné (puissance 4)!
  45.     return true;
  46.   }
  47.  }
  48. }
  49. // pour le vertical
  50. for (int ligne = 1; ligne < NB_LIGNES ; ligne++)
  51. {
  52.  for (int colonne = 0; colonne < NB_COLONNES; colonne++)
  53.  {
  54.   if ((tableau[colonne][ligne]==tableau[colonne][ligne-1])&&(tableau[colonne][ligne]!=FREE))
  55.    // meme couleur
  56.   {
  57.    game[colonne][ligne].vert=game[colonne][ligne-1].vert+1;
  58.    if (game[colonne][ligne].vert==4)
  59.     return true;
  60.   }
  61.  }
  62. }
  63. // pour le diagonal gauche:de bas à gauche vers haut à droite
  64. for (int ligne = 1; ligne < NB_LIGNES ; ligne++)
  65. {
  66.  for (int colonne = 0; colonne < NB_COLONNES-1; colonne++)
  67.  {
  68.   if ((tableau[colonne][ligne]==tableau[colonne+1][ligne-1])&&(tableau[colonne][ligne]!=FREE))
  69.    // meme couleur
  70.   {
  71.    game[colonne][ligne].dg=game[colonne+1][ligne-1].dg+1;
  72.    if (game[colonne][ligne].dg==4)
  73.     return true;
  74.   }
  75.  }
  76. }
  77. // pour le diagonal droite:de haut à gauche vers bas à droite
  78. for (int ligne = 1; ligne < NB_LIGNES ; ligne++)
  79. {
  80.  for (int colonne = 1; colonne < NB_COLONNES; colonne++)
  81.  {
  82.   if ((tableau[colonne][ligne]==tableau[colonne-1][ligne-1])&&(tableau[colonne][ligne]!=FREE))
  83.    // meme couleur
  84.   {
  85.    game[colonne][ligne].dd=game[colonne-1][ligne-1].dd+1;
  86.    if (game[colonne][ligne].dd==4)
  87.     return true;
  88.   }
  89.  }
  90. }
  91. return false;
  92. }


Bon il est améliorable (sortir le nombre magique '4', et utiliser une variable par exemple! et sûrement plein d'autres choses...) mais tu auras une base de départ...


---------------
Seul Google le sait...
Reply

Marsh Posté le 30-09-2011 à 09:36:15    

Merci beaucoup je vais m'y mettre :)

Reply

Marsh Posté le 30-09-2011 à 22:53:24    

J'ai réussi et sans pointeur ! Je file le code si sa peut servir.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define NCASE 11
  4. int test_tableau(int tab[NCASE][NCASE]){
  5.     int i;
  6.     int j;
  7.     for(i=0; i<NCASE; i++){
  8.              for(j=0; j<NCASE; j++){
  9.                       if(tab[i][j]==0){
  10.                                        return 0;
  11.                                        }
  12.                                        
  13.                       }
  14.                       }
  15.                       return 1;
  16.                       }
  17. /* Détection horizontale d'une ligne de 5 pion */
  18. int horizontal(int table[NCASE][NCASE], int joueur){
  19.     int i;
  20.     int j;
  21.     int cpt=0;
  22.     for(i=0; i<NCASE; i++){
  23.              for(j=0; j<NCASE; j++){
  24.                       if(table[i][j]==joueur){
  25.                       cpt++;
  26.                      
  27.                       if(cpt==5){
  28.                                  if(joueur == 1){
  29.                                            table[i][j]=2;
  30.                                            table[i][j-1]=2;
  31.                                            table[i][j-2]=2;
  32.                                            table[i][j-3]=2;
  33.                                            table[i][j-4]=2;
  34.                                            }
  35.                                            else{
  36.                                            table[i][j]=4;
  37.                                            table[i][j-1]=4;
  38.                                            table[i][j-2]=4;
  39.                                            table[i][j-3]=4;
  40.                                            table[i][j-4]=4;
  41.                                            }
  42.                                            printf("Vous avez gagner\n" );
  43.                       return 1;}
  44.                      
  45.                       }
  46.                       else{
  47.                       cpt=0;}
  48.                           }
  49.                            }
  50.                            return 0;
  51.                                                  
  52. }
  53. /* Détection verticale d'une ligne de 5 pion */
  54. int vertical(int table[NCASE][NCASE], int joueur){
  55.     int i;
  56.     int j;
  57.     int cpt=0;
  58.     for(i=0; i<NCASE; i++){
  59.              for(j=0; j<NCASE; j++){
  60.                       if(cpt==5){
  61.                       if(table[j][i]==joueur){
  62.                       cpt++;
  63.                       if(joueur == 1){
  64.                                            table[j][i]=2;
  65.                                            table[j-1][i]=2;
  66.                                            table[j-2][i]=2;
  67.                                            table[j-3][i]=2;
  68.                                            table[j-4][i]=2;
  69.                                            }
  70.                                            else{
  71.                                            table[j][i]=4;
  72.                                            table[j-1][i]=4;
  73.                                            table[j-2][i]=4;
  74.                                            table[j-3][i]=4;
  75.                                            table[j-4][i]=4;
  76.                                            }
  77.                       printf("Félicitation ! Joueur 1, vous avez reussi a aligner 5 pions\n" );
  78.                       return 1;}
  79.                       }
  80.                       else{
  81.                       cpt=0;}
  82.                           }
  83.                            }
  84.                            return 0;
  85. }
  86. /* Détection diagonale d'une ligne de 5 pion */
  87. int diagonal(int table[NCASE][NCASE], int joueur){
  88.     int i;
  89.     int j;
  90.     for(i=0; i<NCASE; i++){
  91.              for(j=0; j<NCASE; j++){
  92.                       if((table[i][j]==joueur) && (table[i+1][j+1]) && (table[i+2][j+2]) && (table[i+3][j+3]) && (table[i+4][i+4])){
  93.                                                if(joueur == 1){
  94.                                            table[i][j]=2;
  95.                                            table[i-1][j-1]=2;
  96.                                            table[i-2][j-2]=2;
  97.                                            table[i-3][j-3]=2;
  98.                                            table[i-4][j-4]=2;
  99.                                            }
  100.                                            else{
  101.                                            table[i][j]=4;
  102.                                            table[i-1][j-1]=4;
  103.                                            table[i-2][j-2]=4;
  104.                                            table[i-3][j-3]=4;
  105.                                            table[i-4][j-4]=4;
  106.                                            }
  107.                                              printf("Félicitation ! Joueur 1, vous avez reussi a aligner 5 pions\n" );
  108.                                              return 1;
  109.                                              }
  110.                                              }
  111.                                              }
  112. }
  113. int main(int argc, char *argv[])
  114. {
  115. /* DEBUT */
  116. int table_rempli;
  117. int var;
  118. int var2;
  119. int var3;
  120. int i,j;
  121. int tab[NCASE][NCASE];
  122. int x_j1=0;
  123. int y_j1=0;
  124. int x_j2=0;
  125. int y_j2=0;
  126. for (i=0; i<NCASE; i++) {                /*Affichage*/
  127.     for (j=0; j<NCASE; j++) {
  128.         tab[i][j] = 0;
  129. }
  130. }
  131. i=0;
  132. int p=0;
  133. while ((table_rempli = test_tableau(tab)) != 1){
  134.           printf("     0  1  2  3  4  5  6  7  8  9  10\n\n" ); /*Affichage des coordonnées utile pour que le joueurs tappe les coordonées */
  135. for (i=0; i<NCASE; i++) {
  136. if (i<10){
  137. printf("%d%d | ", p, i);
  138. } else {
  139. printf("%d | ", i);}
  140.                                             /*Affichage*/
  141.     for (j=0; j<NCASE; j++) {               /*du*/
  142.         printf("%d |", tab[i][j]);            /*tableau*/
  143.      }
  144.     printf("\n" );
  145. }
  146.               /*Demande des coordonnées au joueur 1*/
  147.     printf("\nJoueur 1, veuillez entrez l'abscisse :\n" );
  148.     scanf("%d", &x_j1);
  149.     printf("\nJoueur 1, veuillez entrez l'ordonnee :\n" );
  150.     scanf("%d", &y_j1);
  151.     tab[x_j1][y_j1] = 1;
  152.    
  153.     var = horizontal(tab, 1);
  154.     var2 = vertical(tab, 1);
  155.     var3 = diagonal(tab, 1);
  156.    
  157.    
  158.    
  159.          /*Demande des coordonnées au joueur 1*/
  160.     printf("\nJoueur 2, veuillez entrez l'abscisse :\n" );
  161.     scanf("%d", &x_j2);
  162.     printf("\nJoueur 2, veuillez entrez l'ordonnee :\n" );
  163.     scanf("%d", &y_j2);
  164.     tab[x_j2][y_j2] = 3;
  165.  
  166.    var= horizontal(tab, 3);
  167.    var2= vertical(tab, 3);
  168.    var3 = diagonal(tab, 3);
  169. }
  170.   return EXIT_SUCCESS;
  171. }

Reply

Marsh Posté le 01-10-2011 à 09:19:10    

Tu as juste oublié qu'il y a deux variétés de lignes diagonales possibles...
D'autre part, si tu vérifies pas i+4<NCASE et j+4<NCASE dans l'algo de ta diagonale, tu sors du tableau (et je ne parle pas de la faute de frappe qu'on y lit aussi)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed