This repository has been archived on 2022-12-11. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
Othello/src/jeu.c
2022-12-04 21:05:28 +01:00

239 lines
7 KiB
C

#include "../includes/alphabeta.h"
#include "../includes/humain.h"
#include "../includes/minimax.h"
const char *joueur_type_str(const enum PLAYER_TYPE type) {
switch (type) {
case HUMAIN:
return "qu'humain";
case MINIMAX:
return "que minimax";
case ALPHABETA:
return "qu'alphabêta";
}
return "";
}
Jeton *ajoute_jeton(const int pos_i, const int pos_j, const int couleur) {
Jeton *jeton = malloc(sizeof(Jeton));
jeton->couleur = couleur;
jeton->pos_i = pos_i;
jeton->pos_j = pos_j;
return jeton;
}
void affiche_jeton(FILE *stream, const Jeton *jeton) {
fprintf(stream, "%c%d", jeton->pos_j + 'A', jeton->pos_i + 1);
}
Jeu *nouvelle_partie(void) {
Jeu *jeu = malloc(sizeof(Jeu));
jeu->j1 = nouveau_joueur(NOIR);
jeu->j2 = nouveau_joueur(BLANC);
remplissage_debut(jeu);
return jeu;
}
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)) {
if (!test->test) {
affiche_plateau(jeu->plateau);
}
Coups *possibilites =
action_possible_joueur(jeu->plateau, tour->couleur);
if (possibilites->taille_liste > 0) {
// Si le joueur peut jouer
if (!test->test) {
printf("Tour des jetons %ss !\n", tour->nom);
}
if (tour->couleur == NOIR) {
switch (type_noir) {
case HUMAIN:
printf("Coups possibles (%d) : ",
possibilites->taille_liste);
affiche_liste(possibilites->coups->premier);
printf("\n");
action_joueur_humain(jeu, tour->couleur);
break;
case MINIMAX:
action_joueur_minimax(jeu, tour->couleur,
test->profondeur_minimax);
break;
case ALPHABETA:
action_joueur_alphabeta(jeu, tour->couleur,
test->profondeur_alphabeta);
break;
default:
fprintf(stderr, "Erreur: Joueur noir non supporté.");
exit(1);
}
} else {
switch (type_blanc) {
case HUMAIN:
printf("Coups possibles (%d) : ",
possibilites->taille_liste);
affiche_liste(possibilites->coups->premier);
printf("\n");
action_joueur_humain(jeu, tour->couleur);
break;
case MINIMAX:
action_joueur_minimax(jeu, tour->couleur,
test->profondeur_minimax);
break;
case ALPHABETA:
action_joueur_alphabeta(jeu, tour->couleur,
test->profondeur_alphabeta);
break;
default:
fprintf(stderr, "Erreur: Joueur blanc non supporté.");
}
}
} else {
if (!test->test) {
printf("Pas de coup jouable.\n");
}
}
free_coups(possibilites);
// On passe la main à l'autre joueur
tour = jeu->j1->couleur == tour->couleur ? jeu->j2 : jeu->j1;
}
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",
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;
}
}
Coups *action_possible_joueur(Jeton *plat[LONGEUR][LARGEUR],
const int couleur) {
Coups *coups = malloc(sizeof(Coups));
coups->coups = nouvelle_liste();
coups->taille_liste = 0;
for (int i = 0; i < LONGEUR; i++) {
for (int j = 0; j < LARGEUR; j++) {
if (case_jouable(plat, i, j, couleur)) {
ajoute_liste(coups->coups, nouvel_element(plat[i][j]));
coups->taille_liste++;
}
}
}
return coups;
}
void free_coups(Coups *coups) {
free_liste(coups->coups);
free(coups);
}
int partie_finie(Jeu *jeu) {
Coups *possibilites_j1 = action_possible_joueur(jeu->plateau, NOIR);
Coups *possibilites_j2 = action_possible_joueur(jeu->plateau, BLANC);
int reponse = ((possibilites_j1->taille_liste == 0) &&
(possibilites_j2->taille_liste == 0)) ||
plateau_rempli(jeu->plateau);
free_coups(possibilites_j1);
free_coups(possibilites_j2);
return reponse;
}
int selection_gagnant(const Jeu *jeu, int *resultat) {
if (jeu->j1->nb_jeton == jeu->j2->nb_jeton) {
// Si égalité
return 0;
}
if (jeu->j1->nb_jeton > jeu->j2->nb_jeton) {
// Si le joueur 1 a gagné
resultat[0] = jeu->j1->couleur;
resultat[1] = jeu->j1->nb_jeton;
resultat[2] = jeu->j2->nb_jeton;
} else {
// Si le joueur 2 a gagné
resultat[0] = jeu->j2->couleur;
resultat[1] = jeu->j2->nb_jeton;
resultat[2] = jeu->j1->nb_jeton;
}
return 1;
}
Jeu *copie_jeu(const Jeu *source) {
Jeu *res = malloc(sizeof(Jeu));
// Copie de J1
res->j1 = malloc(sizeof(Joueur));
res->j1->nom = source->j1->nom;
res->j1->couleur = source->j1->couleur;
res->j1->liste_jeton = copie_liste(source->j1->liste_jeton);
res->j1->nb_jeton = source->j1->nb_jeton;
// Copie de J2
res->j2 = malloc(sizeof(Joueur));
res->j2->nom = source->j2->nom;
res->j2->couleur = source->j2->couleur;
res->j2->liste_jeton = copie_liste(source->j2->liste_jeton);
res->j2->nb_jeton = source->j2->nb_jeton;
// Copie du plateau
for (int i = 0; i < LONGEUR; ++i) {
for (int j = 0; j < LARGEUR; ++j) {
Jeton *jeton = malloc(sizeof(Jeton));
jeton->couleur = source->plateau[i][j]->couleur;
jeton->pos_i = source->plateau[i][j]->pos_i;
jeton->pos_j = source->plateau[i][j]->pos_j;
res->plateau[i][j] = jeton;
}
}
return res;
}
void free_jeu(Jeu *jeu) {
free_liste(jeu->j1->liste_jeton);
free(jeu->j1);
free_liste(jeu->j2->liste_jeton);
free(jeu->j2);
for (int i = 0; i < LONGEUR; ++i) {
for (int j = 0; j < LARGEUR; ++j) {
free(jeu->plateau[i][j]);
}
}
free(jeu);
}