diff --git a/Makefile b/Makefile index ce0102a8a007d6716a6bc768063176e028381288..5615fc1ce77392118090c446908ae509768e3927 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -puissance4: main.o twoPlayers.o board.o +puissance4: main.o twoPlayers.o board.o randomAI.o winnerCheck.o @echo "first rule which must create the puissance4 executable" - gcc main.o twoPlayers.o board.o -o puissance4 + gcc main.o twoPlayers.o board.o randomAI.o winnerCheck.o -o puissance4 main.o : src/main.c gcc -Wall -Wextra -c src/main.c @@ -11,6 +11,12 @@ twoPlayers.o : src/twoPlayers.c src/twoPlayers.h board.o : src/board.c src/board.h gcc -Wall -Wextra -c src/board.c +randomAI.o : src/randomAI.c src/randomAI.h + gcc -Wall -Wextra -c src/randomAI.c + +winnerCheck.o : src/winnerCheck.c src/winnerCheck.h + gcc -Wall -Wextra -c src/winnerCheck.c + clean: @echo "this rule must clean everything up (including candidate files in testbed)" $(MAKE) -C testbed clean diff --git a/src/board.c b/src/board.c index e06daa92ab363c635fad71bf7d691e7e6963997e..6e4186c817f30b1b34466cde528813e6f1e5e415 100644 --- a/src/board.c +++ b/src/board.c @@ -64,9 +64,29 @@ void print_game(struct board *board){ printf("\n"); } +int current_line(struct board board, int no_col){ + int no_line = board.line-1; + while(board.data[no_line][no_col] != Vide){ + no_line--; + } + return no_line; +} + +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){ + return false; + } + } + } + return true; +} + void free_board(struct board *board){ for(int i = 0; i < board->line;i++){ free(board->data[i]); } free(board->data); -} \ No newline at end of file +} + diff --git a/src/board.h b/src/board.h index 2421026c06dabad305e8f5b118f94f3b487c73ec..ae3e7f8526cbd71380e99efd0e1f27d6cd2f236c 100644 --- a/src/board.h +++ b/src/board.h @@ -1,8 +1,10 @@ #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #ifndef board_h #define board_h + enum state{Croix, Cercle, Vide}; struct board{ @@ -17,5 +19,8 @@ struct board{ struct board create_board(int col, int line); void init_board(struct board *board); void print_game(struct board *board); +int current_line(struct board board, int no_col); +bool is_full_board(struct board board); void free_board(struct board *board); + #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 025ac64e76f9459457678a3c4563abaed48062ff..a24f9b047926822dd9ad550ca9a63d75abca950c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,12 +1,26 @@ #include "board.h" #include "twoPlayers.h" +#include "randomAI.h" +#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); - play(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; + } free_board(&board); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/randomAI.c b/src/randomAI.c index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2daa95fc4d72b558e94023c38d716c9294f69ec1 100644 --- a/src/randomAI.c +++ b/src/randomAI.c @@ -0,0 +1,39 @@ +#include "randomAI.h" + +void play_with_randomAI(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("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.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.last_symbole = Cercle; + } + board.last_pos_x = no_line; + board.last_pos_y = no_col - 1; + print_game(&board); + if(winner(board)){ + if(board.last_symbole == Croix){ + printf("Player one won!\n"); + } + else if(board.last_symbole == Cercle){ + printf("Computer won!\n"); + } + break; + } + no_round++; + } + if(is_full_board(board)){ + printf("It is a draw.\n"); + } +} diff --git a/src/randomAI.h b/src/randomAI.h index 8b137891791fe96927ad78e64b0aad7bded08bdc..641a0c0dc5869c27aaf5af347f0f0822a7d39902 100644 --- a/src/randomAI.h +++ b/src/randomAI.h @@ -1 +1,11 @@ +#include <stdlib.h> +#include <stdio.h> +#include "board.h" +#include "winnerCheck.h" +#ifndef randomAI_h +#define randomAI_h + +void play_with_randomAI(struct board board); + +#endif \ No newline at end of file diff --git a/src/twoPlayers.c b/src/twoPlayers.c index 2cfc862f272ab384d5278a66434da66f886d28fd..ebaa206a8848b21f542c8ca55411a68a22ee3cd6 100644 --- a/src/twoPlayers.c +++ b/src/twoPlayers.c @@ -1,157 +1,6 @@ #include "twoPlayers.h" -int current_line(struct board board, int no_col){ - int no_line = board.line-1; - while(board.data[no_line][no_col] != Vide){ - no_line--; - } - return no_line; -} - -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){ - return false; - } - } - } - return true; -} - -bool row_of_four(struct board *board){ - int sum = 0; - int i = 0; - int old_i = -1; - while(i < board->col - 1){ - old_i = i; - if(board->data[board->last_pos_x][i] == board->last_symbole && board->data[board->last_pos_x][old_i] == board->last_symbole){ - sum++; - } - else{ - break; - } - i++; - } - if(sum >= 4){ - return true; - } - return false; -} - -bool col_of_four(struct board *board){ - int sum = 0; - int i = board->line -1; - int old_i = -1; - while(i >= 0){ - old_i = i; - if(board->data[i][board->last_pos_y] == board->last_symbole && board->data[old_i][board->last_pos_y] == board->last_symbole){ - sum++; - } - else{ - break; - } - i--; - } - if(sum >= 4){ - return true; - } - return false; -} - -bool diag_of_four_left_right(struct board *board){ - int sum = 1; // Nous commençons à 1 car le dernier symbole est déjà compté - int current_x = board->last_pos_x; - int current_y = board->last_pos_y; - int oldx = -1; - int oldy = -1; - - // Vérification de la diagonale supérieure gauche à la diagonale inférieure droite - while (current_x > 0 && current_y > 0) { - oldx = current_x; - oldy = current_y; - current_x--; - current_y--; - - if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { - sum++; // Increment only if we find consecutive symbols - } - } - - // Réinitialisation des coordonnées - current_x = board->last_pos_x; - current_y = board->last_pos_y; - - // Vérification de la diagonale inférieure droite à la diagonale supérieure gauche - while (current_x < board->line - 1 && current_y < board->col - 1) { - oldx = current_x; - oldy = current_y; - current_x++; - current_y++; - - if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { - sum++; // Increment only if we find consecutive symbols - } - } - - // Vérifie si sum est exactement égal à 4 - if (sum == 4) { - return true; // We found 4 consecutive symbols - } - return false; // No 4 consecutive symbols found -} - -bool diag_of_four_right_left(struct board *board){ - int sum = 1; // On commence à 1 car le dernier symbole est déjà compté - int current_x = board->last_pos_x; - int current_y = board->last_pos_y; - int oldx = -1; - int oldy = -1; - - // Vérification de la diagonale montante gauche à la diagonale descendante droite - while (current_x > 0 && current_y < board->col - 1) { - oldx = current_x; - oldy = current_y; - current_x--; - current_y++; - - if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { - sum++; // Incrémenter seulement si les symboles sont consécutifs - } - } - - // Réinitialisation des coordonnées - current_x = board->last_pos_x; - current_y = board->last_pos_y; - - // Vérification de la diagonale descendante gauche à la diagonale montante droite - while (current_x < board->line - 1 && current_y >= 0) { - oldx = current_x; - oldy = current_y; - current_x++; - current_y--; - - if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { - sum++; // Incrémenter seulement si les symboles sont consécutifs - } - } - - // Vérifie si sum est exactement égal à 4 - if (sum == 4) { - return true; // Si 4 symboles consécutifs sont trouvés, retourner true - } - return false; // Sinon, retourner false -} - -bool winner(struct board board){ - if(row_of_four(&board) || diag_of_four_left_right(&board) || diag_of_four_right_left(&board) || col_of_four(&board)){ - return true; - } - return false; -} - - -void play(struct board board){ +void play_two_players(struct board board){ int no_col = 0; int no_line = 0; int no_round = 1; diff --git a/src/twoPlayers.h b/src/twoPlayers.h index 9d6b462c3bb96ef0051dbb0906d092f48994796a..55e4d1a4f861e2b0bf918059fe7e7aff76711dac 100644 --- a/src/twoPlayers.h +++ b/src/twoPlayers.h @@ -2,14 +2,11 @@ #include <stdlib.h> #include <stdbool.h> #include "board.h" +#include "winnerCheck.h" #ifndef twoplayers_h #define twoplayers_h -int current_line(struct board board, int no_col); -bool is_full_board(struct board board); -bool row_of_four(struct board *board); -bool diag_of_four_left_right(struct board *board); -bool diag_of_four_right_left(struct board *board); -bool winner(struct board board); -void play(struct board board); + +void play_two_players(struct board board); + #endif diff --git a/src/winnerCheck.c b/src/winnerCheck.c new file mode 100644 index 0000000000000000000000000000000000000000..50d20950e7606c50b96d7336e8f97ee05161f447 --- /dev/null +++ b/src/winnerCheck.c @@ -0,0 +1,124 @@ +#include "winnerCheck.h" + +bool row_of_four(struct board *board){ + int sum = 1; + int i = 0; + int old_i = -1; + while(i < board->col - 1){ + old_i = i; + i++; + if(board->data[board->last_pos_x][i] == board->last_symbole && board->data[board->last_pos_x][old_i] == board->last_symbole){ + sum++; + } + if(sum == 4){ + return true; + } + } + return false; +} + +bool col_of_four(struct board *board){ + int sum = 1; + int i = 0; + int old_i = -1; + while(i < board->line -1){ + old_i = i; + i++; + if(board->data[i][board->last_pos_y] == board->last_symbole && board->data[old_i][board->last_pos_y] == board->last_symbole){ + sum++; + } + + if(sum == 4){ + return true; + } + } + return false; +} + +bool diag_of_four_left_right(struct board *board){ + int sum = 1; // Nous commençons à 1 car le dernier symbole est déjà compté + int current_x = board->last_pos_x; + int current_y = board->last_pos_y; + int oldx = -1; + int oldy = -1; + + // Vérification de la diagonale supérieure gauche à la diagonale inférieure droite + while (current_x > 0 && current_y > 0) { + oldx = current_x; + oldy = current_y; + current_x--; + current_y--; + + if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { + sum++; // Increment only if we find consecutive symbols + } + } + + // Réinitialisation des coordonnées + current_x = board->last_pos_x; + current_y = board->last_pos_y; + + // Vérification de la diagonale inférieure droite à la diagonale supérieure gauche + while (current_x < board->line - 1 && current_y < board->col - 1) { + oldx = current_x; + oldy = current_y; + current_x++; + current_y++; + + if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { + sum++; // Increment only if we find consecutive symbols + } + } + + // Vérifie si sum est exactement égal à 4 + if (sum == 4) { + return true; // We found 4 consecutive symbols + } + return false; // No 4 consecutive symbols found +} + +bool diag_of_four_right_left(struct board *board){ + int sum = 1; // On commence à 1 car le dernier symbole est déjà compté + int current_x = board->last_pos_x; + int current_y = board->last_pos_y; + int oldx = -1; + int oldy = -1; + + // Vérification de la diagonale montante gauche à la diagonale descendante droite + while (current_x > 0 && current_y < board->col - 1) { + oldx = current_x; + oldy = current_y; + current_x--; + current_y++; + + if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { + sum++; // Incrémenter seulement si les symboles sont consécutifs + } + } + + // Réinitialisation des coordonnées + current_x = board->last_pos_x; + current_y = board->last_pos_y; + + // Vérification de la diagonale descendante gauche à la diagonale montante droite + while (current_x < board->line - 1 && current_y >= 0) { + oldx = current_x; + oldy = current_y; + current_x++; + current_y--; + + if (board->data[current_x][current_y] == board->last_symbole && board->data[oldx][oldy] == board->last_symbole) { + sum++; // Incrémenter seulement si les symboles sont consécutifs + } + } + + // Vérifie si sum est exactement égal à 4 + if (sum == 4) { + return true; // Si 4 symboles consécutifs sont trouvés, retourner true + } + return false; // Sinon, retourner false +} + +bool winner(struct board board){ + 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 diff --git a/src/winnerCheck.h b/src/winnerCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..f271932e80e229dfefb6988088c2ee83696a9906 --- /dev/null +++ b/src/winnerCheck.h @@ -0,0 +1,15 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include "board.h" + +#ifndef winnerCheck_h +#define winnerCheck_h + +bool row_of_four(struct board *board); +bool col_of_four(struct board *board); +bool diag_of_four_left_right(struct board *board); +bool diag_of_four_right_left(struct board *board); +bool winner(struct board board); + +#endif \ No newline at end of file