Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1756 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Aide pour mon Puissance 4 ! =)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Aide pour mon Puissance 4 ! =)

n°1981031
passio
Posté le 06-04-2010 à 03:19:01  profilanswer
 

Bonsoir à tous, voilà je dois programmer un puissance 4 mais je ne sais comment parcourir le tableau de la bonne manière pour vérifier si la partie est gagnée  :??:  
J'avais l'idée de faire un truc du genre :
 

Code :
  1. if(grille[i][j] == grille[i+1]|j] == grille[i+2]|j] == grille[i+3]|j] && */si leur valeur != de 0/*)
  2. {
  3. //La partie est gagnée
  4. }


 
J'aurais fait pareil avec j, j+1, j+2...
 
Enfin, j'ai essayé mais dans la pratique ça marche 'peu'... Pour la vérification diagonale je n'en parle pas. Si quelqu'un pouvait m'aider en accord avec mon code je lui serais éternellement reconnaissant.
Merci.

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void afficherGrille(int grille[][7]);
  4. int modifierGrille(int choixColonne, int hauteurColonne[], int grille[][7], int tour);
  5. int menu();
  6. int definirJoueur(int tour);
  7. int verifierGagnant(int grille[][7]);
  8. int main()
  9. {
  10.     int grille[6][7] = {0};     //grille[i][j]
  11.     int hauteurColonne[7];
  12.     int i, j;
  13.     int choixColonne = 0;
  14.     int tour = 0;
  15.     for(i = 0; i!=7; i++)
  16.     {
  17.          hauteurColonne[i] = 5;
  18.     }
  19. while(1)
  20. {
  21.     tour = definirJoueur(tour);
  22.     afficherGrille(grille);
  23.     choixColonne = menu();
  24.     modifierGrille(choixColonne, hauteurColonne, grille, tour);
  25.     hauteurColonne[choixColonne]--;
  26.     verifierGagnant(grille);
  27. }
  28.     return 0;
  29. }
  30. int modifierGrille(int choixColonne, int hauteurColonne[], int grille[][7], int tour)
  31. {
  32.     int i;
  33.     int j;
  34.     for(i = 0; i!=6; i++)
  35.     {
  36.         for(j = 0; j!=7; j++)
  37.         {
  38.             if(choixColonne == j)
  39.             {
  40.                 if(tour)
  41.                 {
  42.                 grille[hauteurColonne[j]][j] = 1;
  43.                 }
  44.                 else
  45.                 {
  46.                     grille[hauteurColonne[j]][j] = 2;
  47.                 }
  48.             }
  49.         }
  50.     }
  51. }
  52. int menu()
  53. {
  54.     int choix;
  55.     printf("\nDans quelle colonne souhaitez vous placer un pion ?       " );
  56.     scanf("%ld", &choix);
  57.     if(choix > 7 || choix < 1)
  58.     {
  59.         return menu();
  60.     }
  61.     return choix-1;
  62. }
  63. void afficherGrille(int grille[][7])
  64. {
  65.     int i;
  66.     int j;
  67.     for(i = 0; i!=6; i++)
  68.     {
  69.         printf("                       " );
  70.         for(j = 0; j!=7; j++)
  71.         {
  72.             switch(grille[i][j]) {
  73.  case 1 :  printf("X" );
  74.      break;
  75.  case 2 :  printf("O" );
  76.      break ;
  77.  default : printf("." );
  78.      break ;
  79.     }
  80.         }
  81.         printf("\n" );
  82.     }
  83. }
  84. int definirJoueur(int tour)
  85. {
  86.     return (tour+1)%2;
  87. }
  88. int verifierGagnant(int grille[][7])
  89. {
  90.     int i;
  91.     int j;
  92.     for(i = 0; i<6; i++)
  93.     {
  94.         for(j = 0; j<7; j++)
  95.         {
  96.         }
  97.     }
  98.     printf("\n" );
  99. }


Message édité par passio le 06-04-2010 à 03:20:35
mood
Publicité
Posté le 06-04-2010 à 03:19:01  profilanswer
 

n°1981034
Turkleton
I don't quite understand you
Posté le 06-04-2010 à 07:33:28  profilanswer
 

Si tu as déjà abordé la récursivité en cours, tu peux t'inspirer de ce topic.
 
La vérification se fait par une fonction récursive qui s'incrémente à chaque pion de la même couleur aligné. Et pour le parcours, cette fonction prend en argument des indices (0, 1 ou -1) pour savoir dans quel sens se déplacer.
 
Bien entendu, si tu ne comprends pas mon code, ne l'utilise pas ! Mais si tu veux des précisions, pas de souci ;)


---------------
If you think it could look good, then I guess it should
n°1981138
passio
Posté le 06-04-2010 à 11:24:08  profilanswer
 

Euh, je fais pas de cours :(...

n°1981142
Turkleton
I don't quite understand you
Posté le 06-04-2010 à 11:35:19  profilanswer
 

passio a écrit :

Euh, je fais pas de cours :(...


Ha ok (c'était un bon sujet de TP pourtant :D)
 
Mais ça ne change rien au problème : t'es-tu penché sur la récursivité ? Si oui, essaye de comprendre la finalité du bout de code que j'ai mis dans l'autre topic (il y a sûrement bien d'autres manières de faire sinon).


---------------
If you think it could look good, then I guess it should
n°1981160
passio
Posté le 06-04-2010 à 12:13:39  profilanswer
 

Ah, et tu fais ce genre de TP dans quelle section ? =)
J'ai regardé la récursivité, je comprends pas vraiment :/.

n°1981161
Elmoricq
Modérateur
Posté le 06-04-2010 à 12:14:10  profilanswer
 

Faut comprendre la récursivité, pour comprendre la récursivité.

n°1981164
Turkleton
I don't quite understand you
Posté le 06-04-2010 à 12:21:04  profilanswer
 

passio a écrit :

J'ai regardé la récursivité, je comprends pas vraiment :/.


Le principe est simple : appeler une fonction à l'intérieur d'elle-même. Après, faut surtout appréhender le pourquoi du comment.
Mais dans ton puissance 4, c'est un moyen très efficace de voir si la partie est gagnée ou pas (y compris si ton plateau de jeu fait plusieurs milliers de cases, et qu'il faut aligner 35 pions pour gagner, ce qui un gros avantage). Mais après c'est effectivement peut-être pas le plus simple.
 

Elmoricq a écrit :

Faut comprendre la récursivité, pour comprendre la récursivité.


:D  
Une autre idée sur la façon de procéder sinon ?


---------------
If you think it could look good, then I guess it should
n°1981174
passio
Posté le 06-04-2010 à 12:58:50  profilanswer
 

C'est votre domaine, ou vous êtes des amateurs (et je m'inquiète).
 
Je n'ai pas d'autres idées...
Déjà l'approche de mon puissance 4 est assez difficile, en effet j'avais un bug que j'ai soumis à des programmeurs, qui n'ont rien compris à mon code. Maintenant il est un peu plus clair.
 
http://romintensity.free.fr/grille.pdf

n°1981210
passio
Posté le 06-04-2010 à 13:50:50  profilanswer
 

Idée :
 
int variable = 0;
while(!variable)
{
//code
}
 
Il faudrait pour la vérification horizontale :
Parcourir i(de 0 à 6) et j(de 0 à 4) dans grille[i][j] et variable est vrai si:
 
grille[i][j] == grille[i][j+1] == grille[i][j+2] == grille[i][j+3]
grille[i][j+3] <=6
 
Mais çia marche pas :'(

n°1981225
Turkleton
I don't quite understand you
Posté le 06-04-2010 à 14:15:00  profilanswer
 

passio a écrit :


grille[i][j] == grille[i][j+1] == grille[i][j+2] == grille[i][j+3]


Tu ne peux comparer les valeurs que deux à deux. Il faudrait écrire

Code :
  1. if (grille[i][j]==grille[i][j+1] && grille[i][j]==grille[i][j+2] && grille[i][j]==grille[i][j+3])


 
De plus, tu vas devoir écrire les tests pour toutes les directions. C'est possible mais fastidieux. Et encore, heureusement que ce n'est pas un "Puissance 25" sinon tes conditions vont prendre de la place ! ;)  
 
Tu devrais vraiment te pencher sur la récursivité, c'est un peu compliqué à comprendre de prime abord, mais c'est bien utile (voire même indispensable si tu veux vraiment te mettre à la programmation).


---------------
If you think it could look good, then I guess it should
mood
Publicité
Posté le 06-04-2010 à 14:15:00  profilanswer
 

n°1981239
mrbebert
Posté le 06-04-2010 à 14:37:01  profilanswer
 

Une autre approche, au lieu de rechercher une position gagnante n'importe où dans la grille, serait d'en rechercher une à partir de la position qui vient d'être jouée.
Tu définis une fonction qui prend en paramètre les coordonnées (x,y) de la position à partir de laquelle faire la recherche (qui sera la position qui vient d'être jouée) et qui :
- recherche dans les 8 directions possibles le nombre de pions de la même couleur qu'en (x,y)
(la recherche vers le haut devrait être plutôt triviale :D )
- additionne le nombre de pions trouvés dans les directions opposées (+1 pour la position courante) et renvoie la taille du plus grand alignement
 
Perso, je ferais comme ca [:cosmoschtroumpf]

n°1981264
ptitchep
Posté le 06-04-2010 à 15:39:51  profilanswer
 

Salut
 

passio a écrit :

C'est votre domaine, ou vous êtes des amateurs (et je m'inquiète).
 
Je n'ai pas d'autres idées...
Déjà l'approche de mon puissance 4 est assez difficile, en effet j'avais un bug que j'ai soumis à des programmeurs, qui n'ont rien compris à mon code. Maintenant il est un peu plus clair.
 
http://romintensity.free.fr/grille.pdf


Beaucoup de gens ici sont des professionnels. Si ce n'est pas le cas, ils ont largement le niveau pour un puissance 4 ;)
Apres,
N développeurs ==> N solutions
Ce n'est pas parce que ta solution n'est pas intuitive pour certains (je n'ai pas lu en détail, ce n'est pas une critique) qu'elle est mauvaise.
 
 

mrbebert a écrit :

Une autre approche, au lieu de rechercher une position gagnante n'importe où dans la grille, serait d'en rechercher une à partir de la position qui vient d'être jouée.
Tu définis une fonction qui prend en paramètre les coordonnées (x,y) de la position à partir de laquelle faire la recherche (qui sera la position qui vient d'être jouée) et qui :
- recherche dans les 8 directions possibles le nombre de pions de la même couleur qu'en (x,y)
(la recherche vers le haut devrait être plutôt triviale :D )
- additionne le nombre de pions trouvés dans les directions opposées (+1 pour la position courante) et renvoie la taille du plus grand alignement
 
Perso, je ferais comme ca [:cosmoschtroumpf]


J'aurais fait comme ça aussi mais avec seulement 4 directions car finalement c'est plutôt une recherche horizontale (par exemple) que deux recherches, droite et gauche. La recherche horizontale est ensuite divisée en deux parties qui s'ajoutent (sans oublier le pion de départ) puis si somme>=4, victoire.


---------------
deluser --remove-home ptitchep
n°1981298
passio
Posté le 06-04-2010 à 17:13:25  profilanswer
 

Je trouve l'approche de la position qui vient d'être jouée vraiment très bonne, je me demande même pourquoi je ne l'ai pas eue :).
 
Je ne sais pas si je vais réussir, mais je vais essayer, je pensais jamais réussir mon puissance 4, j'ai arrêté la programmation aux bases du C et à la POO (théorie et Qt) il y a un an, et pendant mon temps de vacances j'ai quand même réussi au bout de trois jours à le programmer à moitié. Je vais continuer d'essayer et je vous tiens au courant.
 
Je devrais créer une variable :
 
positionActuelle[hauteur[j]][j] = VARIABLE
 
valeurPositionHaut = 0; (cela peut rien être au dessus donc osef...)  
 
valeurPositionBas = positionActuelle[hauteur[j-1]][j]
valeurPositionBas2 = positionActuelle[hauteur[j-2]][j]
valeurPositionBas3 = positionActuelle[hauteur[j-3]][j]  
 
valeurPositionGauche = positionActuelle[hauteur[j]][j-1]
valeurPositionGauche = positionActuelle[hauteur[j]][j-2]  
valeurPositionGauche = positionActuelle[hauteur[j]][j-3]  
 
valeurPositionDroite = positionActuelle[hauteur[j]][j+1]
valeurPositionDroite = positionActuelle[hauteur[j]][j+2]  
valeurPositionDroite = positionActuelle[hauteur[j]][j+3]  
 
 
if(VARIABLE == valeurPositionBas && VARIABLE == valeurPositionBas2 && VARIABLE == valeurPositionBas3)
{
WIN
}
 
 
etc ? :s


Message édité par passio le 06-04-2010 à 17:35:28
n°1981299
ptitchep
Posté le 06-04-2010 à 17:15:18  profilanswer
 

N'essaie pas. Fais le.[:grand maitre yoda]

 

Tu devrais mettre ta vérification dans une boucle au lieu de créer plein de variables. Car comme le dit Turkleton, le jour où tu vas faire un puissance 25... Aïe!
Quelque chose du genre (code à l'arrache):

Code :
  1. /*Vérif horizontale*/
  2. decalage=1;
  3. nbPareil=1;
  4. while ( i-decalage>=0 && grille[i-decalage][j] == grille[i][j]) /*On regarde à gauche*/
  5. {
  6.     nbPareil++;
  7.     decalage++;
  8. }
  9. decalage =1;
  10. while ( i+decalage<LARGEUR_GRILLE && grille[i+decalage][j] == grille[i][j]) /*On regarde à droite*/
  11. {
  12.     nbPareil++;
  13.     decalage++;
  14. }
  15. if (nbPareil >= NB_NECESSAIRES_VICTOIRE)
  16.     victoire();


Message édité par ptitchep le 06-04-2010 à 17:53:52

---------------
deluser --remove-home ptitchep
n°1981325
passio
Posté le 06-04-2010 à 18:07:02  profilanswer
 

C'est bien la programmation c'est à celui qui repoussera au plus loin les limites de son esprit. Chez moi ça arrive souvent. C'est frustrant... Mais bon j'compense avec 18 au bac Blanc de français  :bounce:  
 
 
 
Je comprends ton code, mais j'ai l'esprit étroit dans ce domaine et j'ai beaucoup de mal à comprendre en fait... C'est frustrant. Est-ce que ça arrive à tout le monde et ça vient avec le temps ou est-ce inné ?


Message édité par passio le 06-04-2010 à 18:19:28
n°1981332
ptitchep
Posté le 06-04-2010 à 18:21:53  profilanswer
 

C'est normal au début. Petit à petit la logique paraît de plus en plus... logique.
Plus tu les pousses et plus "les limites de ton esprit" seront loin.

 

En tout cas n'hésite pas à poser des questions ici. Le forum est là pour ça et pas mal des programmeurs ont commencé en tant que débutants eux aussi. Ils comprennent donc.


Message édité par ptitchep le 06-04-2010 à 18:24:45

---------------
deluser --remove-home ptitchep
n°1981335
passio
Posté le 06-04-2010 à 18:24:17  profilanswer
 

Je me sens jamais aussi con que quand je programme... C'est quand même rassurant.

n°1981336
ptitchep
Posté le 06-04-2010 à 18:35:31  profilanswer
 

L'important c'est de pratiquer. Finis ce que tu commences et tu progresseras. Après le puissance 4 tu te rendras compte que tu as franchi un "palier" et que tu peux faire autre chose de plus complexe. Tu t'arracheras les cheveux sur autre chose ==> nouveau palier. Et ainsi de suite. C'est en voyant le résultat final que tu verras ta progression donc ne laisse pas tomber. La satisfaction est grande quand ton propre jeu tourne sur ton pc. Même si le jeu est merdique et que tu es le seul à y jouer :p

 

Et puis 18 au bac blanc de français, c'est que ton cerveau est en état de marche.


Message édité par ptitchep le 06-04-2010 à 19:49:02

---------------
deluser --remove-home ptitchep
n°1981345
Turkleton
I don't quite understand you
Posté le 06-04-2010 à 19:02:00  profilanswer
 

+1 avec ptitchep
Je rajouterais même que quand tu auras fini ton puissance 4 et que tu te prendras la tête sur autre chose, c'est encore plus sympa de constater ses progrès en revenant sur un ancien programme et en l'optimisant.
 
Et oui, jouer sur son propre programme merdique, c'est 10x plus jouissif que n'importe quel autre jeu fait par quelqu'un d'autre :D  
En l'occurrence, je me suis remis au C pour pouvoir développer des jeux pour ma Nintendo DS. C'est trop bon :)  
 
Pour ton Puissance 4, le code de ptitchep est excellent pour contourner l'usage des fonctions récursives par celui des boucles while. Si tu te sens un peu motivé, tu peux même faire un mix de nos deux codes : utiliser les boucles while pour le parcours des cases, mais en utilisant des indices pour les variables de décalages horizontales et verticales. Ainsi, tu n'as la boucle qu'une seule fois (dans une fonction, que tu appelles à chaque fois avec des indices différents pour explorer toutes les directions), ça optimise énormément le code.


---------------
If you think it could look good, then I guess it should
n°1981757
passio
Posté le 07-04-2010 à 22:35:31  profilanswer
 

Coucou, c'est encore moi... Alors j'ai avancé, j'oserai pas vous dire en combien d'heures, mais j'ai avancé  :D  
 
Voilà mon code :

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void afficherGrille(int grille[][7]);
  4. int modifierGrille(int choixColonne, int hauteurColonne[], int grille[][7], int tour, int *pointeurTour);
  5. int menu();
  6. int definirJoueur(int tour);
  7. int tableauRempli(int hauteurColonne[], int *pointeurTour);
  8. int verifierGagnant( int grille[][7], int choixColonne, int hauteurColonne[], int valeurPositionActuelle);
  9. void menuPrincipal();
  10. int main()
  11. {
  12.     int grille[6][7] = {0};     //grille[i][j]
  13.     int i;
  14.     int choixColonne = 0;
  15.     int tour = 0;
  16.     int *pointeurTour = &tour;
  17.     int nbrPionsIdentiquesV;
  18.     int nbrPionsIdentiquesH;
  19.     int valeurPositionActuelle;
  20.     int VICTOIRE = 0;
  21.     int hauteurColonne[7];
  22.     for(i = 0; i!=7; i++){
  23.         hauteurColonne[i] = 5;}
  24. menuPrincipal();
  25. do{
  26.     afficherGrille(grille);
  27.     tour = definirJoueur(tour);
  28.     choixColonne = menu();
  29.     modifierGrille(choixColonne, hauteurColonne, grille, tour, &tour);
  30.     if(hauteurColonne[choixColonne]>=0){
  31.     hauteurColonne[choixColonne]--;}
  32.     else{
  33.     tour++;}
  34.     VICTOIRE = verifierGagnant(grille, choixColonne, hauteurColonne, valeurPositionActuelle);
  35.     }
  36.     while(!tableauRempli(hauteurColonne, &tour) && !VICTOIRE);
  37.     afficherGrille(grille);
  38.     if(!VICTOIRE){
  39.         printf("\n                                            VOUS AVEZ REMPLI LA GRILLE\n\n" );
  40.     }
  41.     return main();
  42. }
  43. int modifierGrille(int choixColonne, int hauteurColonne[], int grille[][7], int tour, int *pointeurTour)
  44. {
  45.     int i;
  46.     int j;
  47.     for(i = 0; i!=6; i++)
  48.     {
  49.         for(j = 0; j!=7; j++)
  50.         {
  51.             if(choixColonne == j)
  52.             {
  53.                 if(hauteurColonne[j] >= 0)           //éviter le débordement de pions sur le haut [0][j]
  54.                 {
  55.                 if(tour) //boléen 1/0
  56.                 {
  57.                 grille[hauteurColonne[j]][j] = 1; //Pion ☺
  58.                 }
  59.                 else
  60.                 {
  61.                     grille[hauteurColonne[j]][j] = 2; //Pions ☻
  62.                 }
  63.                 }
  64.                 else{
  65.                     if(!i)            //Pour implémenter une fois à l'intérieur de la boucle.
  66.                     {
  67. //on incrémente la variable associé au pointeur  //FACULTATIF *ponteurTour+=1; en fonction des modif code;
  68.                     }                         //pour éviter le décalage du nombre de pion en cas de mauvaise saisie
  69. }}}}} //
  70. int menu()
  71. {
  72.     int choix;
  73.     printf("\nDans quelle colonne souhaitez vous placer un pion ?       " );
  74.     scanf("%ld", &choix);
  75.     if(choix > 7 || choix < 1)
  76.     {
  77.         printf("La valeur doit etre comprise entre 1 et 7.\n" );
  78.         return menu();
  79.     }
  80.     return choix-1; // 1 = 0 & Jmin = 0
  81. }
  82. void afficherGrille(int grille[][7])
  83. {
  84.     int i;
  85.     int j;
  86.     for(i = 0; i!=6; i++)
  87.     {
  88.         printf("                       " );
  89.         for(j = 0; j!=7; j++)
  90.         {
  91.             switch(grille[i][j]) {
  92.  case 2 :  printf("%c", 1);
  93.      break;
  94.  case 1 :  printf("%c", 2);
  95.      break ;
  96.         case 3 :  printf("%c", 3);
  97.      break ;
  98.         case 4 :  printf("%c", 4);
  99.      break ;
  100.  default : printf("." );
  101.      break ;
  102.     }
  103.         }
  104.         printf("\n" );
  105.     }
  106. }
  107. int definirJoueur(int tour)
  108. {
  109.     return (tour+1)%2; //renvoie 0 ou 1
  110. }
  111. int tableauRempli(int hauteurColonne[], int *pointeurTour)
  112. {
  113.     int resultat = 0;
  114.     int i;
  115.     const int limite = -1;
  116.     for(i = 0; i<7; i++)
  117.     {
  118.         if(hauteurColonne[i] == limite && hauteurColonne[i+1] == limite && hauteurColonne[i+2] == limite && hauteurColonne[i+3] == limite && hauteurColonne[i+4] == limite && hauteurColonne[i+5] == limite && hauteurColonne[i+6] == limite)
  119.         {
  120.             resultat = 1;
  121.         }
  122.     }
  123.     printf("\n" );
  124.     return resultat;
  125. }
  126. int verifierGagnant( int grille[][7], int choixColonne, int hauteurColonne[], int valeurPositionActuelle)
  127. {
  128.     valeurPositionActuelle = grille[hauteurColonne[choixColonne]+1][choixColonne];
  129.     int valeurPositionDroite = grille[hauteurColonne[choixColonne]+1][choixColonne+1];
  130.     int valeurPositionGauche = grille[hauteurColonne[choixColonne]+1][choixColonne-1];
  131.     int valeurPositionDroite2 = grille[hauteurColonne[choixColonne]+1][choixColonne+2];
  132.     int valeurPositionGauche2 = grille[hauteurColonne[choixColonne]+1][choixColonne-2];
  133.     int nbrPionsIdentiquesV = 1;
  134.     int nbrPionsIdentiquesH = 1;
  135.     int i;
  136.     int VICTOIRE = 0;
  137.        for(i = 2; i<5; i++)
  138.        {
  139.            if(grille[hauteurColonne[choixColonne]+1][choixColonne] == grille[hauteurColonne[choixColonne]+i][choixColonne])
  140.            {
  141.                nbrPionsIdentiquesV+=1;
  142.            }
  143.        }
  144.         for(i = 1; i<4; i++)
  145.        {
  146.            if(grille[hauteurColonne[choixColonne]+1][choixColonne] == grille[hauteurColonne[choixColonne]+1][choixColonne+i] || grille[hauteurColonne[choixColonne]+1][choixColonne] == grille[hauteurColonne[choixColonne]+1][choixColonne-i])
  147.            {
  148.                nbrPionsIdentiquesH +=1;
  149.            }
  150.            else if( grille[hauteurColonne[choixColonne]+1][choixColonne] == valeurPositionDroite && grille[hauteurColonne[choixColonne]+1][choixColonne] == valeurPositionDroite2 && grille[hauteurColonne[choixColonne]+1][choixColonne] == valeurPositionGauche)
  151.            {
  152.                nbrPionsIdentiquesH = 4;
  153.            }
  154.            else if( grille[hauteurColonne[choixColonne]+1][choixColonne] == valeurPositionDroite && grille[hauteurColonne[choixColonne]+1][choixColonne] == valeurPositionGauche && grille[hauteurColonne[choixColonne]+1][choixColonne] == valeurPositionGauche2)
  155.            {
  156.                nbrPionsIdentiquesH = 4;
  157.            }
  158.        }
  159.        if(nbrPionsIdentiquesH ==4 || nbrPionsIdentiquesV ==4)
  160.    {
  161.        VICTOIRE = 1;
  162.    }
  163.    return VICTOIRE;
  164. }
  165. void menuPrincipal()
  166. {
  167.     printf("                      PUISSANCE 4\n\n" );
  168.     printf("                                      %c  Joueur 1\n                                      %c  Joueur 2\n", 1, 2);
  169. }


 
 
 
 
Le problème se pose lors de la vérification horizontale, la fonction est vraie quand :
OXOXXOO
XOXOXOX
XXXOXOO
 
 
Quelqu'un saurait il améliorer ma fonction car je planche :'(
 
 
Merci beaucoup.

n°1981783
ptitchep
Posté le 08-04-2010 à 01:43:14  profilanswer
 

A vue de nez je dirais que tu ne vérifies pas la validité de tes indices.

 
ptitchep a écrit :

Code :
  1. ...
  2. while ( i-decalage>=0 && grille[i-decalage][j] == grille[i][j]) /*On regarde à gauche*/
  3. ...
  4. while ( i+decalage<LARGEUR_GRILLE && grille[i+decalage][j] == grille[i][j]) /*On regarde à droite*/
  5. ...



 

les tests sur i-decalage>=0 et  i+decalage<LARGEUR_GRILLE permettent dans mon code de vérifier cela.
En mémoire, ton tableau de 6x7 est en réalité 42 cases contigües. La première case de la 2ème ligne est à la suite de la dernière case de la 1ère ligne. La deuxième dimension n'existe que dans ta tête.
Tu peux obtenir la "vraie" case avec la formule y*largeurTableau+x

 

Ton tableau dans ton exemple:
OXOXXOO
XOXOXOX
XXXOXOO

 

ressemble à ça en mémoire (sans les espaces c'est pour que tu vois les colonnes):
OXOXXOO XOXOXOX XXXOXOO
Quand tu le regardes comme ça, tu as en effet 4 X alignés! Pourtant le joueur n'a pas gagné.

 


donc si tu es sur la 1ere case de la troisième ligne [0][2] et que tu recules d'une case, ta position devient [-1][2] ce qui n'est pas normal. Cependant cette position est tout de même valide elle correspond à la case précédente en mémoire c'est à dire la dernière case de la ligne précédente [6][1]. Il faut que tu arrêtes ta vérification si un des indices devient <0 ou >6.

 

Vu l'heure, je ne suis pas sûr d'être clair. Si besoin demande ce que tu n'as pas compris.

 



Message édité par ptitchep le 08-04-2010 à 01:46:15

---------------
deluser --remove-home ptitchep
n°1981945
passio
Posté le 08-04-2010 à 13:00:12  profilanswer
 

J'ai absolument depuis toujours compris que les deux dimensions sont que dans ma tête et il me suffit de supprimer de supprimer le \n dans la boucle pour m'en rendre compte. Cependant, j'ai un blocage dans mon raisonnement pour y parer... Malgré tous mes efforts. Je vais essayer de m'y replonger mais ça me saoule pas mal là.
 
 
J'aurais besoin que tu m'explique la manière dont varie i-decalage et leur valeur d'initialisation.
 
 
Sinon pour ma fonction tout vient de là :
 
if(grille[hauteurColonne[choixColonne]+1][choixColonne] == grille[hauteurColonne[choixColonne]+1][choixColonne+i] || grille[hauteurColonne[choixColonne]+1][choixColonne] == grille[hauteurColonne[choixColonne]+1][choixColonne-i])
           {
               nbrPionsIdentiquesH +=1;
           }


Message édité par passio le 08-04-2010 à 13:30:20
n°1982011
ptitchep
Posté le 08-04-2010 à 14:43:52  profilanswer
 

Utilise un débugger, c'est le meilleur moyen de voir comment fonctionne un programme. Tu travailles avec quel environnement?
 
Avec le débugger tu sauras combien valent tes indices et tu trouveras le bug.


---------------
deluser --remove-home ptitchep
n°1982056
passio
Posté le 08-04-2010 à 15:55:47  profilanswer
 

J'ai réussi !!!! Avec une petite astuce simple...

Code :
  1. int limite = 0;
  2.     int limite2 = 0;
  3.                     if(choixColonne+4 > LARGEUR)
  4.                {
  5.                    limite = 1;
  6.                    printf("L" );
  7.                 }
  8.                     if(choixColonne - 3 < 0)
  9.                {
  10.                    limite2 = 1;
  11.                    printf("M" );
  12.                 }
  13.        for(i = 2; i<5; i++){
  14.            if(position.actuelle == grille[hauteurColonne[choixColonne]+i][choixColonne]){
  15.                pionsIdentiques.verticale+=1;
  16.            }
  17.        }
  18.         for(i = 1; i<4; i++){
  19.            if(position.actuelle == grille[hauteurColonne[choixColonne]+1][choixColonne+i]){
  20.                if(!limite){
  21.                pionsIdentiques.horizontale +=1;
  22.                }
  23.            }


 
 
Je crois que je vais m'arrêter là car pour la diagonale je suis dans... l'impasse..
 
Je travaille avec Code::blocks

n°1982059
passio
Posté le 08-04-2010 à 15:56:31  profilanswer
 

J'ai réussi !!!! Avec une petite astuce simple...

Code :
  1. int limite = 0;
  2.     int limite2 = 0;
  3.                 if(choixColonne+4 > LARGEUR){
  4.                    limite = 1;
  5.                 }
  6.                 if(choixColonne - 3 < 0){
  7.                    limite2 = 1;
  8.                 }
  9.                
  10.        for(i = 2; i<5; i++){
  11.            if(position.actuelle == grille[hauteurColonne[choixColonne]+i][choixColonne]){
  12.                pionsIdentiques.verticale+=1;
  13.            }
  14.        }
  15.         for(i = 1; i<4; i++){
  16.            if(position.actuelle == grille[hauteurColonne[choixColonne]+1][choixColonne+i]){
  17.                if(!limite){
  18.                pionsIdentiques.horizontale +=1;
  19.                }
  20.            }
  21.            if(position.actuelle == grille[hauteurColonne[choixColonne]+1][choixColonne-i]){
  22.                               if(!limite2){
  23.                pionsIdentiques.horizontale2 +=1;
  24.                }


 
 
Je crois que je vais m'arrêter là car pour la diagonale je suis dans... l'impasse..
 
Je travaille avec Code::blocks

Message cité 1 fois
Message édité par passio le 08-04-2010 à 15:57:59
n°1982082
breizhbugs
Posté le 08-04-2010 à 16:28:12  profilanswer
 

J'ai fait un puissance 4 aussi un jour, voici le code pour la vérification:

Code :
  1. struct Case
  2. {
  3. int dg;
  4. int vert;
  5. int dd;
  6. int horz;
  7. };
  8. ...
  9. #define FREE  0
  10. #define JAUNE 1
  11. #define ROUGE 2
  12. ...
  13. int tableau[NB_COLONNES][NB_LIGNES];  // l'espace de jeu contenant l'une des valeur ci dessus / case
  14. ...
  15. bool CPuissance4Dlg::check()
  16. /*
  17. Principe:
  18. Additioner le contenu de la case adjacente correcte (->meme couleur)
  19. au contenu de la case courante.
  20. */
  21. {
  22.         // initialisation de game
  23. Case game[NB_COLONNES][NB_LIGNES];
  24. for (int ligne = 0; ligne < NB_LIGNES ; ligne++)
  25. {
  26.  for (int colonne = 0; colonne < NB_COLONNES; colonne++)
  27.  {
  28.   /*
  29.   Par defaut il y a 1 pion sur 4 d'aligner correctement
  30.   */
  31.   game[colonne][ligne].horz=1;
  32.   game[colonne][ligne].vert=1;
  33.   game[colonne][ligne].dg=1;
  34.   game[colonne][ligne].dd=1;
  35.  }
  36. }
  37. // pour le horizontal
  38. for (int ligne = 0; ligne < NB_LIGNES ; ligne++)
  39. {
  40.  for (int colonne = 1; colonne < NB_COLONNES; colonne++)
  41.  {
  42.   if ((tableau[colonne][ligne]==tableau[colonne-1][ligne])&&(tableau[colonne][ligne]!=FREE))
  43.    // Si la case courante et celle  de la colonne précédente sont de même couleur (mais pas libre -> donc du même joueur)
  44.   {
  45.                                 // on incrémente la valeur "horz" du tableau de comptage game avec la valeur "de la case de la colonne précédente" + 1
  46.    game[colonne][ligne].horz=game[colonne-1][ligne].horz+1;
  47.    if (game[colonne][ligne].horz==4)
  48.                                  // si on est a 4 alors on retourne vrai: le joueur a gagné (comme on recalcule a chaque fois, on sait que c'est je joueur courant!)
  49.     return true;
  50.   }
  51.  }
  52. }
  53. // pour le vertical
  54. for (int ligne = 1; ligne < NB_LIGNES ; ligne++)
  55. {
  56.  for (int colonne = 0; colonne < NB_COLONNES; colonne++)
  57.  {
  58.   if ((tableau[colonne][ligne]==tableau[colonne][ligne-1])&&(tableau[colonne][ligne]!=FREE))
  59.    // meme couleur
  60.   {
  61.    game[colonne][ligne].vert=game[colonne][ligne-1].vert+1;
  62.    if (game[colonne][ligne].vert==4)
  63.     return true;
  64.   }
  65.  }
  66. }
  67. // pour le diagonal gauche:de bas à gauche vers haut à droite
  68. for (int ligne = 1; ligne < NB_LIGNES ; ligne++)
  69. {
  70.  for (int colonne = 0; colonne < NB_COLONNES-1; colonne++)
  71.  {
  72.   if ((tableau[colonne][ligne]==tableau[colonne+1][ligne-1])&&(tableau[colonne][ligne]!=FREE))
  73.    // meme couleur
  74.   {
  75.    game[colonne][ligne].dg=game[colonne+1][ligne-1].dg+1;
  76.    if (game[colonne][ligne].dg==4)
  77.     return true;
  78.   }
  79.  }
  80. }
  81. // pour le diagonal droite:de haut à gauche vers bas à droite
  82. for (int ligne = 1; ligne < NB_LIGNES ; ligne++)
  83. {
  84.  for (int colonne = 1; colonne < NB_COLONNES; colonne++)
  85.  {
  86.   if ((tableau[colonne][ligne]==tableau[colonne-1][ligne-1])&&(tableau[colonne][ligne]!=FREE))
  87.    // meme couleur
  88.   {
  89.    game[colonne][ligne].dd=game[colonne-1][ligne-1].dd+1;
  90.    if (game[colonne][ligne].dd==4)
  91.     return true;
  92.   }
  93.  }
  94. }
  95. return false;
  96. }


 
L'algo est un calcul sur tout le tableau de jeu. On se créer un deuxième tableau (game) dans lequel on va noter le nombre de pion de la même couleur et qui se succède en fonction des 4 directions. Par exemple si le pion a la position (+1, +1) est de même couleur et a dans sa game[+1, +1].dg une valeur de 3 c'est que notre pion (0,0) est le quatrième et donc que la partie est gagnée (sinon on incrémente game[0, 0].dg de "1+game[+1, +1].dg" )
 
Pas très optimisé, le calcul est entièrement refait a chaque coup :-(


Message édité par breizhbugs le 08-04-2010 à 16:34:53
n°1982227
passio
Posté le 08-04-2010 à 21:24:30  profilanswer
 

Whàw, l'approche est bien différente de la mienne.

n°1982393
ptitchep
Posté le 09-04-2010 à 10:38:11  profilanswer
 

passio a écrit :

J'ai réussi !!!! Avec une petite astuce simple...
...
Je crois que je vais m'arrêter là car pour la diagonale je suis dans... l'impasse..
 
Je travaille avec Code::blocks


 
Avec code blocks tu as un débugger intégré. Utilise le au maximum pour voir comment s'exécute ton programme, c'est très instructif.
 
Pour les diagonales, le principe est le même sau qu'au lieu de  
 
while ( i-decalage>=0 && grille[i-decalage][j] == grille[i][j])
 
tu as
 
while ( i-decalage>=0 && j - decalage >=0 && grille[i-decalage][j-decalage] == grille[i][j])
 
histoire de te déplacer à gauche ET vers le haut.
 
 
Pour ta question de l'évolution de i-decalage, j'ai oublié de répondre.  
Au début, i vaut la colonne dans laquelle tu as posé le pion. A toi de l'initialiser avec la valeur choisie par l'utilisateur.
Decalage représente la distance entre la colonne que tu observes et celle jouée. Au début decalage vaut 1 et pas 0 car rien ne sert de vérifier la colonne i vu que l'on sait qui a joué ici.
A chaque itération de la boucle, decalage augmente de 1 ce qui permet de regarder la colonne suivante: i-1 puis i-2 etc. Bien sûr on vérifie que i-decalage (donc la colonne que l'on regarde) ne soit pas inférieur à 0 car regarder la colonne -1 n'a pas de sens.
Pour la diagonale, on veut la colonne précédente mais aussi la ligne du dessus. Heureusement, la diagonale est à 45°. Chaque fois que l'on recule d'une colonne, on remonte d'une ligne donc on peut utiliser le même décalage pour les deux indices. On regarde la ligne j-decalage de la colonne i-decalage.
 
Toi tu obtiens ta ligne avec hauteurColonne[choixColonne]+1 donc tu peux faire:
j = hauteurColonne[choixColonne]+1
 et  
i = choixColonne
 
Enfin c'est peut-être l'inverse, je mélange souvent les lignes et les colonnes dsl.
Ensuite, tu peux passer  aux boucles de vérif.
 
J'espère être clair.


---------------
deluser --remove-home ptitchep
n°1982442
passio
Posté le 09-04-2010 à 11:53:52  profilanswer
 

Citation :

Avec code blocks tu as un débugger intégré. Utilise le au maximum pour voir comment s'exécute ton programme, c'est très instructif.


 
 
Ne t'en fais pas, il m'insulte toutes les deux minutes xD...
 
 
Sinon, merci pour les conseils.

n°1982613
ptitchep
Posté le 09-04-2010 à 15:59:15  profilanswer
 

Tu es sûr que l'on parle de la même chose? Mon debugger ne parle pas.


---------------
deluser --remove-home ptitchep
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Aide pour mon Puissance 4 ! =)

 

Sujets relatifs
Comment compiler un fichier C#Divers questions en C
Aide effet Toggle Javascriptaide pour interface
[C] Récuperer le nom d'un fichier zipDebutant besoin aide
demande d'aide pour mon mcdAide avec SED
[MATLAB] aide graphique loi binomiale :/Aide pour modèle objet. moteur d'ordre?
Plus de sujets relatifs à : [C] Aide pour mon Puissance 4 ! =)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR