diff --git a/includes/minimax.h b/includes/minimax.h index 7bb6a15..b261b30 100644 --- a/includes/minimax.h +++ b/includes/minimax.h @@ -7,14 +7,14 @@ typedef struct jeu Jeu; -/* Joue le tour d'après l'algorithme Minimax */ +/* Joue le tour d'après l'algorithme minimax */ void action_joueur_minimax(Jeu *jeu, int couleur); -/* Implémentation de Minimax */ -int minimax(int profondeur, Element *position, int joueur, int couleur, - Jeu *jeu); +/* Décide d'une case à jouer via l'algorithme minimax */ +void _action_joueur_minimax(Jeu *jeu, int profondeur, int couleur, int gagnant, + int *ligne, int *colonne, int *score); /* Calcule la valeur heuristique pour un coup */ -int heuristique(Jeton coup_choisi, int couleur, Jeu *jeu); +int heuristique(Jeu *jeu, int couleur); #endif diff --git a/src/minimax.c b/src/minimax.c index bf2cbe3..95ee4bd 100644 --- a/src/minimax.c +++ b/src/minimax.c @@ -1,57 +1,76 @@ #include "../includes/minimax.h" void action_joueur_minimax(Jeu *jeu, int couleur) { - Jeu *jeu_copie = copie_jeu(jeu); - Coups *possibilites = action_possible_joueur(jeu_copie->plateau, couleur); - - int rep_minimax = - minimax(3, possibilites->coups->premier, INT_MAX, couleur, jeu_copie); - - printf("Réponse de minimax: %d\n", rep_minimax); - - free_coups(possibilites); - free_jeu(jeu_copie); - - // Crash temporaire - exit(1); - - int ligne = -1, colonne = -1; + int ligne, colonne, score = INT_MAX; + _action_joueur_minimax(jeu, 3, couleur, couleur, &ligne, &colonne, &score); jeu_joueur(jeu, ligne, colonne, couleur); } -int minimax(int profondeur, Element *position, int joueur, int couleur, - Jeu *jeu) { - if (!position->suivant || profondeur == 0) { - // Position terminale ou profondeur maximale - return heuristique(*position->jeton, joueur, jeu); +void _action_joueur_minimax(Jeu *jeu, int profondeur, int couleur, int gagnant, + int *ligne, int *colonne, int *score) { + + int score_rec, i_rec, j_rec; + Coups *possibilites = action_possible_joueur(jeu->plateau, couleur); + + // Pas de coups possibles + if (!possibilites->taille_liste) { + free(possibilites); + couleur = couleur_ennemi(couleur); + possibilites = action_possible_joueur(jeu->plateau, couleur); + + if (!possibilites->taille_liste) { + *score = heuristique(jeu, gagnant); + free(possibilites); + + return; + } } - for (Element *pi = position; pi; pi = pi->suivant) { - if (joueur == INT_MAX) { - return max(INT_MIN, minimax(profondeur - 1, pi, INT_MIN, - couleur_ennemi(couleur), jeu)); + if (couleur == gagnant) { + *score = INT_MIN; + } else { + *score = INT_MAX; + } + + profondeur--; + for (Element *i = possibilites->coups->premier; i; i = i->suivant) { + Jeu *jeu_copie = copie_jeu(jeu); + if (!jeu_joueur(jeu_copie, i->jeton->pos_i, i->jeton->pos_j, couleur)) { + fprintf(stderr, "Coup illégal.\n"); + exit(EXIT_FAILURE); + } + if (profondeur) { + _action_joueur_minimax(jeu_copie, profondeur, + couleur_ennemi(couleur), gagnant, &i_rec, + &j_rec, &score_rec); } else { - return min(INT_MAX, - minimax(profondeur - 1, pi, INT_MAX, couleur, jeu)); + score_rec = heuristique(jeu_copie, gagnant); + } + if (couleur == gagnant) { // MAX + if (score_rec >= *score) { + // On change notre coup si il est meilleur + *score = score_rec; + *ligne = i->jeton->pos_i; + *colonne = i->jeton->pos_j; + } + + } else { // MIN + if (score_rec <= *score) { + // On change notre coup s'il est + désavantageux pour + // l'adversaire + *score = score_rec; + *ligne = i->jeton->pos_i; + *colonne = i->jeton->pos_j; + } } } - - fprintf(stderr, "Erreur innatendu lors de Minimax."); - exit(EXIT_FAILURE); } -int heuristique(Jeton coup_choisi, int couleur, Jeu *jeu) { - if (jeu_joueur(jeu, coup_choisi.pos_i, coup_choisi.pos_j, couleur)) { - if (jeu->j1->couleur == couleur) { - return jeu->j1->nb_jeton; - } - return jeu->j2->nb_jeton; +int heuristique(Jeu *jeu, int couleur) { + if (jeu->j1->couleur == couleur) { + // Si on est le joueur 1 + return jeu->j1->nb_jeton - jeu->j2->nb_jeton; } - fprintf(stderr, "Coup illégal des %ss en ", - jeu->j1->couleur == couleur ? jeu->j1->nom : jeu->j2->nom); - affiche_jeton(stderr, &coup_choisi); - fprintf(stderr, ".\n"); - - exit(EXIT_FAILURE); + return jeu->j2->nb_jeton - jeu->j1->nb_jeton; }