diff --git a/puissance4.c b/puissance4.c
index fb4712f5c7a07384c2ee3630af4258a33324ab5b..1fca65c0b8a8f4c9fbb0fe56dfd720f307bf8fe6 100644
--- a/puissance4.c
+++ b/puissance4.c
@@ -8,7 +8,7 @@
 
 void init_board(int rows, int cols, int** board);
 void print_board(int rows, int cols, int** board);
-struct coordinate add_token(int col, int player, int rows, int** board);
+// struct coordinate add_token(int col, int player, int rows, int** board);
 bool does_player_win(int col, int row, int rows, int cols, int** board);
 void flush_input();
 int** create_board(int rows, int cols);
@@ -17,6 +17,8 @@ bool is_valid_game_mode(int game_mode);
 bool is_valid_board_size(int rows, int cols);
 bool is_column_full(int col, int rows, int** board);
 int select_random_column(int number_of_columns, int number_of_rows, int** board);
+int select_smart_column(int number_of_columns, int number_of_rows, int** board);
+
 
 
 enum STATE {
@@ -38,6 +40,8 @@ enum GAME_MODE {
 
 
 char transform_state_to_char(enum STATE state);
+void place_token(int player, struct coordinate coordinate, int** board);
+struct coordinate find_empty_slot(int col, int rows, int** board);
 
 int main(int argc, char const* argv[]) {
     if (argc != 4 || !is_valid_game_mode(atoi(argv[1])) || !is_valid_board_size(atoi(argv[2]), atoi(argv[3]))) {
@@ -72,14 +76,22 @@ int main(int argc, char const* argv[]) {
             printf("\nColumn number? (starts at 1):");
             scanf("%d", &player_selected_column);
         } else {
-            player_selected_column = select_random_column(cols, rows, board);
+            if (game_mode == PLAYER_VS_RANDOM_AI) {
+                player_selected_column = select_random_column(cols, rows, board);
+            } else if (game_mode == PLAYER_VS_SMART_AI) {
+                player_selected_column = select_smart_column(cols, rows, board);
+            }
         }
 
         if (player_selected_column < 1 || player_selected_column > cols) {
             continue;
         }
 
-        coordinate = add_token(player_selected_column, player % 2, rows, board);
+        // coordinate = add_token(player_selected_column, player % 2, rows, board);
+        coordinate = find_empty_slot(player_selected_column, rows, board);
+        if (coordinate.x != -1 && coordinate.y != -1) {
+            place_token(player % 2, coordinate, board);
+        }
 
         print_board(rows, cols, board);
         if (does_player_win(coordinate.x, coordinate.y, rows, cols, board)) {
@@ -88,7 +100,6 @@ int main(int argc, char const* argv[]) {
             } else {
                 printf("\n%s won!\n", player % 2 == 0 ? "Player one" : "Computer");
             }
-
             break;
         }
         if (player + 1 == rows * cols) {
@@ -123,6 +134,53 @@ int select_random_column(int number_of_columns, int number_of_rows, int** board)
     return robot_selected_column;
 }
 
+int select_smart_column(int number_of_columns, int number_of_rows, int** board) {
+    int robot_selected_column = -999;
+
+    // Check if the player can win in the next move, if so, block it
+    for (int col = 0; col < number_of_columns; col++) {
+        if (!is_column_full(col + 1, number_of_rows, board)) {
+            struct coordinate temp_coordinate = find_empty_slot(col + 1, number_of_rows, board);
+
+            // Check if the player can win in the next move
+            board[temp_coordinate.x][temp_coordinate.y] = PLAYER1;
+            if (does_player_win(temp_coordinate.x, temp_coordinate.y, number_of_rows, number_of_columns, board)) {
+                robot_selected_column = col + 1;
+                board[temp_coordinate.x][temp_coordinate.y] = EMPTY;
+                break;
+            }
+            board[temp_coordinate.x][temp_coordinate.y] = EMPTY;
+        }
+    }
+
+    if (robot_selected_column != -999) {
+        return robot_selected_column;
+    }
+
+    // Check if the AI can win in the next move, if so, play it
+    for (int col = 0; col < number_of_columns; col++) {
+        if (!is_column_full(col + 1, number_of_rows, board)) {
+            struct coordinate temp_coordinate = find_empty_slot(col + 1, number_of_rows, board);
+
+            board[temp_coordinate.x][temp_coordinate.y] = PLAYER2;
+            if (does_player_win(temp_coordinate.x, temp_coordinate.y, number_of_rows, number_of_columns, board)) {
+                robot_selected_column = col + 1;
+                board[temp_coordinate.x][temp_coordinate.y] = EMPTY;
+                break;
+            }
+            board[temp_coordinate.x][temp_coordinate.y] = EMPTY;
+        }
+
+    }
+
+    // If no winning move is found, select a random column
+    if (robot_selected_column == -999) {
+        robot_selected_column = select_random_column(number_of_columns, number_of_rows, board);
+    }
+
+    return robot_selected_column;
+}
+
 bool is_column_full(int col, int rows, int** board) {
     for (int i = 0; i < rows; i++) {
         if (board[i][col - 1] == EMPTY) {
@@ -132,11 +190,10 @@ bool is_column_full(int col, int rows, int** board) {
     return true;
 }
 
-struct coordinate add_token(int col, int player, int rows, int** board) {
-    struct coordinate coordinate = { 0,0 };
+struct coordinate find_empty_slot(int col, int rows, int** board) {
+    struct coordinate coordinate = { -1, -1 };
     for (int i = rows - 1; i >= 0; i--) {
         if (board[i][col - 1] == EMPTY) {
-            board[i][col - 1] = player == 0 ? PLAYER1 : PLAYER2;
             coordinate.x = i;
             coordinate.y = col - 1;
             break;
@@ -145,6 +202,12 @@ struct coordinate add_token(int col, int player, int rows, int** board) {
     return coordinate;
 }
 
+void place_token(int player, struct coordinate coordinate, int** board) {
+    if (coordinate.x != -1 && coordinate.y != -1) {
+        board[coordinate.x][coordinate.y] = player == 0 ? PLAYER1 : PLAYER2;
+    }
+}
+
 int** create_board(int rows, int cols) {
     int** board = malloc(rows * sizeof(int*));
     if (board == NULL) {