From ac9750ccf7bc2ab02789f504131c8e3e6cf0e747 Mon Sep 17 00:00:00 2001 From: "remi.greub" <remi.greub@hes-so.ch> Date: Thu, 3 Apr 2025 22:22:22 +0200 Subject: [PATCH] =?UTF-8?q?am=C3=A9lioration=20de=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- puissance4_GRB/main.c | 12 +- puissance4_GRB/puissance4.c | 233 +++++++++++++++++++----------------- puissance4_GRB/puissance4.h | 34 +++--- 3 files changed, 147 insertions(+), 132 deletions(-) diff --git a/puissance4_GRB/main.c b/puissance4_GRB/main.c index 38598c5..735f13b 100644 --- a/puissance4_GRB/main.c +++ b/puissance4_GRB/main.c @@ -10,7 +10,7 @@ int main(int argc, char** argv){ printf("il manque des arguments\n"); return EXIT_FAILURE; } - int mode = atoi(argv[1]); //a gérer pour plus tard... + int mode = atoi(argv[1]); int width = 0; int height = atoi(argv[2]); if(argc < 4){ @@ -20,18 +20,18 @@ int main(int argc, char** argv){ } printf("Board size is %dx%d (rows x col)\n",height,width); - - init_puissance4(height, width); + struct game game; + init_puissance4(&game, height, width); switch (mode) { case 1: - Launch_puissance4_randBot(0); + Launch_puissance4_randBot(&game, 0); break; case 2: - Launch_puissance4_smartBot(0); + Launch_puissance4_smartBot(&game, 0); break; case 3: - Launch_puissance4(); + Launch_puissance4(&game); break; default: diff --git a/puissance4_GRB/puissance4.c b/puissance4_GRB/puissance4.c index 50bd5ba..76716c2 100644 --- a/puissance4_GRB/puissance4.c +++ b/puissance4_GRB/puissance4.c @@ -2,8 +2,6 @@ #include <stdint.h> #include <stdio.h> -grid game; - /*********************************** * function : Create_grid2D * arguments : taille de grille hauteur x largeur @@ -12,14 +10,14 @@ grid game; * initialise les valeurs de la grille * et alloue la mémoire dynamiquement ***********************************/ -struct cell **Create_grid2D(){ - struct cell** cells = malloc(game.width*sizeof(struct cell*)); - for(int k =0; k<game.width; k++){ - cells[k] = malloc(game.height*sizeof(struct cell)); +struct cell **Create_grid2D(int height, int width){ + struct cell** cells = malloc(width*sizeof(struct cell*)); + for(int k =0; k<width; k++){ + cells[k] = malloc(height*sizeof(struct cell)); } //initialise les positions et les valeurs de base - for(int i = 0; i<game.width; i++){ - for(int j=0; j<game.height; j++){ + for(int i = 0; i<width; i++){ + for(int j=0; j<height; j++){ cells[i][j].symbol = EMPTY; cells[i][j].i_pos = i; cells[i][j].j_pos = j; @@ -28,50 +26,59 @@ struct cell **Create_grid2D(){ return cells; } -void print_cells(struct cell **cell){ - for(int i=0; i<game.width; i++){ - for(int j=0; j<game.height; j++){ +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(){ - print_cells(game.cells); +void print_gameCells(struct game game){ + print_cells(game.cells, game.height, game.width); } -void init_puissance4(int height, int width){ - game.players[1].check_win = 0; - game.players[1].score = 0; - game.players[1].symbol = CIRCLE; +int init_puissance4(struct game *game, int height, int width){ + if(game == NULL){ + return -1; + } + if(height > 3 || width > 3){ + game->players[1].check_win = 0; + game->players[1].score = 0; + game->players[1].symbol = CIRCLE; - game.players[0].check_win = 0; - game.players[0].score = 0; - game.players[0].symbol = CROSS; + game->players[0].check_win = 0; + game->players[0].score = 0; + game->players[0].symbol = CROSS; - game.curr_player = 0; - game.height = height; - game.width = width; - game.gamePlayed = height*width; - game.cells = Create_grid2D(); + game->curr_player = 0; + game->height = height; + game->width = width; + game->gamePlayed = height*width; + game->cells = Create_grid2D(height, width); + return 0; + }else{ + return -1; + } } -void cell_destroy(struct cell **cells, int height){ - for(int i=0; i<height; i++){ +void cell_destroy(struct cell **cells, int width){ + for(int i=0; i<width; i++){ free(cells[i]); } free(cells); } -int kill_game(){ - cell_destroy(game.cells, game.height); +int kill_game(struct game **game){ + cell_destroy((*game)->cells, (*game)->width); + free(*game); + *game=NULL; return EXIT_SUCCESS; } - -int put_free_cell(int j_p, symbol_t symbol){ +int put_free_cell(struct game *game, int j_p, symbol_t symbol){ int i=0; - if((i = is_cell_free(j_p, 0, game.players[game.curr_player].symbol)) != -1){ - game.cells[j_p][i].symbol = symbol; + if((i = is_cell_free(game, j_p, 0, game->players[game->curr_player].symbol)) != -1){ + game->cells[j_p][i].symbol = symbol; } return i; } @@ -81,13 +88,13 @@ 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) */ -int is_cell_free(int j_p, int i, symbol_t symbol){ - if(game.cells[j_p][i].symbol == EMPTY){ +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 return i; }else{ - if(i<(game.height-1)){ - return is_cell_free(j_p, i+1, 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; @@ -95,209 +102,217 @@ int is_cell_free(int j_p, int i, symbol_t symbol){ } } -int Launch_puissance4(){ +int Launch_puissance4(struct game *game){ symbol_t winner=EMPTY; int chiffre=0; - + if(game == NULL){ + return -1; + } while(winner==EMPTY){ - print_game(); + print_game(*game); printf("Column number? (starts at 1):\n"); do{ scanf("%d",&chiffre); chiffre-=1; //gestion des chiffres de 1 à n et non de 0 à n-1 - if(chiffre >= game.width || chiffre < 0){ + if(chiffre >= game->width || chiffre < 0){ printf("HEP HEPHEP !! donne un chiffre dans la plage de chiffres indiquée !\n"); } - }while((chiffre >= game.width) || (chiffre < 0) || is_cell_free(chiffre, 0, game.players[game.curr_player].symbol)<0); + }while((chiffre >= game->width) || (chiffre < 0) || is_cell_free(game, chiffre, 0, game->players[game->curr_player].symbol)<0); - game.gamePlayed -= 1; //Complément de verbe du code + game->gamePlayed -= 1; //Complément de verbe du code int i = 0; //verifier que put free cell fonctionne - if((i = put_free_cell(chiffre, game.players[game.curr_player].symbol))<0){ - if(Is_Grid_full()){ + if((i = put_free_cell(game, chiffre, game->players[game->curr_player].symbol))<0){ + if(Is_Grid_full(*game)){ //print egalite mais y a probablement eu un bug printf("y a un egalite mais probablement un bug\n"); //fin du jeu return EQUAL; }else{ printf("la y a un bug, faut check ca \n"); - print_game(); + print_game(*game); //fin du jeu return -1; //retourne une erreur } } //check le winner - winner = Find_winner(game.cells, game.cells[chiffre][i]); + winner = Find_winner(game, game->cells, game->cells[chiffre][i]); if( winner != EMPTY){ if(winner==CROSS){ //reset du jeu + mise a jour des scores (scores optionels) - print_game(); + print_game(*game); printf("Player one won!\n"); return CROSS; } if(winner==CIRCLE){ //reset du jeu + mise a jour des scores (scores optionels) - print_game(); + print_game(*game); printf("Player two won!\n"); return CIRCLE; } }else{ //sois le jeu est plein, sois y a juste pas encore de winner - if(Is_Grid_full()){ + if(Is_Grid_full(*game)){ //la grille est pleine - print_game(); + print_game(*game); printf("It is a draw.\n"); return EQUAL; } //y a juste pas encore de winner ducoup... - game.curr_player ^= 1; //switch de joueur + game->curr_player ^= 1; //switch de joueur } } return winner; } -int Launch_puissance4_randBot(int seed){ +int Launch_puissance4_randBot(struct game *game, int seed){ + if(game == NULL){ + return -1; + } symbol_t winner=EMPTY; int chiffre=0; srand(seed); while(winner==EMPTY){ - print_game(); - if(game.curr_player == 1){ + print_game(*game); + if(game->curr_player == 1){ do{ - chiffre = rand()%game.width; - }while((is_cell_free(chiffre, 0, game.players[game.curr_player].symbol))<0); + chiffre = rand()%game->width; + }while((is_cell_free(game, chiffre, 0, game->players[game->curr_player].symbol))<0); }else{ printf("Column number? (starts at 1):\n"); do{ scanf("%d",&chiffre); chiffre-=1; //gestion des chiffres de 1 à n et non de 0 à n-1 - if(chiffre >= game.width || chiffre < 0){ + if(chiffre >= game->width || chiffre < 0){ printf("HEP HEPHEP !! donne un chiffre dans la plage de chiffres indiquée !\n"); } - }while((chiffre >= game.width) || (chiffre < 0) || is_cell_free(chiffre, 0, game.players[game.curr_player].symbol)<0); + }while((chiffre >= game->width) || (chiffre < 0) || is_cell_free(game, chiffre, 0, game->players[game->curr_player].symbol)<0); } - game.gamePlayed -= 1; + game->gamePlayed -= 1; int i = 0; //verifier que put free cell fonctionne - if((i = put_free_cell(chiffre, game.players[game.curr_player].symbol))<0){ - if(Is_Grid_full()){ + if((i = put_free_cell(game, chiffre, game->players[game->curr_player].symbol))<0){ + if(Is_Grid_full(*game)){ printf("y a un egalite mais probablement un bug\n"); return EQUAL; //jeu egal ou retourner un bug ... a voir.. }else{ printf("ok la y a un bug de zinzin check ca \n"); - print_game(); + print_game(*game); //fin du jeu return -1; //erreur } } //check de la win - winner = Find_winner(game.cells, game.cells[chiffre][i]); + winner = Find_winner(game, game->cells, game->cells[chiffre][i]); if( winner != EMPTY){ if(winner==CROSS){ - print_game(); + print_game(*game); printf("Player one won!\n"); //fin du jeu return CROSS; } if(winner==CIRCLE){ - print_game(); + print_game(*game); printf("Computer won!\n"); //fin du jeu return CIRCLE; } }else{ //sois le jeu est plein, sois y a juste pas encore de winner - if(Is_Grid_full()){ - print_game(); + if(Is_Grid_full(*game)){ + print_game(*game); printf("It is a draw.\n"); //fin du jeu return EQUAL; } //y a juste pas encore de winner ducoup... - game.curr_player ^= 1; //switch de joueur + game->curr_player ^= 1; //switch de joueur } } return winner; } -int Launch_puissance4_smartBot(int seed){ +int Launch_puissance4_smartBot(struct game *game, int seed){ + if(game == NULL){ + return -1; + } symbol_t winner=EMPTY; int chiffre=0; srand(seed); while(winner==EMPTY){ - print_game(); - if(game.curr_player == 1){ - chiffre = SmartBot(); + print_game(*game); + if(game->curr_player == 1){ + chiffre = SmartBot(game); }else{ printf("Column number? (starts at 1):\n"); do{ scanf("%d",&chiffre); chiffre-=1; //gestion des chiffres de 1 à n et non de 0 à n-1 - if(chiffre >= game.width || chiffre < 0){ + if(chiffre >= game->width || chiffre < 0){ printf("HEP HEPHEP !! donne un chiffre dans la plage de chiffres indiquée !\n"); } - }while((chiffre >= game.width) || (chiffre < 0) || is_cell_free(chiffre, 0, game.players[game.curr_player].symbol)<0); + }while((chiffre >= game->width) || (chiffre < 0) || is_cell_free(game, chiffre, 0, game->players[game->curr_player].symbol)<0); } - game.gamePlayed -= 1; + game->gamePlayed -= 1; int i = 0; //verifier que put free cell fonctionne - if((i = put_free_cell(chiffre, game.players[game.curr_player].symbol))<0){ - if(Is_Grid_full()){ + if((i = put_free_cell(game, chiffre, game->players[game->curr_player].symbol))<0){ + if(Is_Grid_full(*game)){ printf("y a un egalite mais probablement un bug\n"); //fin du jeu return EQUAL; //jeu egal ou retourner un bug ... a voir.. }else{ printf("il y a un bug, faut check ca \n"); - print_game(); + print_game(*game); //fin du jeu return -1; //erreur } } //check de la win - winner = Find_winner(game.cells, game.cells[chiffre][i]); + winner = Find_winner(game, game->cells, game->cells[chiffre][i]); if( winner != EMPTY){ if(winner==CROSS){ - print_game(); + print_game(*game); printf("Player one won!\n"); return CROSS; } if(winner==CIRCLE){ - print_game(); + print_game(*game); printf("Computer won!\n"); return CIRCLE; } }else{ //sois le jeu est plein, sois y a juste pas encore de winner - if(Is_Grid_full()){ - print_game(); + if(Is_Grid_full(*game)){ + print_game(*game); printf("It is a draw.\n"); return EQUAL; } //y a juste pas encore de winner ducoup... - game.curr_player ^= 1; //switch de joueur + game->curr_player ^= 1; //switch de joueur } } return winner; } -int SmartBot(){ +int SmartBot(struct game *game){ int pos=0; int chfr1 = -1, chfr2 = -1; - for(int chfr=0; chfr<game.width; chfr++){ + for(int chfr=0; chfr<game->width; chfr++){ //verifie que le coup est jouable - if((pos = put_free_cell(chfr, game.players[game.curr_player].symbol))>=0){ - struct cell *tempCell = &game.cells[chfr][pos]; - tempCell->symbol = game.players[game.curr_player].symbol; - if (Find_winner(game.cells, game.cells[chfr][pos]) == game.players[game.curr_player].symbol){ + if((pos = put_free_cell(game, chfr, game->players[game->curr_player].symbol))>=0){ + struct cell *tempCell = &game->cells[chfr][pos]; + tempCell->symbol = game->players[game->curr_player].symbol; + if (Find_winner(game, game->cells, game->cells[chfr][pos]) == game->players[game->curr_player].symbol){ //1er cas : a trouvé le bon coup à jouer pour gagner tempCell->symbol = EMPTY; chfr1 = chfr; } //tente de chercher si l'autre joueur a un coup gagnant - tempCell->symbol = game.players[game.curr_player^1].symbol; - if (Find_winner(game.cells, game.cells[chfr][pos]) == game.players[game.curr_player^1].symbol){ + tempCell->symbol = game->players[game->curr_player^1].symbol; + if (Find_winner(game, game->cells, game->cells[chfr][pos]) == game->players[game->curr_player^1].symbol){ //2e cas : joue le coup gagnant de l'autre joueur pour le bloquer tempCell->symbol = EMPTY; chfr2 = chfr; @@ -313,13 +328,13 @@ int SmartBot(){ //3e cas : joue un coup au hasard int randomchfr=0; do{ - randomchfr = rand()%game.width; - }while((is_cell_free(randomchfr, 0, game.players[game.curr_player].symbol))<0); + randomchfr = rand()%game->width; + }while((is_cell_free(game, randomchfr, 0, game->players[game->curr_player].symbol))<0); return randomchfr; } } -bool Is_Grid_full(){ +bool Is_Grid_full(struct game game){ return game.gamePlayed == 0; } @@ -334,7 +349,7 @@ bool Is_Grid_full(){ * (cherche des suites de cases gagnantes) * !!! Fonctionne avec CheckWin_in_a_direction !!! ***********************************/ -symbol_t Find_winner(struct cell **grid, struct cell cellPlayed){ +symbol_t Find_winner(struct game *game, struct cell **grid, struct cell cellPlayed){ //int grid_len = game.height*game.width; int k[4][2]={ {0,1}, @@ -351,11 +366,11 @@ symbol_t Find_winner(struct cell **grid, struct cell cellPlayed){ symbol_t result; for(int i=0; i<4; i++){ //à savoir, il est impossible que le cellPlayed soit empty !! - result = CheckWin_in_a_direction(k[i], grid, grid[cellPlayed.i_pos][cellPlayed.j_pos]); + result = CheckWin_in_a_direction(game, k[i], grid, grid[cellPlayed.i_pos][cellPlayed.j_pos]); if(result != EMPTY){return result;} - result = CheckWin_in_a_direction(k2[i], grid, grid[cellPlayed.i_pos][cellPlayed.j_pos]); - game.players[0].check_win = 0; - game.players[1].check_win = 0; + result = CheckWin_in_a_direction(game, k2[i], grid, grid[cellPlayed.i_pos][cellPlayed.j_pos]); + game->players[0].check_win = 0; + game->players[1].check_win = 0; if(result != EMPTY){ return result; //si il trouve un winner, alors il stoppe la fonction :) } @@ -375,32 +390,32 @@ symbol_t Find_winner(struct cell **grid, struct cell cellPlayed){ * recursivement, dans une seule direction * à l'aide des var globale cross et circle ***********************************/ -symbol_t CheckWin_in_a_direction(int dir[2], struct cell **grid, struct cell cell){ +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]; symbol_t result = EMPTY; - if(x1<game.width && x1>=0 && x2<game.height && x2>=0){ + if(x1<game->width && x1>=0 && x2<game->height && x2>=0){ if(grid[x1][x2].symbol==cell.symbol){ if(cell.symbol == CIRCLE){ - game.players[0].check_win += 1; + game->players[0].check_win += 1; }else{ - game.players[1].check_win += 1; + game->players[1].check_win += 1; } - if(game.players[0].check_win>=3){ + if(game->players[0].check_win>=3){ return CIRCLE; //circle win } - else if(game.players[1].check_win>=3){ + else if(game->players[1].check_win>=3){ return CROSS; //cross win }else{ - result = CheckWin_in_a_direction(dir, grid, grid[x1][x2]); + result = CheckWin_in_a_direction(game, dir, grid, grid[x1][x2]); } } } return result; } -void print_game(){ +void print_game(struct game game){ //printf("h:%d, w:%d\n", game.height, game.width); //affiche ┌─┬─┬─┬─┬─┬─┬─┐ for(int i=0; i<(game.width*2)+1; i++){ diff --git a/puissance4_GRB/puissance4.h b/puissance4_GRB/puissance4.h index 3f1ebe9..2c244cd 100644 --- a/puissance4_GRB/puissance4.h +++ b/puissance4_GRB/puissance4.h @@ -24,38 +24,38 @@ struct player{ int check_win; }; -typedef struct grid{ +struct game{ int height; int width; int gamePlayed; struct cell** cells; struct player players[2]; int curr_player; -}grid; +}; struct cell **Create_grid2D(); //on pourrait peut être créer une autre librairie CELL.h pour gérer les cellules maybe ? -void print_cells(struct cell **cell); -void print_gameCells(); +void print_cells(struct cell **cell, int height, int width); +void print_gameCells(struct game game); -void init_puissance4(int height, int width); +int init_puissance4(struct game *game, int height, int width); //void Show_grid(struct cell** cell); //partie graphique a venir -void cell_destroy(struct cell **cells, int height); -int kill_game(); +void cell_destroy(struct cell **cells, int width); +int kill_game(struct game **game); -int put_free_cell(int j_p, symbol_t symbol); -int is_cell_free(int j_p, int i, symbol_t symbol); -int Launch_puissance4(); -int Launch_puissance4_randBot(int seed); -int Launch_puissance4_smartBot(int seed); +int put_free_cell(struct game *game, int j_p, symbol_t symbol); +int is_cell_free(struct game *game, int j_p, int i, symbol_t symbol); +int Launch_puissance4(struct game *game); +int Launch_puissance4_randBot(struct game *game, int seed); +int Launch_puissance4_smartBot(struct game *game, int seed); -int SmartBot(); -bool Is_Grid_full(); +int SmartBot(struct game *game); +bool Is_Grid_full(struct game game); -void print_game(); +void print_game(struct game game); -symbol_t Find_winner(struct cell **grid, struct cell cellPlayed); -symbol_t CheckWin_in_a_direction(int dir[2], struct cell **grid, struct cell cell); +symbol_t Find_winner(struct game *game, struct cell **grid, struct cell cellPlayed); +symbol_t CheckWin_in_a_direction(struct game *game, int dir[2], struct cell **grid, struct cell cell); #endif \ No newline at end of file -- GitLab