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);
|
||||
|
||||
/* 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 {
|
||||
|
|
|
@ -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
|
||||
|
|
25
src/jeu.c
25
src/jeu.c
|
@ -38,7 +38,7 @@ Jeu *nouvelle_partie(void) {
|
|||
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 Test_Data *test) {
|
||||
Joueur *tour = jeu->j1->couleur == NOIR ? jeu->j1 : jeu->j2;
|
||||
|
@ -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)) {
|
||||
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]);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
96
src/test.c
96
src/test.c
|
@ -1,11 +1,14 @@
|
|||
#include "../includes/jeu.h"
|
||||
#include <stdio.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));
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
Reference in a new issue