From 1778c07dbcc28fc289e80f95d053a8641f1dc526 Mon Sep 17 00:00:00 2001
From: Sabrina L <sabrina.lapaire@hesge.ch>
Date: Fri, 28 Mar 2025 14:40:53 +0100
Subject: [PATCH] Mode 2 players and randomAI works totally

---
 Makefile          |  10 ++-
 src/board.c       |  22 ++++++-
 src/board.h       |   5 ++
 src/main.c        |  16 ++++-
 src/randomAI.c    |  39 ++++++++++++
 src/randomAI.h    |  10 +++
 src/twoPlayers.c  | 153 +---------------------------------------------
 src/twoPlayers.h  |  11 ++--
 src/winnerCheck.c | 124 +++++++++++++++++++++++++++++++++++++
 src/winnerCheck.h |  15 +++++
 10 files changed, 242 insertions(+), 163 deletions(-)
 create mode 100644 src/winnerCheck.c
 create mode 100644 src/winnerCheck.h

diff --git a/Makefile b/Makefile
index ce0102a..5615fc1 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 e06daa9..6e4186c 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 2421026..ae3e7f8 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 025ac64..a24f9b0 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 e69de29..2daa95f 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 8b13789..641a0c0 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 2cfc862..ebaa206 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 9d6b462..55e4d1a 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 0000000..50d2095
--- /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 0000000..f271932
--- /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
-- 
GitLab