From 79613e27bc6050d08263d41c9fb8b9f682fc6ea3 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Mon, 21 Nov 2022 00:40:53 +0100 Subject: [PATCH] add alphabeta algorithm --- includes/alphabeta.h | 16 +++++++ src/alphabeta.c | 109 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 includes/alphabeta.h create mode 100644 src/alphabeta.c diff --git a/includes/alphabeta.h b/includes/alphabeta.h new file mode 100644 index 0000000..5b77155 --- /dev/null +++ b/includes/alphabeta.h @@ -0,0 +1,16 @@ +#ifndef OTHELLO_ALPHABETA_H +#define OTHELLO_ALPHABETA_H 1 + +#include + +#include "minimax.h" + +/* Joue le tour d'après l'algorithme alpha-beta */ +void action_joueur_alphabeta(Jeu *jeu, int couleur); + +/* Décide d'une case à jouer via l'algorithme alpha-beta */ +void _action_joueur_alphabeta(Jeu *jeu, int profondeur, int couleur, + int gagnant, int *ligne, int *colonne, int *score, + int note, int qui); + +#endif diff --git a/src/alphabeta.c b/src/alphabeta.c new file mode 100644 index 0000000..6a0e500 --- /dev/null +++ b/src/alphabeta.c @@ -0,0 +1,109 @@ +#include "../includes/alphabeta.h" + +void action_joueur_alphabeta(Jeu *jeu, int couleur) { + int ligne, colonne, score = INT_MAX; + _action_joueur_alphabeta(jeu, 9, couleur, couleur, &ligne, &colonne, &score, + 0, VIDE); + + jeu_joueur(jeu, ligne, colonne, couleur); +} + +void _action_joueur_alphabeta(Jeu *jeu, int profondeur, int couleur, + int gagnant, int *ligne, int *colonne, int *score, + int note, int qui) { + Coups *possibilites = action_possible_joueur(jeu->plateau, couleur); + + if (!possibilites->taille_liste) { + free_coups(possibilites); + couleur = couleur_ennemi(couleur); + possibilites = action_possible_joueur(jeu->plateau, couleur); + + if (!possibilites->taille_liste) { + *score = heuristique(jeu, gagnant); + free_coups(possibilites); + + return; + } + } + + if (couleur == gagnant) { + *score = INT_MIN; + } else { + *score = INT_MAX; + } + + profondeur--; + int score_tmp, i_tmp, j_tmp; + 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_alphabeta(jeu_copie, profondeur, + couleur_ennemi(couleur), gagnant, &i_tmp, + &j_tmp, &score_tmp, *score, couleur); + } else { + score_tmp = heuristique(jeu_copie, gagnant); + } + + if (couleur == gagnant) { + if (qui == couleur_ennemi(gagnant) && score_tmp >= note) { + while (i->suivant) { + if (i->suivant->suivant) { + i = i->suivant; + } else { + break; + } + } + *score = INT_MAX; + } else { + if (score_tmp >= *score) { + *score = score_tmp; + *ligne = i->jeton->pos_i; + *colonne = i->jeton->pos_j; + if (*score == INT_MAX) { + while (i->suivant) { + if (i->suivant->suivant) { + i = i->suivant; + } else { + break; + } + } + } + } + } + } else { + if (qui == gagnant && score_tmp <= note) { + while (i->suivant) { + if (i->suivant->suivant) { + i = i->suivant; + } else { + break; + } + } + *score = INT_MIN; + } else { + if (score_tmp <= *score) { + *score = score_tmp; + *ligne = i->jeton->pos_i; + *colonne = i->jeton->pos_j; + if (*score == INT_MIN) { + while (i->suivant) { + if (i->suivant->suivant) { + i = i->suivant; + } else { + break; + } + } + } + } + } + } + + free_jeu(jeu_copie); + } + + free_coups(possibilites); +}