Problème avec un alphabeta en C pour othello

Problème avec un alphabeta en C pour othello - C - Programmation

Marsh Posté le 03-05-2011 à 12:03:37    

Bonjour,  je suis étudiante en maths-informatique et on nous a donné comme premier projet le jeu d'othello.
Cependant il semble que l'alphabeta soit mal programmé (il me semble qu'il gère mal les scores dans le cas où un joueur doit passer son tour mais je me trompe peut être).
Etant un peu à court d'idée j'espère que vous pourrez m'aider et me dire ce qui ne va pas dans ce code :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "structures.h"
  4. #include "main.h"
  5. int game_over(partie battle, int couleur){
  6.     if((possibilite(&battle, battle.plateau, couleur)==-1) || (battle.nb_coupsjoues>MAX_COUPS))//si il n'y a plus de coups possible ou si on ajoue 60 coups, la partie est terminee
  7.         return -1;
  8.     else
  9.         return 1;
  10. }
  11. int alphabeta(int profondeur, int alpha, int beta, partie* b){
  12. partie battle=(*b);
  13.     coup coups;
  14. int i=11, couleur, legal, score, avant, dir;
  15. int pass=0;//nous servira a avoir les bons scores pour les cas ou un joueur doit sauter son tour
  16. coup meilleur_coup;
  17. if (battle.nb_coupsjoues==0){//si aucun coup n'a ete joue (l'ordi commence), la couleur est  initialisee a noir
  18.  couleur=NOIR;
  19. }
  20. else if(battle.coups[battle.nb_coupsjoues-1].couleur==NOIR)//sinon on regarde la couleur du cop precedent pour savoir quel couleur prendre
  21.  couleur=BLANC;
  22. else
  23.  couleur=NOIR;
  24.     if(possibilite(&battle, battle.plateau,couleur)==0){
  25.         couleur=(couleur+1)%2;
  26.         pass=1;
  27.     }
  28. if(game_over(battle, couleur)!=1){//si la partie est termine on regarde si le joueur actuel a gagne
  29.         if (battle.plateau->materiel[couleur]>battle.plateau->materiel[(couleur+1)%2])//si oui, on renvoit un grand nombre
  30.   {
  31.    return +1000000;
  32.   }
  33.   else if(battle.plateau->materiel[(couleur+1)%2]>battle.plateau->materiel[couleur])//sinon un tres petit nombre
  34.   {
  35.    return -1000000;
  36.   }
  37.   else
  38.   {
  39.    return 0;//pour l'egalite, on renvoit 0
  40.   }
  41. }
  42. else if(profondeur<=0){//si on a atteint la profondeur souhaite, on lance la fonction d'evaluation
  43.         return evaluation(battle, couleur);
  44.     }
  45.     else{//sinon on parcourts le damier afin de tester les coups legaux
  46.         while(i<=88){
  47.             for (dir=0;dir<DIRECTIONS;dir++)
  48.                 coups.retournement[dir]=0;
  49.             coups.position=i;
  50.             coups.couleur=couleur;
  51.             legal=coup_legal(battle.plateau, coups);
  52.             if(legal==-1)
  53.                 i++;
  54.             else{
  55.                 battle.plateau->damier[coups.position]=coups.couleur; // on "pose le pion sur le plateau" = on attribu a la case de l'othellier la valeur de la couleur
  56.                 coups=new_plateau(battle.plateau, coups); // on retourne les pions adverses
  57.                 battle.coups[battle.nb_coupsjoues]=coups; // on enregistre le coup joue
  58.                 couleur=(couleur+1)%2;//on change couleur
  59.                 battle.nb_coupsjoues++;
  60.                 if (battle.nb_coupsjoues>battle.longueur)
  61.                     battle.longueur++;
  62.                 if(pass==1){//si pass egal a 1, on ne change pas alphabeta a par la profondeur (pas d'alternance minmax)
  63.                     score=alphabeta(profondeur-1, alpha, beta, &battle);
  64.                 }
  65.                 else{//sinon on fait l'alternance minmax, (un joueur cherche a minimiser et l'autre a maximiser)
  66.                     score=-alphabeta(profondeur-1, -beta, -alpha, &battle);
  67.                 }
  68.                 avant=couleur;
  69.                 battle=annuler(battle.plateau, battle, (coups.couleur+1)%2);
  70.                 couleur=battle.coups[battle.nb_coupsjoues].couleur; //permet de passer au joueur precedant
  71.                 if(score>=alpha){//si score >= alpha, ce dernier coup est le meilleur
  72.                     alpha=score;//on change alpha
  73.                     meilleur_coup=coups;//on sauvegarde ce coup
  74.                     (*b).coups[battle.nb_coupsjoues]=coups;//on le sauvegarde egalement ici pour pouvoir le faire passer dans le jeu principal
  75.                     if(alpha>=beta){//si alpha >= beta, c'est inutile de continuer plus loins dans cette branche
  76.                         break;
  77.                     }
  78.                 }
  79.                 i++;
  80.             }
  81.         }
  82.     }
  83. return alpha;
  84. }


 
 
 
 
<config>Windows 7 / Firefox 3.6.17</config>


Message édité par Liarina le 03-05-2011 à 13:57:10
Reply

Marsh Posté le 03-05-2011 à 12:03:37   

Reply

Marsh Posté le 03-05-2011 à 13:51:30    

Salut,
 
J'ai pas encore trop regardé en détail, mais je pense qu'ajouter le contenu de tes fichiers d'entête structures.h et main.h aiderait à la compréhension générale du code (notamment les structures que tu utilises). Utilise aussi le bouton "C/C++" quand tu postes du code ici, ça ajoute la coloration syntaxique et ce genre de choses qui facilitent la lecture.
 
À mon avis, l'erreur vient de la complexité de ta fonction alphabeta, la découper en plus petites fonctions (chacune faisant une chose relativement simple) te permettra de mieux comprendre chaque partie de ton code et donc de ne pas devoir chercher où se cache l'éventuelle erreur dans une longue fonction. Mais déjà, avoir le contenu des structures que tu utilises permettra de mieux comprendre le fonctionnement de ton programme.

Reply

Marsh Posté le 03-05-2011 à 13:56:53    

Désolée pour la première édition. j'avais pas fait attention au bouton c/c++
 
main.h

Code :
  1. #include <SDL/SDL.h>
  2. #include <SDL_image.h>
  3. #include <SDL/SDL_ttf.h>
  4. void save(partie battle);
  5. partie load(FILE *save);
  6. int coup_legal(othellier plateau, coup coups);
  7. othellier initialisation(othellier plateau);
  8. int possibilite(partie *battle, othellier plateau, int couleur);
  9. coup new_plateau(othellier plateau,coup coups);
  10. partie annuler(othellier plateau,partie battle,int couleur);
  11. partie suivant(othellier plateau,partie battle,int couleur);
  12. int alphabeta(int profondeur, int alpha, int beta, partie *b);
  13. int game_over(partie battle, int couleur);
  14. int evaluation(partie battle, int couleur);
  15. int mobilite(partie battle, int couleur);
  16. int materiel(partie battle, int couleur);
  17. int coins(partie battle, int couleur);
  18. void affiche_menu(SDL_Surface *ecran);
  19. void affiche_oth(SDL_Surface* ecran, partie battle, int couleur, char choix[10]);
  20. int main();


 
structures.h
 

Code :
  1. #ifndef __STRUCTURES__
  2. #define __STRUCTURES__
  3. #include "definitions.h"
  4. struct othellier{
  5. int damier[MAX_CASE];
  6. int materiel[NB_JOUEURS];
  7. };
  8. typedef struct othellier * othellier;
  9. typedef struct{
  10. int position;
  11. int couleur;
  12. int retournement[DIRECTIONS];
  13. }coup;
  14. struct joueur{
  15. char nom[10];
  16. int type;
  17. int couleur;
  18. int niveau;
  19. };
  20. typedef struct joueur * joueur;
  21. typedef struct{
  22. int longueur;
  23. int nb_coupsjoues;
  24. joueur joueurs[2];
  25. int nbcoups_possible[2];
  26. coup coups[MAX_COUPS];
  27. othellier plateau;
  28. }partie;
  29. #endif

Reply

Sujets relatifs:

Leave a Replay

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