diff --git a/includes/jeu.h b/includes/jeu.h index 1ed98f4..0d4a6bf 100644 --- a/includes/jeu.h +++ b/includes/jeu.h @@ -47,8 +47,9 @@ typedef struct jeu Jeu; Jeu *nouvelle_partie(void); /* Lance et joue une partie */ -void deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE noir, - const enum PLAYER_TYPE blanc, const Test_Data *test); +enum CASE deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE noir, + const enum PLAYER_TYPE blanc, + const Test_Data *test); /* Coups possibles d'un joueur */ struct coups { diff --git a/includes/test.h b/includes/test.h index a0755ad..8279bb2 100644 --- a/includes/test.h +++ b/includes/test.h @@ -5,17 +5,25 @@ struct test_data { int test; - int profondeur; + int profondeur_minimax; + int profondeur_alphabeta; }; typedef struct test_data Test_Data; /* Initialise un Test_Data */ -Test_Data *nouveau_test_data(int test, int profondeur); +Test_Data *nouveau_test_data(int test, int profondeur_minimax, + int profondeur_alphabeta); /* Libère un Test_Data de la mémoire */ void free_test_data(Test_Data *test_data); -/* Run the tests */ +/* Lance les différents tests */ void run_tests(void); +/* Test par rapport à la vitesse d'éxécution */ +void speed_test(int profondeur_max_minimax, int profondeur_max_alphabeta); + +/* Test par rapport à qui gagne */ +void winrate_test(int profondeur_max_minimax, int profondeur_max_alphabeta); + #endif diff --git a/src/jeu.c b/src/jeu.c index e0d7ada..02d0d0b 100644 --- a/src/jeu.c +++ b/src/jeu.c @@ -38,9 +38,9 @@ Jeu *nouvelle_partie(void) { return jeu; } -void deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE type_noir, - const enum PLAYER_TYPE type_blanc, - const Test_Data *test) { +enum CASE deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE type_noir, + const enum PLAYER_TYPE type_blanc, + const Test_Data *test) { Joueur *tour = jeu->j1->couleur == NOIR ? jeu->j1 : jeu->j2; while (!partie_finie(jeu)) { @@ -66,11 +66,12 @@ void deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE type_noir, action_joueur_humain(jeu, tour->couleur); break; case MINIMAX: - action_joueur_minimax(jeu, tour->couleur, test->profondeur); + action_joueur_minimax(jeu, tour->couleur, + test->profondeur_minimax); break; case ALPHABETA: action_joueur_alphabeta(jeu, tour->couleur, - test->profondeur); + test->profondeur_alphabeta); break; default: fprintf(stderr, "Erreur: Joueur noir non supporté."); @@ -87,11 +88,12 @@ void deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE type_noir, action_joueur_humain(jeu, tour->couleur); break; case MINIMAX: - action_joueur_minimax(jeu, tour->couleur, test->profondeur); + action_joueur_minimax(jeu, tour->couleur, + test->profondeur_minimax); break; case ALPHABETA: action_joueur_alphabeta(jeu, tour->couleur, - test->profondeur); + test->profondeur_alphabeta); break; default: fprintf(stderr, "Erreur: Joueur blanc non supporté."); @@ -110,17 +112,24 @@ void deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE type_noir, if (!test->test) { affiche_plateau(jeu->plateau); + } - int resultat[3]; - if (selection_gagnant(jeu, resultat)) { + int resultat[3]; + if (selection_gagnant(jeu, resultat)) { + Joueur *gagnant = jeu->j1->couleur == resultat[0] ? jeu->j1 : jeu->j2; + if (!test->test) { printf("Fin de partie ! Le joueur %s a gagné %d contre %d !\n", - jeu->j1->couleur == resultat[0] ? jeu->j1->nom - : jeu->j2->nom, - resultat[1], resultat[2]); - } else { + gagnant->nom, resultat[1], resultat[2]); + } + + return gagnant->couleur; + } else { + if (!test->test) { printf("Égalité parfaite, %d contre %d !\n", jeu->j1->nb_jeton, jeu->j2->nb_jeton); } + + return VIDE; } } diff --git a/src/main.c b/src/main.c index 9b9ed42..584bc2f 100644 --- a/src/main.c +++ b/src/main.c @@ -74,7 +74,7 @@ int main(int argc, char const *argv[]) { } Jeu *jeu = nouvelle_partie(); - Test_Data *test = nouveau_test_data(0, 3); + Test_Data *test = nouveau_test_data(0, 4, 6); printf("Le jeu commence avec les noirs en tant %s et les blancs en " "tant %s.\n", diff --git a/src/test.c b/src/test.c index 5a0efc4..7cb2979 100644 --- a/src/test.c +++ b/src/test.c @@ -1,11 +1,14 @@ #include "../includes/jeu.h" +#include #include -Test_Data *nouveau_test_data(int test, int profondeur) { +Test_Data *nouveau_test_data(int test, int profondeur_minimax, + int profondeur_alphabeta) { Test_Data *res = malloc(sizeof(Test_Data)); res->test = test; - res->profondeur = profondeur; + res->profondeur_minimax = profondeur_minimax; + res->profondeur_alphabeta = profondeur_alphabeta; return res; } @@ -13,24 +16,27 @@ Test_Data *nouveau_test_data(int test, int profondeur) { void free_test_data(Test_Data *test_data) { free(test_data); } void run_tests(void) { + speed_test(6, 8); + winrate_test(5, 7); +} + +void speed_test(int profondeur_max_minimax, int profondeur_max_alphabeta) { int repetions = 5; - int max_profondeur = 8; - int max_profondeur_minimax = 6; printf("Lancement des tests, on va jusqu'à une profondeur de %d avec une " "moyenne de %d répétitions.\n", - max_profondeur, repetions); + profondeur_max_alphabeta, repetions); printf("On fait jouer alpha-bêta contre lui-même puis minimax contre " "lui-même.\n"); clock_t t0; double delta1, delta2, precedent = 0, actuel = 0; - for (int i = 1; i < max_profondeur + 1; ++i) { + for (int i = 1; i < profondeur_max_alphabeta + 1; ++i) { delta1 = 0; for (int j = 0; j < repetions; ++j) { Jeu *jeu = nouvelle_partie(); - Test_Data *test = nouveau_test_data(1, i); + Test_Data *test = nouveau_test_data(1, 0, i); t0 = clock(); @@ -44,17 +50,17 @@ void run_tests(void) { } delta1 /= repetions; - printf("Profondeur de %d (moyenne de %d tests) ->\t Alphabêta = %fs\t", + printf("Profondeur de %d (moyenne de %d tests) ->\t alpha-bêta = %fs\t", i, repetions, delta1); - if (i < max_profondeur_minimax) { + if (i < profondeur_max_minimax) { // On ne calcul que Minimax avec une petite profondeur parce que // sinon c'est trop long delta2 = 0; for (int j = 0; j < repetions; ++j) { Jeu *jeu = nouvelle_partie(); - Test_Data *test = nouveau_test_data(1, i); + Test_Data *test = nouveau_test_data(1, i, 0); t0 = clock(); @@ -69,10 +75,10 @@ void run_tests(void) { delta2 /= repetions; actuel = delta2 - delta1; - printf("| Minimax = %fs\t | Différence (m - a) = %fs", delta2, + printf("| minimax = %fs\t | différence (m - a) = %fs", delta2, actuel); } - if (i > 1 && i < max_profondeur_minimax) { + if (i > 1 && i < profondeur_max_minimax) { printf("\tavec le précédent = %fs\n", actuel - precedent); } else { printf("\n"); @@ -80,3 +86,69 @@ void run_tests(void) { precedent = actuel; } } + +void winrate_test(int profondeur_max_minimax, int profondeur_max_alphabeta) { + int nb_tests = 0; + + int nb_victoire_minimax = 0, nb_victoire_alphabeta = 0, nb_egalite = 0; + for (int i = 1; i < profondeur_max_alphabeta; ++i) { + for (int j = 1; j < profondeur_max_minimax; ++j, ++nb_tests) { + Jeu *jeu = nouvelle_partie(); + Test_Data *test = nouveau_test_data(1, j, i); + + // On alterne qui commence le jeu + int joueur_noir = i % 2 ? MINIMAX : ALPHABETA; + int joueur_blanc = joueur_noir == MINIMAX ? ALPHABETA : MINIMAX; + + int res; + switch (res = deroulement_partie(jeu, joueur_noir, joueur_blanc, + test)) { + case VIDE: + nb_egalite++; + break; + case BLANC: + if (joueur_blanc == MINIMAX) { + nb_victoire_minimax++; + printf("Minimax a gagné (profondeur minimax = %d vs %d = " + "profondeur alphabêta)\n", + j, i); + } else { + nb_victoire_alphabeta++; + printf( + "Alpha-bêta a gagné (profondeur minimax = %d vs %d = " + "profondeur alphabêta)\n", + j, i); + } + break; + case NOIR: + if (joueur_noir == MINIMAX) { + nb_victoire_minimax++; + printf("Minimax a gagné (profondeur minimax = %d vs %d = " + "profondeur alphabêta)\n", + j, i); + } else { + nb_victoire_alphabeta++; + printf( + "Alpha-bêta a gagné (profondeur minimax = %d vs %d = " + "profondeur alphabêta)\n", + j, i); + } + break; + default: + fprintf(stderr, + "Une erreur est survenue lors des tests de victoire " + "'%c'.\n", + res); + exit(1); + } + + free_jeu(jeu); + free_test_data(test); + } + } + + printf("Nombre totale de parties : %d.\n", nb_tests); + printf("Alpha-bêta a gagné %d fois.\n", nb_victoire_alphabeta); + printf("Minimax a gagné %d fois.\n", nb_victoire_minimax); + printf("Il y a eu %d égalités.\n", nb_egalite); +}