From 363615cefb383b173e72f394535e1eb4380669d6 Mon Sep 17 00:00:00 2001 From: Sabrina <sabrinalap98@gmail.com> Date: Fri, 4 Apr 2025 21:36:57 +0200 Subject: [PATCH] add comments --- src/board.c | 48 +++++++++++++++++++++++++++++++++------ src/main.c | 44 ++++++++++++++++++++++-------------- src/randomAI.c | 25 +++++++++++++++------ src/smartAI.c | 57 ++++++++++++++++++++--------------------------- src/smartAI.h | 4 ++-- src/twoPlayers.c | 4 ++++ src/winnerCheck.c | 38 +++++++++++++++++++++++++------ 7 files changed, 147 insertions(+), 73 deletions(-) diff --git a/src/board.c b/src/board.c index 20bad7f..8dfc05a 100644 --- a/src/board.c +++ b/src/board.c @@ -1,27 +1,46 @@ #include "board.h" +/** + * Create the board of the game + * @param int width of the board + * @param int height of the board + * @return return the created board + */ struct board create_board(int col, int line){ struct board board; - board.data = malloc(sizeof(struct board) * line); + board.data = malloc(sizeof(struct board) * line); // Dynamically allocates memory for the board height for(int i = 0; i < line; i++){ - board.data[i] = malloc(sizeof(struct board)*col); + board.data[i] = malloc(sizeof(struct board)*col); // Dynamically allocates memory for the board width for each board line } + // Filling the different members of the struct board.col = col; board.line = line; board.last_pos_x = -1; board.last_pos_y = -1; board.last_symbole = Vide; + return board; } + +/** + * Initilize the board with the enum "Empty" + * @param struct the pointer of the game board + * @return no return + */ void init_board(struct board *board){ for(int i = 0; i < board->line;i++){ for(int j = 0; j < board->col; j++){ - board->data[i][j] = Vide; + board->data[i][j] = Vide; // Each cases get enum "Empty" } } } +/** + * Print the game board + * @param struct the pointer of the game board + * @return no return + */ void print_game(struct board *board){ printf("┌"); for(int i = 1; i < board->col; i++){ @@ -64,18 +83,29 @@ void print_game(struct board *board){ printf("\n"); } +/** + * Look the next empty case of a column + * @param struct the game board + * @param int number of the colmun to look + * @return return the line of the next empty case + */ int current_line(struct board board, int no_col){ int no_line = board.line - 1; - while (no_line >= 0 && board.data[no_line][no_col] != Vide) { + while (no_line >= 0 && board.data[no_line][no_col] != Vide) { // Decrement no_line while the next case is not empty and no_line is bigger then 0 no_line--; } return no_line; } +/** + * Look if the board is full + * @param struct the game board + * @return return if the board is full or not + */ bool is_full_board(struct board board){ for(int i = 0; i < board.line; i++){ for(int j = 0; j < board.col; j++){ - if(board.data[i][j] == Vide){ + if(board.data[i][j] == Vide){ // if one of case is empty, we return false return false; } } @@ -83,10 +113,14 @@ bool is_full_board(struct board board){ return true; } +/** + * Free the game board when the game is over + * @param struct the pointer of the game board + */ void free_board(struct board *board){ for(int i = 0; i < board->line;i++){ - free(board->data[i]); + free(board->data[i]); // free the width of lines } - free(board->data); + free(board->data); // free lines } diff --git a/src/main.c b/src/main.c index 3acfb6d..ac3077a 100644 --- a/src/main.c +++ b/src/main.c @@ -4,23 +4,33 @@ #include "smartAI.h" int main(int argc, char **argv){ - srand(0); - struct board board = create_board(atoi(argv[3]), atoi(argv[2])); - init_board(&board); - printf("Board size is %dx%d (rows x col)\n", board.line, board.col); - print_game(&board); - switch (atoi(argv[1])) - { - case 1: - play_with_randomAI(board); - break; - case 2: - play_with_smartAI(board); - break; - case 3: - play_two_players(board); - break; + if(argc != 4){ + printf("Usage: puissance4 <mode> <row> <col>\n"); + printf("mode "); + printf("specifies the mode: 1 = single player game (random),\n 2 = single player game (AI), 3 = two players game\n"); + printf("row specifies the number of rows (>= 4)\n"); + printf("col specifies the number of columns (>= 4)\n"); + } + else{ + srand(0); // seed for random + + struct board board = create_board(atoi(argv[3]), atoi(argv[2])); + init_board(&board); + printf("Board size is %dx%d (rows x col)\n", board.line, board.col); + print_game(&board); + switch (atoi(argv[1])) // Select a game mode between randomAI, smartAI or two players + { + case 1: + play_with_randomAI(board); + break; + case 2: + play_with_smartAI(board); + break; + case 3: + play_two_players(board); + break; + } + free_board(&board); } - free_board(&board); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/randomAI.c b/src/randomAI.c index 2daa95f..b1cb970 100644 --- a/src/randomAI.c +++ b/src/randomAI.c @@ -1,28 +1,38 @@ #include "randomAI.h" +/** + * Actions for play with a random AI + * @param struct the game board + * @return no return + */ void play_with_randomAI(struct board board){ - int no_col = 0; + int no_col = 0; int no_line = 0; int no_round = 1; - while(!is_full_board(board)){ - if(no_round % 2 != 0){ + + while(!is_full_board(board)){ // While the board is not full + if(no_round % 2 != 0){ // For the player and the random AI play alternating printf("Column number? (starts at 1):"); scanf("%d", &no_col); printf("\n"); + no_line = current_line(board,no_col - 1); - board.data[no_line][no_col - 1] = Croix; + board.data[no_line][no_col - 1] = Croix; // Put the player's piece (Cross) in the board board.last_symbole = Croix; } else{ no_col = rand() % 7 + 1; no_line = current_line(board,no_col - 1); - board.data[no_line][no_col - 1] = Cercle; + board.data[no_line][no_col - 1] = Cercle; // Put the random AI's (Circle) piece in the board board.last_symbole = Cercle; } + board.last_pos_x = no_line; board.last_pos_y = no_col - 1; + print_game(&board); - if(winner(board)){ + + if(winner(board)){ // Check if there is a winner after each placement of a piece if(board.last_symbole == Croix){ printf("Player one won!\n"); } @@ -31,7 +41,8 @@ void play_with_randomAI(struct board board){ } break; } - no_round++; + + no_round++; // Increment no_round for the next round } if(is_full_board(board)){ printf("It is a draw.\n"); diff --git a/src/smartAI.c b/src/smartAI.c index 411a919..26a526f 100644 --- a/src/smartAI.c +++ b/src/smartAI.c @@ -1,23 +1,23 @@ #include "smartAI.h" -int is_possible_to_win(struct board *board){ +/** + * Simulation for the piece placement AI to see if it can win on the next round + * @param struct the pointer of the game board + * @return return 0 if AI can win on the next round, 0 if it can't win + */ +int simulate_for_win(struct board *board){ int no_line = -1; for(int i = 0; i < board->col; i++){ - //printf("Colonne %d : %d\n", i, no_line); no_line = current_line(*board, i); - //printf("Colonne %d : %d\n", i, no_line); - - //printf("%d\n", no_line); if(board->data[no_line][i] == Vide){ - board->data[no_line][i] = Cercle; + board->data[no_line][i] = Cercle; // Simulation to put a AI piece in the game board->last_symbole = Cercle; board->last_pos_x = no_line; board->last_pos_y = i; - //printf("Case %d, Symbole %d, x %d, y %d\n\n", board.data[no_line][i], board.last_symbole, board.last_pos_x, board.last_pos_y); - if(winner(*board)){ + if(winner(*board)){ // if AI can win, we leave the simulated piece return 0; } - board->data[no_line][i] = Vide; + board->data[no_line][i] = Vide; // Else, we remove the piece board->last_symbole = Vide; board->last_pos_x = -1; board->last_pos_y = -1; @@ -27,25 +27,29 @@ int is_possible_to_win(struct board *board){ return -1; } -int is_possible_to_block_player(struct board *board){ +/** + * Simulation for the piece placement AI to block player to win + * @param the pointer of the game board + * @return return 0 if the AI ​​was able to block the player, 0 if it can't block the player + */ +int simulate_for_block_player(struct board *board){ int no_line = -1; for(int i = 0; i < board->col; i++){ no_line = current_line(*board, i); - //printf("%d\n", no_line); if(board->data[no_line][i] == Vide){ - board->data[no_line][i] = Croix; + board->data[no_line][i] = Croix; // Simulation to put a player piece in the game board->last_symbole = Croix; board->last_pos_x = no_line; board->last_pos_y = i; - if(winner(*board)){ + if(winner(*board)){ // If the AI can block, we put a AI piece in the same place board->data[no_line][i] = Cercle; board->last_symbole = Cercle; board->last_pos_x = no_line; board->last_pos_y = i; return 0; } - board->data[no_line][i] = Vide; + board->data[no_line][i] = Vide; // Else, we remove the piece board->last_symbole = Vide; board->last_pos_x = -1; board->last_pos_y = -1; @@ -54,14 +58,15 @@ int is_possible_to_block_player(struct board *board){ return -1; } - +/** + * Actions for play with the smart AI + */ void play_with_smartAI(struct board board){ int no_col = 0; int no_line = 0; int no_round = 1; while(!is_full_board(board)){ if(no_round % 2 != 0){ - // printf("mmmmmmmmmmmmmmmm\n\n\n\n\n\n\n\n\n\n"); printf("Column number? (starts at 1):"); scanf("%d", &no_col); printf("\n"); @@ -70,39 +75,25 @@ void play_with_smartAI(struct board board){ board.last_symbole = Croix; } else{ - if(is_possible_to_win(&board) != -1){ + if(simulate_for_win(&board) != -1){ // If the AI can win, we stop the game and AI is the winner print_game(&board); printf("Computer won!\n"); break; } - if(is_possible_to_block_player(&board) != -1){ + if(simulate_for_block_player(&board) != -1){ // If the AI block the player, we continue with the next round print_game(&board); no_round++; - - //printf("kasjh\n\n\n\n"); continue; } - no_col = rand() % 7; - //printf("Colonne %d : %d\n", no_col, no_line); - //printf("%d\n", no_line); + no_col = rand() % 7; // Else, AI place his piece in the random column no_line = current_line(board,no_col); - //printf("Colonne %d : %d\n", no_col, no_line); - //printf("skdjgbnlkd\n\n\n\n\n\n\n\n\n\n"); - board.data[no_line][no_col] = Cercle; board.last_symbole = Cercle; - // printf("skdjgbnlkd\n\n\n\n\n\n\n\n\n\n"); } board.last_pos_x = no_line; board.last_pos_y = no_col - 1; print_game(&board); - // for(int i = 0; i< board.line;i++){ - // for(int j = 0; j<board.col;j++){ - // printf("%d ", board.data[i][j]); - // } - // printf("\n"); - // } if(winner(board)){ if(board.last_symbole == Croix){ printf("Player one won!\n"); diff --git a/src/smartAI.h b/src/smartAI.h index 99d569d..ceb7b4b 100644 --- a/src/smartAI.h +++ b/src/smartAI.h @@ -6,8 +6,8 @@ #ifndef randomAI_h #define randomAI_h -int is_possible_to_win(struct board *board); -int is_possible_to_block_player(struct board *board); +int simulate_for_win(struct board *board); +int simulate_for_block_player(struct board *board); void play_with_smartAI(struct board board); #endif \ No newline at end of file diff --git a/src/twoPlayers.c b/src/twoPlayers.c index ebaa206..b4c24eb 100644 --- a/src/twoPlayers.c +++ b/src/twoPlayers.c @@ -1,5 +1,9 @@ #include "twoPlayers.h" +/** + * Actions for play with two players + * @param struct the game board + */ void play_two_players(struct board board){ int no_col = 0; int no_line = 0; diff --git a/src/winnerCheck.c b/src/winnerCheck.c index dd06dd4..c756b8c 100644 --- a/src/winnerCheck.c +++ b/src/winnerCheck.c @@ -1,29 +1,44 @@ #include "winnerCheck.h" +/** + * Check if there is a row of four + * @param struct the pointer of the game board + * @return retrurn true if there is a row of four, false if there is anything + */ bool row_of_four(struct board *board){ for (int col = 0; col < board->col - 3; col++) { if (board->data[board->last_pos_x][col] != Vide && board->data[board->last_pos_x][col] == board->data[board->last_pos_x][col+1] && board->data[board->last_pos_x][col] == board->data[board->last_pos_x][col+2] && board->data[board->last_pos_x][col] == board->data[board->last_pos_x][col+3]) { - return true; // Il y a une victoire + return true; } } return false; } +/** + * Check if there is a colunm of four + * @param struct the pointer of the game board + * @return retrurn true if there is a colunm of four, false if there is anything + */ bool col_of_four(struct board *board){ for (int row = 0; row < board->line - 3; row++) { if (board->data[row][board->last_pos_y] != Vide && board->data[row][board->last_pos_y] == board->data[row+1][board->last_pos_y] && board->data[row][board->last_pos_y] == board->data[row+2][board->last_pos_y] && board->data[row][board->last_pos_y] == board->data[row+3][board->last_pos_y]) { - return true; // Il y a une victoire + return true; } } return false; } +/** + * Check if there is a diagonal from left to right of four + * @param struct the pointer of the game board + * @return retrurn true if there is a diagonal of four, false if there is anything + */ bool diag_of_four_left_right(struct board *board){ for (int row = 0; row < board->line - 3; row++) { for (int col = 0; col < board->col - 3; col++) { @@ -31,13 +46,18 @@ bool diag_of_four_left_right(struct board *board){ board->data[row][col] == board->data[row+1][col+1] && board->data[row][col] == board->data[row+2][col+2] && board->data[row][col] == board->data[row+3][col+3]) { - return true; // Il y a une victoire + return true; } } } - return false; // No 4 consecutive symbols found + return false; } +/** + * Check if there is a diagonal from right to left of four + * @param struct the pointer of the game board + * @return retrurn true if there is a diagonal of four, false if there is anything + */ bool diag_of_four_right_left(struct board *board){ for (int row = 0; row < board->line - 3; row++) { for (int col = 3; col < board->col; col++) { @@ -45,14 +65,18 @@ bool diag_of_four_right_left(struct board *board){ board->data[row][col] == board->data[row+1][col-1] && board->data[row][col] == board->data[row+2][col-2] && board->data[row][col] == board->data[row+3][col-3]) { - return true; // Il y a une victoire + return true; } } } - return false; // Sinon, retourner false + return false; } +/** + * Check if the function above is true + * @param struct the game board + * @return return true is one of function is true, false if all function are false + */ bool winner(struct board board){ - //printf("kasjh\n\n\n\n"); return row_of_four(&board) || diag_of_four_left_right(&board) || diag_of_four_right_left(&board) || col_of_four(&board); } \ No newline at end of file -- GitLab