add winrate test
This commit is contained in:
parent
f278a49f66
commit
68c7f2824a
5 changed files with 121 additions and 31 deletions
|
@ -47,8 +47,9 @@ typedef struct jeu Jeu;
|
||||||
Jeu *nouvelle_partie(void);
|
Jeu *nouvelle_partie(void);
|
||||||
|
|
||||||
/* Lance et joue une partie */
|
/* Lance et joue une partie */
|
||||||
void deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE noir,
|
enum CASE deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE noir,
|
||||||
const enum PLAYER_TYPE blanc, const Test_Data *test);
|
const enum PLAYER_TYPE blanc,
|
||||||
|
const Test_Data *test);
|
||||||
|
|
||||||
/* Coups possibles d'un joueur */
|
/* Coups possibles d'un joueur */
|
||||||
struct coups {
|
struct coups {
|
||||||
|
|
|
@ -5,17 +5,25 @@
|
||||||
|
|
||||||
struct test_data {
|
struct test_data {
|
||||||
int test;
|
int test;
|
||||||
int profondeur;
|
int profondeur_minimax;
|
||||||
|
int profondeur_alphabeta;
|
||||||
};
|
};
|
||||||
typedef struct test_data Test_Data;
|
typedef struct test_data Test_Data;
|
||||||
|
|
||||||
/* Initialise un 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 */
|
/* Libère un Test_Data de la mémoire */
|
||||||
void free_test_data(Test_Data *test_data);
|
void free_test_data(Test_Data *test_data);
|
||||||
|
|
||||||
/* Run the tests */
|
/* Lance les différents tests */
|
||||||
void run_tests(void);
|
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
|
#endif
|
||||||
|
|
35
src/jeu.c
35
src/jeu.c
|
@ -38,9 +38,9 @@ Jeu *nouvelle_partie(void) {
|
||||||
return jeu;
|
return jeu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE type_noir,
|
enum CASE deroulement_partie(Jeu *jeu, const enum PLAYER_TYPE type_noir,
|
||||||
const enum PLAYER_TYPE type_blanc,
|
const enum PLAYER_TYPE type_blanc,
|
||||||
const Test_Data *test) {
|
const Test_Data *test) {
|
||||||
Joueur *tour = jeu->j1->couleur == NOIR ? jeu->j1 : jeu->j2;
|
Joueur *tour = jeu->j1->couleur == NOIR ? jeu->j1 : jeu->j2;
|
||||||
|
|
||||||
while (!partie_finie(jeu)) {
|
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);
|
action_joueur_humain(jeu, tour->couleur);
|
||||||
break;
|
break;
|
||||||
case MINIMAX:
|
case MINIMAX:
|
||||||
action_joueur_minimax(jeu, tour->couleur, test->profondeur);
|
action_joueur_minimax(jeu, tour->couleur,
|
||||||
|
test->profondeur_minimax);
|
||||||
break;
|
break;
|
||||||
case ALPHABETA:
|
case ALPHABETA:
|
||||||
action_joueur_alphabeta(jeu, tour->couleur,
|
action_joueur_alphabeta(jeu, tour->couleur,
|
||||||
test->profondeur);
|
test->profondeur_alphabeta);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Erreur: Joueur noir non supporté.");
|
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);
|
action_joueur_humain(jeu, tour->couleur);
|
||||||
break;
|
break;
|
||||||
case MINIMAX:
|
case MINIMAX:
|
||||||
action_joueur_minimax(jeu, tour->couleur, test->profondeur);
|
action_joueur_minimax(jeu, tour->couleur,
|
||||||
|
test->profondeur_minimax);
|
||||||
break;
|
break;
|
||||||
case ALPHABETA:
|
case ALPHABETA:
|
||||||
action_joueur_alphabeta(jeu, tour->couleur,
|
action_joueur_alphabeta(jeu, tour->couleur,
|
||||||
test->profondeur);
|
test->profondeur_alphabeta);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Erreur: Joueur blanc non supporté.");
|
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) {
|
if (!test->test) {
|
||||||
affiche_plateau(jeu->plateau);
|
affiche_plateau(jeu->plateau);
|
||||||
|
}
|
||||||
|
|
||||||
int resultat[3];
|
int resultat[3];
|
||||||
if (selection_gagnant(jeu, resultat)) {
|
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",
|
printf("Fin de partie ! Le joueur %s a gagné %d contre %d !\n",
|
||||||
jeu->j1->couleur == resultat[0] ? jeu->j1->nom
|
gagnant->nom, resultat[1], resultat[2]);
|
||||||
: jeu->j2->nom,
|
}
|
||||||
resultat[1], resultat[2]);
|
|
||||||
} else {
|
return gagnant->couleur;
|
||||||
|
} else {
|
||||||
|
if (!test->test) {
|
||||||
printf("Égalité parfaite, %d contre %d !\n", jeu->j1->nb_jeton,
|
printf("Égalité parfaite, %d contre %d !\n", jeu->j1->nb_jeton,
|
||||||
jeu->j2->nb_jeton);
|
jeu->j2->nb_jeton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return VIDE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main(int argc, char const *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Jeu *jeu = nouvelle_partie();
|
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 "
|
printf("Le jeu commence avec les noirs en tant %s et les blancs en "
|
||||||
"tant %s.\n",
|
"tant %s.\n",
|
||||||
|
|
96
src/test.c
96
src/test.c
|
@ -1,11 +1,14 @@
|
||||||
#include "../includes/jeu.h"
|
#include "../includes/jeu.h"
|
||||||
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
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));
|
Test_Data *res = malloc(sizeof(Test_Data));
|
||||||
|
|
||||||
res->test = test;
|
res->test = test;
|
||||||
res->profondeur = profondeur;
|
res->profondeur_minimax = profondeur_minimax;
|
||||||
|
res->profondeur_alphabeta = profondeur_alphabeta;
|
||||||
|
|
||||||
return res;
|
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 free_test_data(Test_Data *test_data) { free(test_data); }
|
||||||
|
|
||||||
void run_tests(void) {
|
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 repetions = 5;
|
||||||
int max_profondeur = 8;
|
|
||||||
int max_profondeur_minimax = 6;
|
|
||||||
|
|
||||||
printf("Lancement des tests, on va jusqu'à une profondeur de %d avec une "
|
printf("Lancement des tests, on va jusqu'à une profondeur de %d avec une "
|
||||||
"moyenne de %d répétitions.\n",
|
"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 "
|
printf("On fait jouer alpha-bêta contre lui-même puis minimax contre "
|
||||||
"lui-même.\n");
|
"lui-même.\n");
|
||||||
|
|
||||||
clock_t t0;
|
clock_t t0;
|
||||||
double delta1, delta2, precedent = 0, actuel = 0;
|
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;
|
delta1 = 0;
|
||||||
for (int j = 0; j < repetions; ++j) {
|
for (int j = 0; j < repetions; ++j) {
|
||||||
Jeu *jeu = nouvelle_partie();
|
Jeu *jeu = nouvelle_partie();
|
||||||
|
|
||||||
Test_Data *test = nouveau_test_data(1, i);
|
Test_Data *test = nouveau_test_data(1, 0, i);
|
||||||
|
|
||||||
t0 = clock();
|
t0 = clock();
|
||||||
|
|
||||||
|
@ -44,17 +50,17 @@ void run_tests(void) {
|
||||||
}
|
}
|
||||||
delta1 /= repetions;
|
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);
|
i, repetions, delta1);
|
||||||
|
|
||||||
if (i < max_profondeur_minimax) {
|
if (i < profondeur_max_minimax) {
|
||||||
// On ne calcul que Minimax avec une petite profondeur parce que
|
// On ne calcul que Minimax avec une petite profondeur parce que
|
||||||
// sinon c'est trop long
|
// sinon c'est trop long
|
||||||
delta2 = 0;
|
delta2 = 0;
|
||||||
for (int j = 0; j < repetions; ++j) {
|
for (int j = 0; j < repetions; ++j) {
|
||||||
Jeu *jeu = nouvelle_partie();
|
Jeu *jeu = nouvelle_partie();
|
||||||
|
|
||||||
Test_Data *test = nouveau_test_data(1, i);
|
Test_Data *test = nouveau_test_data(1, i, 0);
|
||||||
|
|
||||||
t0 = clock();
|
t0 = clock();
|
||||||
|
|
||||||
|
@ -69,10 +75,10 @@ void run_tests(void) {
|
||||||
delta2 /= repetions;
|
delta2 /= repetions;
|
||||||
|
|
||||||
actuel = delta2 - delta1;
|
actuel = delta2 - delta1;
|
||||||
printf("| Minimax = %fs\t | Différence (m - a) = %fs", delta2,
|
printf("| minimax = %fs\t | différence (m - a) = %fs", delta2,
|
||||||
actuel);
|
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);
|
printf("\tavec le précédent = %fs\n", actuel - precedent);
|
||||||
} else {
|
} else {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -80,3 +86,69 @@ void run_tests(void) {
|
||||||
precedent = actuel;
|
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);
|
||||||
|
}
|
||||||
|
|
Reference in a new issue