refactor: .h

This commit is contained in:
Mylloon 2022-11-18 16:35:36 +01:00
parent 94df6620e9
commit 507695d621
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
9 changed files with 271 additions and 242 deletions

15
includes/humain.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef OTHELLO_HUMAN_H
#define OTHELLO_HUMAN_H 1
#include "jeu.h"
#include "joueur.h"
typedef struct jeu Jeu;
/* Joue le tour d'un joueur humain */
void action_joueur_humain(Jeu *jeu, int couleur);
/* Auxiliaire : Demande au joueur où placer son jeton */
void _action_joueur_humain(int *ligne, int *colonne);
#endif

View file

@ -6,13 +6,15 @@
#include "liste.h"
typedef struct joueur Joueur;
/* Une case est soit vide, soit occupé par un des joueurs, noir ou blanc */
enum CASE { VIDE = ' ', BLANC = 'B', NOIR = 'N' };
/* Propriété globale du jeu */
enum PLATEAU { LONGEUR = 8, LARGEUR = 8 };
/* Jeton contenant le type de case (CASE) ainsi que la position */
/* Jeton contenant le type de case (cf. enum CASE) ainsi que la position */
struct jeton {
int couleur;
int pos_i;
@ -23,25 +25,6 @@ typedef struct jeton Jeton;
/* Ajoute un nouveau jeton */
Jeton *ajoute_jeton(int position_i, int position_j, int couleur);
/* Joueur contenant le nom, le type ainsi que sa liste de jeton placé sur le
* plateau */
struct joueur {
char *nom;
int couleur;
Liste *liste_jeton;
int nb_jeton;
};
typedef struct joueur Joueur;
/* Créer un nouveau joueur */
Joueur *nouveau_joueur(int pion);
/* Ajoute un jeton d'un joueur */
void ajoute_jeton_joueur(Joueur *joueur, Jeton *jeton);
/* Retire le jeton d'un joueur */
void retire_jeton_joueur(Joueur *joueur, Jeton *jeton);
/* Jeu contenant nos 2 joueurs et le plateau de jeu */
struct jeu {
Joueur *j1;
@ -56,18 +39,6 @@ Jeu *nouvelle_partie(void);
/* Lance et joue une partie */
void deroulement_partie(Jeu *jeu);
/* Renvoie la couleur de l'ennemi */
int couleur_ennemi(int couleur);
/* Auxiliaire : S'occupe de faire les changements de jetons récursivement
* lorsqu'un joueur joue */
void _jeu_joueur(Jeu *jeu, int case_i, int case_j, int case_i_direction,
int case_j_direction, int couleur);
/* Gère le coup d'un joueur en faisant les changements nécessaire au jeu.
* Renvoie 0 en cas de coup illégal */
int jeu_joueur(Jeu *jeu, int case_i, int case_j, int couleur);
/* Coups possibles d'un joueur */
struct coups {
Liste *coups;
@ -75,25 +46,18 @@ struct coups {
};
typedef struct coups Coups;
/* Libère les coups possibles de la mémoire */
void free_coups(Coups *coups);
/* Vérifie si un joueur peut jouer */
Coups *action_possible_joueur(Jeton *plateau[LONGEUR][LARGEUR], int couleur);
/* Auxiliaire : Demande au joueur où placer son jeton */
void _action_joueur_humain(int *ligne, int *colonne);
/* Joue le tour d'un joueur humain */
void action_joueur_humain(Jeu *jeu, int couleur);
/* Libère les coups possibles de la mémoire */
void free_coups(Coups *coups);
/* Vérifie si une partie est terminée */
int partie_finie(Jeu *jeu);
/* Compte les points, change le résultat avec le gagnant ainsi que les points de
* chacun des joueurs (Gagnant, Perdant)
* Renvoie 0 si égalité entre les 2
* joueurs */
* Renvoie 0 si égalité entre les 2 joueurs */
int selection_gagnant(Jeu *jeu, int *resultat);
/* Libère le jeu de la mémoire */

41
includes/joueur.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef OTHELLO_JOUEUR_H
#define OTHELLO_JOUEUR_H 1
#include "jeu.h"
#include "liste.h"
#include "plateau.h"
typedef struct jeu Jeu;
/* Joueur possédant un nom, une couleur ainsi que sa liste de jeton
* placé sur le plateau */
struct joueur {
char *nom;
int couleur;
Liste *liste_jeton;
int nb_jeton; // permet de facilement savoir qui a gagné
};
typedef struct joueur Joueur;
/* Créer un nouveau joueur */
Joueur *nouveau_joueur(int pion);
/* Ajoute un jeton à un joueur */
void ajoute_jeton_joueur(Joueur *joueur, Jeton *jeton);
/* Retire un jeton à un joueur */
void retire_jeton_joueur(Joueur *joueur, Jeton *jeton);
/* Renvoie la couleur de l'ennemi */
int couleur_ennemi(int couleur);
/* Gère le coup d'un joueur en faisant les changements nécessaire au jeu
* Renvoie 0 en cas de coup illégal */
int jeu_joueur(Jeu *jeu, int case_i, int case_j, int couleur);
/* Auxiliaire : S'occupe de faire les changements de jetons récursivement
* lorsqu'un joueur joue */
void _jeu_joueur(Jeu *jeu, int case_i, int case_j, int case_i_direction,
int case_j_direction, int couleur);
#endif

View file

@ -7,20 +7,20 @@
/* Remplie le plateau avec la configuration de départ */
void remplissage_debut(Jeu *jeu);
/* Auxiliaire : Affiche une suite de lettres */
void _affiche_lettres(void);
/* Affiche le plateau */
void affiche_plateau(Jeton *plateau[LONGEUR][LARGEUR]);
/* Auxiliaire : Vérifie pour une direction si le coup est jouable */
int _case_jouable(Jeton *plat[LONGEUR][LARGEUR], int case_i, int case_j,
int case_i_direction, int case_j_direction, int couleur);
/* Auxiliaire : Affiche une suite de lettres pour l'affichage du plateau */
void _affiche_lettres(void);
/* Vérifie si une case est jouable par un joueur */
int case_jouable(Jeton *plateau[LONGEUR][LARGEUR], int case_i, int case_j,
int couleur);
/* Auxiliaire : Vérifie pour une direction si le coup est légal */
int _case_jouable(Jeton *plat[LONGEUR][LARGEUR], int case_i, int case_j,
int case_i_direction, int case_j_direction, int couleur);
/* Vérifie si le plateau est rempli */
int plateau_rempli(Jeton *plateau[LONGEUR][LARGEUR]);

51
src/humain.c Normal file
View file

@ -0,0 +1,51 @@
#include "../includes/humain.h"
void action_joueur_humain(Jeu *jeu, int couleur) {
int ligne, colonne;
_action_joueur_humain(&ligne, &colonne);
int ok = 0;
while (!ok) {
printf("Vous voulez jouer en %c%d... ", colonne, ligne);
if (!jeu_joueur(jeu, ligne - 1, colonne - 'A', couleur)) {
printf("mais ce n'est pas possible, réessayez !\n");
_action_joueur_humain(&ligne, &colonne);
} else {
printf("et c'est un bon coup ;)\n");
ok = 1;
}
}
}
void _action_joueur_humain(int *ligne, int *colonne) {
// Demande la colonne
int ok = 0;
char tmp;
while (!ok) {
printf("Quelle colonne voulez-vous placer votre jeton (A-H) ? ");
scanf(" %1c", &tmp);
majuscule(&tmp);
if (!(tmp >= 'A' && tmp <= 'H')) {
printf("Colonne renseignée invalide.\n");
} else {
*colonne = tmp;
ok = 1;
}
}
// Demande la ligne
ok = 0, *ligne = 0;
while (!ok) {
printf("Quelle ligne voulez-vous placer votre jeton (1-8) ? ");
scanf(" %1d", ligne);
if (*ligne < 1 || *ligne > LARGEUR) {
printf("Ligne renseignée invalide.\n");
} else {
ok = 1;
}
}
}

145
src/jeu.c
View file

@ -1,4 +1,5 @@
#include "../includes/plateau.h"
#include "../includes/humain.h"
#include "../includes/joueur.h"
Jeton *ajoute_jeton(int pos_i, int pos_j, int couleur) {
Jeton *jeton = malloc(sizeof(Jeton));
@ -9,16 +10,6 @@ Jeton *ajoute_jeton(int pos_i, int pos_j, int couleur) {
return jeton;
}
Joueur *nouveau_joueur(int pion) {
Joueur *joueur = malloc(sizeof(Joueur));
joueur->nom = pion == NOIR ? "noir" : "blanc";
joueur->couleur = pion;
joueur->liste_jeton = nouvelle_liste();
joueur->nb_jeton = 0;
return joueur;
}
Jeu *nouvelle_partie(void) {
Jeu *jeu = malloc(sizeof(Jeu));
jeu->j1 = nouveau_joueur(NOIR);
@ -65,82 +56,6 @@ void deroulement_partie(Jeu *jeu) {
}
}
void _jeu_joueur(Jeu *jeu, int case_i, int case_j, int case_i_direction,
int case_j_direction, int couleur) {
if (case_i + case_i_direction < 0 || case_i + case_i_direction >= LONGEUR ||
case_j + case_j_direction < 0 || case_j + case_j_direction >= LARGEUR) {
// Après une suite de pion ennemi, si l'on arrive à l'extérieur du
// plateau ce n'est pas valide
return;
}
if (jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]
->couleur == couleur_ennemi(couleur)) {
jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]
->couleur = couleur;
Joueur *joueur, *adversaire;
if (couleur == NOIR) {
joueur = jeu->j1;
adversaire = jeu->j2;
} else {
joueur = jeu->j2;
adversaire = jeu->j1;
}
// Retire le jeton de l'adversaire
retire_jeton_joueur(
adversaire,
jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]);
// Ajoute le jeton du joueur
ajoute_jeton_joueur(
joueur,
jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]);
_jeu_joueur(jeu, case_i + case_i_direction, case_j + case_j_direction,
case_i_direction, case_j_direction, couleur);
}
}
int couleur_ennemi(int couleur) { return couleur == NOIR ? BLANC : NOIR; }
int jeu_joueur(Jeu *jeu, int case_i, int case_j, int couleur) {
int flag = 0;
// Coup illégal
if (jeu->plateau[case_i][case_j]->couleur == NOIR ||
jeu->plateau[case_i][case_j]->couleur == BLANC) {
return flag;
}
// Regarde dans toutes les directions
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
if (i != 0 || j != 0) {
if (_case_jouable(jeu->plateau, case_i, case_j, i, j,
couleur) &&
jeu->plateau[case_i + i][case_j + j]->couleur ==
couleur_ennemi(couleur)) {
_jeu_joueur(jeu, case_i, case_j, i, j, couleur);
flag = 1;
}
}
}
}
// Case actuelle
if (flag) {
jeu->plateau[case_i][case_j]->couleur = couleur;
if (couleur == NOIR) {
ajoute_jeton_joueur(jeu->j1, jeu->plateau[case_i][case_j]);
} else {
ajoute_jeton_joueur(jeu->j2, jeu->plateau[case_i][case_j]);
}
}
return flag;
}
Coups *action_possible_joueur(Jeton *plat[LONGEUR][LARGEUR], int couleur) {
Coups *coups = malloc(sizeof(Coups));
coups->coups = nouvelle_liste();
@ -158,54 +73,9 @@ Coups *action_possible_joueur(Jeton *plat[LONGEUR][LARGEUR], int couleur) {
return coups;
}
void _action_joueur_humain(int *ligne, int *colonne) {
// Demande la colonne
int ok = 0;
char tmp;
while (!ok) {
printf("Quelle colonne voulez-vous placer votre jeton (A-H) ? ");
scanf(" %1c", &tmp);
majuscule(&tmp);
if (!(tmp >= 'A' && tmp <= 'H')) {
printf("Colonne renseignée invalide.\n");
} else {
*colonne = tmp;
ok = 1;
}
}
// Demande la ligne
ok = 0, *ligne = 0;
while (!ok) {
printf("Quelle ligne voulez-vous placer votre jeton (1-8) ? ");
scanf(" %1d", ligne);
if (*ligne < 1 || *ligne > LARGEUR) {
printf("Ligne renseignée invalide.\n");
} else {
ok = 1;
}
}
}
void action_joueur_humain(Jeu *jeu, int couleur) {
int ligne, colonne;
_action_joueur_humain(&ligne, &colonne);
int ok = 0;
while (!ok) {
printf("Vous voulez jouer en %c%d... ", colonne, ligne);
if (!jeu_joueur(jeu, ligne - 1, colonne - 'A', couleur)) {
printf("mais ce n'est pas possible, réessayez !\n");
_action_joueur_humain(&ligne, &colonne);
} else {
printf("et c'est un bon coup ;)\n");
ok = 1;
}
}
void free_coups(Coups *coups) {
free_liste(coups->coups);
free(coups);
}
int partie_finie(Jeu *jeu) {
@ -257,8 +127,3 @@ void free_jeu(Jeu *jeu) {
free(jeu);
}
void free_coups(Coups *coups) {
free_liste(coups->coups);
free(coups);
}

109
src/joueur.c Normal file
View file

@ -0,0 +1,109 @@
#include "../includes/joueur.h"
Joueur *nouveau_joueur(int pion) {
Joueur *joueur = malloc(sizeof(Joueur));
joueur->nom = pion == NOIR ? "noir" : "blanc";
joueur->couleur = pion;
joueur->liste_jeton = nouvelle_liste();
joueur->nb_jeton = 0;
return joueur;
}
void ajoute_jeton_joueur(Joueur *joueur, Jeton *jeton) {
// Change le jeton
jeton->couleur = joueur->couleur;
// Ajoute le jeton à la liste des jetons du joueur
Element *element = nouvel_element(jeton);
ajoute_liste(joueur->liste_jeton, element);
joueur->nb_jeton++;
}
void retire_jeton_joueur(Joueur *joueur, Jeton *jeton) {
Element *tmp = joueur->liste_jeton->premier;
if (tmp->jeton == jeton) {
joueur->liste_jeton->premier = tmp->suivant;
free(tmp);
} else {
supprime_liste(tmp, jeton);
}
joueur->nb_jeton--;
jeton->couleur = VIDE;
}
int couleur_ennemi(int couleur) { return couleur == NOIR ? BLANC : NOIR; }
int jeu_joueur(Jeu *jeu, int case_i, int case_j, int couleur) {
int flag = 0;
// Coup illégal
if (jeu->plateau[case_i][case_j]->couleur == NOIR ||
jeu->plateau[case_i][case_j]->couleur == BLANC) {
return flag;
}
// Regarde dans toutes les directions
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
if (i != 0 || j != 0) {
if (_case_jouable(jeu->plateau, case_i, case_j, i, j,
couleur) &&
jeu->plateau[case_i + i][case_j + j]->couleur ==
couleur_ennemi(couleur)) {
_jeu_joueur(jeu, case_i, case_j, i, j, couleur);
flag = 1;
}
}
}
}
// Case actuelle
if (flag) {
jeu->plateau[case_i][case_j]->couleur = couleur;
if (couleur == NOIR) {
ajoute_jeton_joueur(jeu->j1, jeu->plateau[case_i][case_j]);
} else {
ajoute_jeton_joueur(jeu->j2, jeu->plateau[case_i][case_j]);
}
}
return flag;
}
void _jeu_joueur(Jeu *jeu, int case_i, int case_j, int case_i_direction,
int case_j_direction, int couleur) {
if (case_i + case_i_direction < 0 || case_i + case_i_direction >= LONGEUR ||
case_j + case_j_direction < 0 || case_j + case_j_direction >= LARGEUR) {
// Après une suite de pion ennemi, si l'on arrive à l'extérieur du
// plateau ce n'est pas valide
return;
}
if (jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]
->couleur == couleur_ennemi(couleur)) {
jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]
->couleur = couleur;
Joueur *joueur, *adversaire;
if (couleur == NOIR) {
joueur = jeu->j1;
adversaire = jeu->j2;
} else {
joueur = jeu->j2;
adversaire = jeu->j1;
}
// Retire le jeton de l'adversaire
retire_jeton_joueur(
adversaire,
jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]);
// Ajoute le jeton du joueur
ajoute_jeton_joueur(
joueur,
jeu->plateau[case_i + case_i_direction][case_j + case_j_direction]);
_jeu_joueur(jeu, case_i + case_i_direction, case_j + case_j_direction,
case_i_direction, case_j_direction, couleur);
}
}

View file

@ -15,16 +15,6 @@ Liste *nouvelle_liste(void) {
return liste;
}
void ajoute_jeton_joueur(Joueur *joueur, Jeton *jeton) {
// Change le jeton
jeton->couleur = joueur->couleur;
// Ajoute le jeton à la liste des jetons du joueur
Element *element = nouvel_element(jeton);
ajoute_liste(joueur->liste_jeton, element);
joueur->nb_jeton++;
}
void ajoute_liste(Liste *liste, Element *nouveau) {
Element *ptr = liste->premier;
while (ptr) {
@ -34,18 +24,6 @@ void ajoute_liste(Liste *liste, Element *nouveau) {
liste->premier = nouveau;
}
void retire_jeton_joueur(Joueur *joueur, Jeton *jeton) {
Element *tmp = joueur->liste_jeton->premier;
if (tmp->jeton == jeton) {
joueur->liste_jeton->premier = tmp->suivant;
free(tmp);
} else {
supprime_liste(tmp, jeton);
}
joueur->nb_jeton--;
jeton->couleur = VIDE;
}
void supprime_liste(Element *act, Jeton *data) {
if (act->suivant == NULL) {
fprintf(stderr, "Élement introuvable dans la liste\n");

View file

@ -1,6 +1,12 @@
#include "../includes/plateau.h"
#include "../includes/joueur.h"
void remplissage_debut(Jeu *jeu) {
if (LONGEUR * LONGEUR <= 4) {
fprintf(stderr, "Impossible de jouer dans un plateau aussi petit.");
exit(EXIT_FAILURE);
}
for (int i = 0; i < LONGEUR; ++i) {
for (int j = 0; j < LARGEUR; ++j) {
jeu->plateau[i][j] = ajoute_jeton(i, j, VIDE);
@ -17,14 +23,6 @@ void remplissage_debut(Jeu *jeu) {
ajoute_jeton_joueur(jeu->j1, jeu->plateau[LONGEUR / 2][LARGEUR / 2 - 1]);
}
void _affiche_lettres(void) {
printf(" ");
for (int debut = 'A', i = debut; i < LARGEUR + debut; ++i) {
printf(" %c ", i);
}
printf("\n");
}
void affiche_plateau(Jeton *plat[LONGEUR][LARGEUR]) {
// TODO (enhancement): Instead of print instantly, store everything in a
// table and print the whole thing once?
@ -58,31 +56,12 @@ void affiche_plateau(Jeton *plat[LONGEUR][LARGEUR]) {
_affiche_lettres();
}
int _case_jouable(Jeton *plat[LONGEUR][LARGEUR], int case_i, int case_j,
int case_i_direction, int case_j_direction, int couleur) {
if (case_i + case_i_direction < 0 || case_i + case_i_direction >= LONGEUR ||
case_j + case_j_direction < 0 || case_j + case_j_direction >= LARGEUR) {
// Après une suite de pion ennemi, si l'on arrive à l'extérieur du
// plateau ce n'est pas valide
return 0;
void _affiche_lettres(void) {
printf(" ");
for (int debut = 'A', i = debut; i < LARGEUR + debut; ++i) {
printf(" %c ", i);
}
// S'il y a un pion ennemi
if (plat[case_i + case_i_direction][case_j + case_j_direction]->couleur ==
(couleur_ennemi(couleur))) {
return _case_jouable(plat, case_i + case_i_direction,
case_j + case_j_direction, case_i_direction,
case_j_direction, couleur);
}
// Si c'est bon
if (plat[case_i + case_i_direction][case_j + case_j_direction]->couleur ==
couleur) {
return 1;
}
// Couleur vide
return 0;
printf("\n");
}
int case_jouable(Jeton *plat[LONGEUR][LARGEUR], int case_i, int case_j,
@ -111,6 +90,33 @@ int case_jouable(Jeton *plat[LONGEUR][LARGEUR], int case_i, int case_j,
return flag;
}
int _case_jouable(Jeton *plat[LONGEUR][LARGEUR], int case_i, int case_j,
int case_i_direction, int case_j_direction, int couleur) {
if (case_i + case_i_direction < 0 || case_i + case_i_direction >= LONGEUR ||
case_j + case_j_direction < 0 || case_j + case_j_direction >= LARGEUR) {
// Après une suite de pion ennemi, si l'on arrive à l'extérieur du
// plateau ce n'est pas valide
return 0;
}
// S'il y a un pion ennemi
if (plat[case_i + case_i_direction][case_j + case_j_direction]->couleur ==
(couleur_ennemi(couleur))) {
return _case_jouable(plat, case_i + case_i_direction,
case_j + case_j_direction, case_i_direction,
case_j_direction, couleur);
}
// Si c'est bon
if (plat[case_i + case_i_direction][case_j + case_j_direction]->couleur ==
couleur) {
return 1;
}
// Couleur vide
return 0;
}
int plateau_rempli(Jeton *plat[LONGEUR][LARGEUR]) {
for (int i = 0; i < LONGEUR; ++i) {
for (int j = 0; j < LARGEUR; ++j) {