diff --git a/puissance4_GRB/puissance4.c b/puissance4_GRB/puissance4.c index 3c3a005c7ccfbb3cb0a3208de27020bea595003e..ecf69d6274fe280dfe42aaf7a674e11ecab3f643 100644 --- a/puissance4_GRB/puissance4.c +++ b/puissance4_GRB/puissance4.c @@ -2,14 +2,15 @@ #include <stdint.h> #include <stdio.h> -/*********************************** +/****************************************************************** * function : Create_grid2D * arguments : taille de grille hauteur x largeur * - * return value : cell_t** -> la grille mise à jour et allouée - * initialise les valeurs de la grille - * et alloue la mémoire dynamiquement - ***********************************/ + * return value : cell** -> la grille mise à jour et allouée + * + * Description : initialise les valeurs de la grille et alloue la + * mémoire dynamiquement + ******************************************************************/ struct cell **Create_grid2D(int height, int width){ struct cell** cells = malloc(width*sizeof(struct cell*)); for(int k =0; k<width; k++){ @@ -26,18 +27,19 @@ struct cell **Create_grid2D(int height, int width){ return cells; } -void print_cells(struct cell **cell, int height, int width){ - for(int i=0; i<width; i++){ - for(int j=0; j<height; j++){ - printf("%d, ", cell[i][j].symbol); - } - printf("\n"); - } -} -void print_gameCells(struct game game){ - print_cells(game.cells, game.height, game.width); -} +/****************************************************************** + * function : init_puissance4 + * arguments : la structure du jeu struct game + * hauteur du plateau virtuel + * largeur du plateau virtuel + * + * return value : 0 -> si tout a fonctionné + * -1 -> si erreur + * + * Description : prends le jeu alloué en paramètre, puis l'initialiser + * en tenant compte de la taille du plateau souhaité + ******************************************************************/ int init_puissance4(struct game *game, int height, int width){ if(game == NULL){ return -1; @@ -62,19 +64,84 @@ int init_puissance4(struct game *game, int height, int width){ } } +/****************************************************************** + * function : print_cells + * arguments : le tableau 2D type cell**, hauteur, largeur + * + * return value : - + * Description : affiche simplement le contenu du tableau 2D cell** + ******************************************************************/ +void print_cells(struct cell **cell, int height, int width){ + for(int i=0; i<width; i++){ + for(int j=0; j<height; j++){ + printf("%d, ", cell[i][j].symbol); + } + printf("\n"); + } +} + +/****************************************************************** + * function : print_gameCells + * arguments : structure du jeu "struct game" + * + * return value : - + * Description : affiche le contenu du tableau 2D cell** contenu dans + * la structure game + ******************************************************************/ +void print_gameCells(struct game game){ + print_cells(game.cells, game.height, game.width); +} + +/****************************************************************** + * function : cell_destroy + * arguments : tableau 2D struct cell** + * largeur du tableau + * + * return value : - + * + * Description : détruit et libère la mémoire allouée sur le tableau + * 2D du tableau alloué avec Create_grid2D + ******************************************************************/ void cell_destroy(struct cell **cells, int width){ for(int i=0; i<width; i++){ free(cells[i]); } free(cells); } + +/****************************************************************** + * function : kill_game + * arguments : struct game** (structure du jeu) + * + * return value : 0 -> tout fonctionne + * -1 -> erreur + * + * Description : détruit et libère la mémoire allouée de la structure + * du jeu si non NULL. + ******************************************************************/ int kill_game(struct game **game){ + if(*game==NULL){ + return -1; + } cell_destroy((*game)->cells, (*game)->width); free(*game); *game=NULL; return EXIT_SUCCESS; } +/****************************************************************** + * function : put_free_cell + * arguments : struct game* (structure du jeu) + * int j_p -> colonne sélectionnée par le joueur + * symbol_t symbol -> symbole du joueur + * + * return value : [0-x] -> valeur de la ligne du tableau où placer le jeton + * -1 -> il n'y a pas de case disponible dans la colonne selectionée + * + * Description : place le jeton du joueur correspondant au symbol_t + * dans la case j_p, puis le place dans la dernière case vide si il + * y en a une. + ******************************************************************/ int put_free_cell(struct game *game, int j_p, symbol_t symbol){ int i=0; if((i = is_cell_free(game, j_p, 0, game->players[game->curr_player].symbol)) != -1){ @@ -84,11 +151,19 @@ int put_free_cell(struct game *game, int j_p, symbol_t symbol){ return i; } -/* -retourne la ligne d'une cellule de libre dans une -colonne donnée -(si il y en a une, retourn -1 si il n'y en a aucune) -*/ +/****************************************************************** + * function : is_cell_free + * arguments : struct game* (structure du jeu) + * int j_p -> colonne sélectionnée par le joueur + * int i -> doit être = à 0 au premier appel ! pour la recursion + * symbol_t symbol -> symbole du joueur + * + * return value : [0-x] -> valeur de la ligne du tableau où placer le jeton + * -1 -> il n'y a pas de case disponible dans la colonne selectionée + * + * Description : trouve dans la colonne donnée la ligne disponible + * pour placer le jeton. + ******************************************************************/ int is_cell_free(struct game *game, int j_p, int i, symbol_t symbol){ if(game->cells[j_p][i].symbol == EMPTY){ //retourne la ligne disponible @@ -97,12 +172,20 @@ int is_cell_free(struct game *game, int j_p, int i, symbol_t symbol){ if(i<(game->height-1)){ return is_cell_free(game, j_p, i+1, symbol); }else{ - //printf("il n'y a plus de case de disponible sur cette colonne\n"); return -1; } } } +/****************************************************************** + * function : Launch_puissance4 + * arguments : struct game* (structure du jeu) + * + * return value : retourne le resultat du gagnant de la partie + * ou -1 si il y a une erreur + * + * Description : Jeu du puissance4 en mode 2players (deux joueurs) + ******************************************************************/ int Launch_puissance4(struct game *game){ symbol_t winner=EMPTY; int chiffre=0; @@ -164,6 +247,17 @@ int Launch_puissance4(struct game *game){ return winner; } +/****************************************************************** + * function : Launch_puissance4_randBot + * arguments : struct game* (structure du jeu) + * int seed -> graine de generation pseudo-aléatoire + * + * return value : retourne le resultat du gagnant de la partie + * ou -1 si il y a une erreur + * + * Description : Jeu du puissance4 en mode joueur vs bot, + * mais le bot a un algorithme pseudo aléatoire. + ******************************************************************/ int Launch_puissance4_randBot(struct game *game, int seed){ if(game == NULL){ return -1; @@ -231,6 +325,19 @@ int Launch_puissance4_randBot(struct game *game, int seed){ return winner; } +/****************************************************************** + * function : Launch_puissance4_smartBot + * arguments : struct game* (structure du jeu) + * int seed -> graine de generation pseudo-aléatoire + * + * return value : retourne le resultat du gagnant de la partie + * ou -1 si il y a une erreur + * + * Description : Jeu du puissance4 en mode joueur vs smart-bot, + * le bot peux trouver un coup gagnant si il peux en jouer un, + * bloquer un coup du joueur adversaire si il peux + * sinon, joue en mode pseudo-aléatoire. + ******************************************************************/ int Launch_puissance4_smartBot(struct game *game, int seed){ if(game == NULL){ return -1; @@ -294,6 +401,17 @@ int Launch_puissance4_smartBot(struct game *game, int seed){ return winner; } +/****************************************************************** + * function : SmartBot + * arguments : struct game* (structure du jeu) + * + * return value : retourne le prochain coup joué par le bot + * + * Description : algorithme smartBot utilisé dans le mode de jeu 2 + * le bot peux trouver un coup gagnant si il peux en jouer un, + * bloquer un coup du joueur adversaire si il peux + * sinon, joue en mode pseudo-aléatoire. + ******************************************************************/ int SmartBot(struct game *game){ int pos=0; int chfr1 = -1, chfr2 = -1; @@ -333,21 +451,33 @@ int SmartBot(struct game *game){ } } +/****************************************************************** + * function : Is_Grid_full + * arguments : struct game (structure du jeu) + * + * return value : retourne si la partie est egalité ou non + * (si la grille est pleine ou non) + * + * Description : Lorsque le jeu est lancé, cette fonction est utilisée + * pour savoir si la grille de jeu est pleine (ou si c'est un égalité) + ******************************************************************/ bool Is_Grid_full(struct game game){ return game.gamePlayed == 0; } -/*********************************** +/****************************************************************** * function : Find_winner - * arguments : grid[][], - * cellule jouée, - * taille de grille (ex: 3 pour 3x3) + * arguments : struct game (structure du jeu) + * struct cell** : grille a tester + * struct cell : cellule jouée, * * return value : symbole -> gagnant ou EMPTY - * Cherche si il y a un gagnant, - * (cherche des suites de cases gagnantes) - * !!! Fonctionne avec CheckWin_in_a_direction !!! - ***********************************/ + * + * Description : + * Cherche si il y a un gagnant selon le dernier coup + * joué. + * !!! Fonctionne avec CheckWin_in_a_direction !!! + ******************************************************************/ symbol_t Find_winner(struct game *game, struct cell **grid, struct cell cellPlayed){ //int grid_len = game.height*game.width; int k[4][2]={ @@ -377,18 +507,17 @@ symbol_t Find_winner(struct game *game, struct cell **grid, struct cell cellPlay return EMPTY; // pas de winner pour l'instant } -/*********************************** +/****************************************************************** * function : CheckWin_in_a_direction - * arguments : grid[][], - * cellule jouée, - * taille de grille (ex: 3 pour 3x3) + * arguments : struct game* (structure du jeu) + * int dir[2] : direction 2D où chercher une suite + * struct cell : cellule jouée * * return value : symbole -> gagnant ou EMPTY si non * - * Va chercher des suites de cases gagnantes - * recursivement, dans une seule direction - * à l'aide des var globale cross et circle - ***********************************/ + * Description : Va chercher des suites de cases gagnantes + * recursivement, dans une seule direction selon le dernier jeton joué + ******************************************************************/ symbol_t CheckWin_in_a_direction(struct game *game, int dir[2], struct cell **grid, struct cell cell){ int x1 = cell.i_pos+dir[0]; int x2 = cell.j_pos+dir[1]; @@ -414,6 +543,29 @@ symbol_t CheckWin_in_a_direction(struct game *game, int dir[2], struct cell **gr return result; } +/****************************************************************** + * function : print_game + * arguments : struct game (structure du jeu) + * + * return value : - + * Description : fonction d'affichage du jeu de la manière suivante : + * (ex pour un jeu 6x7) + * ┌─┬─┬─┬─┬─┬─┬─┐ + * │ │ │ │ │ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │ │ │ │ │ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │ │ │ │X│ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │ │ │X│O│ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │O│X│X│O│ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │X│O│X│O│ │ │ │ + * └─┴─┴─┴─┴─┴─┴─┘ + * 1 2 3 4 5 6 7 + * + ******************************************************************/ void print_game(struct game game){ //printf("h:%d, w:%d\n", game.height, game.width); //affiche ┌─┬─┬─┬─┬─┬─┬─┐ diff --git a/puissance4_GRB/puissance4.h b/puissance4_GRB/puissance4.h index 2c244cdac8eb7bafeba07c1e90cb3e7078301295..641240795d87d832e3d940cec70b9e12777a434a 100644 --- a/puissance4_GRB/puissance4.h +++ b/puissance4_GRB/puissance4.h @@ -33,29 +33,220 @@ struct game{ int curr_player; }; -struct cell **Create_grid2D(); //on pourrait peut être créer une autre librairie CELL.h pour gérer les cellules maybe ? +/****************************************************************** + * function : Create_grid2D + * arguments : taille de grille hauteur x largeur + * + * return value : cell** -> la grille mise à jour et allouée + * + * Description : initialise les valeurs de la grille et alloue la + * mémoire dynamiquement + ******************************************************************/ +struct cell **Create_grid2D(int height, int width); -void print_cells(struct cell **cell, int height, int width); -void print_gameCells(struct game game); +/****************************************************************** + * function : init_puissance4 + * arguments : la structure du jeu struct game + * hauteur du plateau virtuel + * largeur du plateau virtuel + * + * return value : 0 -> si tout a fonctionné + * -1 -> si erreur + * + * Description : prends le jeu alloué en paramètre, puis l'initialiser + * en tenant compte de la taille du plateau souhaité + ******************************************************************/ int init_puissance4(struct game *game, int height, int width); -//void Show_grid(struct cell** cell); //partie graphique a venir +/****************************************************************** + * function : print_cells + * arguments : le tableau 2D type cell**, hauteur, largeur + * + * return value : - + * Description : affiche simplement le contenu du tableau 2D cell** + ******************************************************************/ +void print_cells(struct cell **cell, int height, int width); + +/****************************************************************** + * function : print_gameCells + * arguments : structure du jeu "struct game" + * + * return value : - + * Description : affiche le contenu du tableau 2D cell** contenu dans + * la structure game + ******************************************************************/ +void print_gameCells(struct game game); + +/****************************************************************** + * function : cell_destroy + * arguments : tableau 2D struct cell** + * largeur du tableau + * + * return value : - + * + * Description : détruit et libère la mémoire allouée sur le tableau + * 2D du tableau alloué avec Create_grid2D + ******************************************************************/ void cell_destroy(struct cell **cells, int width); + +/****************************************************************** + * function : kill_game + * arguments : struct game** (structure du jeu) + * + * return value : 0 -> tout fonctionne + * -1 -> erreur + * + * Description : détruit et libère la mémoire allouée de la structure + * du jeu si non NULL. + ******************************************************************/ int kill_game(struct game **game); +/****************************************************************** + * function : put_free_cell + * arguments : struct game* (structure du jeu) + * int j_p -> colonne sélectionnée par le joueur + * symbol_t symbol -> symbole du joueur + * + * return value : [0-x] -> valeur de la ligne du tableau où placer le jeton + * -1 -> il n'y a pas de case disponible dans la colonne selectionée + * + * Description : place le jeton du joueur correspondant au symbol_t + * dans la case j_p, puis le place dans la dernière case vide si il + * y en a une. + ******************************************************************/ int put_free_cell(struct game *game, int j_p, symbol_t symbol); + +/****************************************************************** + * function : is_cell_free + * arguments : struct game* (structure du jeu) + * int j_p -> colonne sélectionnée par le joueur + * int i -> doit être = à 0 au premier appel ! pour la recursion + * symbol_t symbol -> symbole du joueur + * + * return value : [0-x] -> valeur de la ligne du tableau où placer le jeton + * -1 -> il n'y a pas de case disponible dans la colonne selectionée + * + * Description : trouve dans la colonne donnée la ligne disponible + * pour placer le jeton. + ******************************************************************/ int is_cell_free(struct game *game, int j_p, int i, symbol_t symbol); + +/****************************************************************** + * function : Launch_puissance4 + * arguments : struct game* (structure du jeu) + * + * return value : retourne le resultat du gagnant de la partie + * ou -1 si il y a une erreur + * + * Description : Jeu du puissance4 en mode 2players (deux joueurs) + ******************************************************************/ int Launch_puissance4(struct game *game); + +/****************************************************************** + * function : Launch_puissance4_randBot + * arguments : struct game* (structure du jeu) + * int seed -> graine de generation pseudo-aléatoire + * + * return value : retourne le resultat du gagnant de la partie + * ou -1 si il y a une erreur + * + * Description : Jeu du puissance4 en mode joueur vs bot, + * mais le bot a un algorithme pseudo aléatoire. + ******************************************************************/ int Launch_puissance4_randBot(struct game *game, int seed); + +/****************************************************************** + * function : Launch_puissance4_smartBot + * arguments : struct game* (structure du jeu) + * int seed -> graine de generation pseudo-aléatoire + * + * return value : retourne le resultat du gagnant de la partie + * ou -1 si il y a une erreur + * + * Description : Jeu du puissance4 en mode joueur vs smart-bot, + * le bot peux trouver un coup gagnant si il peux en jouer un, + * bloquer un coup du joueur adversaire si il peux + * sinon, joue en mode pseudo-aléatoire. + ******************************************************************/ int Launch_puissance4_smartBot(struct game *game, int seed); +/****************************************************************** + * function : SmartBot + * arguments : struct game* (structure du jeu) + * + * return value : retourne le prochain coup joué par le bot + * + * Description : algorithme smartBot utilisé dans le mode de jeu 2 + * le bot peux trouver un coup gagnant si il peux en jouer un, + * bloquer un coup du joueur adversaire si il peux + * sinon, joue en mode pseudo-aléatoire. + ******************************************************************/ int SmartBot(struct game *game); -bool Is_Grid_full(struct game game); -void print_game(struct game game); +/****************************************************************** + * function : Is_Grid_full + * arguments : struct game (structure du jeu) + * + * return value : retourne si la partie est egalité ou non + * (si la grille est pleine ou non) + * + * Description : Lorsque le jeu est lancé, cette fonction est utilisée + * pour savoir si la grille de jeu est pleine (ou si c'est un égalité) + ******************************************************************/ +bool Is_Grid_full(struct game game); +/****************************************************************** + * function : Find_winner + * arguments : struct game (structure du jeu) + * struct cell** : grille a tester + * struct cell : cellule jouée, + * + * return value : symbole -> gagnant ou EMPTY + * + * Description : + * Cherche si il y a un gagnant selon le dernier coup + * joué. + * !!! Fonctionne avec CheckWin_in_a_direction !!! + ******************************************************************/ symbol_t Find_winner(struct game *game, struct cell **grid, struct cell cellPlayed); + +/****************************************************************** + * function : CheckWin_in_a_direction + * arguments : struct game* (structure du jeu) + * int dir[2] : direction 2D où chercher une suite + * struct cell : cellule jouée + * + * return value : symbole -> gagnant ou EMPTY si non + * + * Description : Va chercher des suites de cases gagnantes + * recursivement, dans une seule direction selon le dernier jeton joué + ******************************************************************/ symbol_t CheckWin_in_a_direction(struct game *game, int dir[2], struct cell **grid, struct cell cell); +/****************************************************************** + * function : print_game + * arguments : struct game (structure du jeu) + * + * return value : - + * Description : fonction d'affichage du jeu de la manière suivante : + * (ex pour un jeu 6x7) + * ┌─┬─┬─┬─┬─┬─┬─┐ + * │ │ │ │ │ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │ │ │ │ │ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │ │ │ │X│ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │ │ │X│O│ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │O│X│X│O│ │ │ │ + * ├─┼─┼─┼─┼─┼─┼─┤ + * │X│O│X│O│ │ │ │ + * └─┴─┴─┴─┴─┴─┴─┘ + * 1 2 3 4 5 6 7 + * + ******************************************************************/ +void print_game(struct game game); + #endif \ No newline at end of file diff --git a/puissance4_GRB/unit_tests.c b/puissance4_GRB/unit_tests.c index 545754033bf994c159775ed8c644c2d9ac7aabf7..9fd07b3b027ac958e093834df64a71c7ec7d31c5 100644 --- a/puissance4_GRB/unit_tests.c +++ b/puissance4_GRB/unit_tests.c @@ -131,14 +131,14 @@ int main(){ i = put_free_cell(games, 0, CROSS); i = put_free_cell(games, 4, CIRCLE); printf("return should be : true, returned=%s \n",Is_Grid_full(*games) ? "true":"false" ); - print_game(*games); assert(games->gamePlayed==0); assert(Is_Grid_full(*games)==true); printf("\ngrid overflow passed\n"); - printf("winner test should return equal/empty (2) : returns %d\n",Find_winner(games, games->cells, games->cells[4][i])); + printf("winner test should return EMPTY (2/3) : returns %d\n",Find_winner(games, games->cells, games->cells[4][i])); printf("===================================================\n\n"); + //test de wins(CROIX, CERCLES ou si il y a une suite plus grande que 4) printf("===================================================\n"); games->cells[5][0].symbol = CROSS; assert(Find_winner(games, games->cells, games->cells[5][0])==CROSS); @@ -149,7 +149,7 @@ int main(){ printf("should return CIRCLE wins (0) : returns=%d\n",Find_winner(games, games->cells, games->cells[4][4])); games->cells[4][4].symbol = CROSS; assert(Find_winner(games, games->cells, games->cells[4][4])==EMPTY); - printf("should return EQUAL/EMPTY wins (2) : returns=%d\n",Find_winner(games, games->cells, games->cells[4][4])); + printf("should return EMPTY wins (2) : returns=%d\n",Find_winner(games, games->cells, games->cells[4][4])); games->cells[1][2].symbol = CIRCLE; assert(Find_winner(games, games->cells, games->cells[1][2])==CIRCLE); printf("should return CIRCLE wins (0) : returns=%d\n",Find_winner(games, games->cells, games->cells[1][2])); @@ -157,9 +157,5 @@ int main(){ printf("===================================================\n\n"); kill_game(&games); printf("Tests tous reussis !\n"); - //test de detection de wins - //test is cell free - //test put cells ?? (pas obligé je dis) - // return EXIT_SUCCESS; } \ No newline at end of file