diff --git a/Makefile b/Makefile
index bc8b3ac47d8df2b91aba7904fe132193722f2067..727325a4aba71a99ddd63bece287b12c0d560cc7 100644
--- a/Makefile
+++ b/Makefile
@@ -3,17 +3,18 @@ CFLAGS  = -g -Wall -Wextra -Wpedantic
 LDLIBS  = -lm
 LDFLAGS = -fsanitize=address -fsanitize=leak
 
-puissance4: puissance4.o src/board.o src/game.o
+puissance4: puissance4.o src/board.o src/computer.o src/game.o
 	$(CC) $(CFLAGS) $^ -o $@ $(LDLIBS) $(LDFLAGS)
 
 board.o: src/board.h
-game.o: src/game.h
-puissance4.o: puissance4.h
+game.o: src/game.h src/computer.h
+computer.o: src/computer.h src/board.h
+puissance4.o: puissance4.h src/game.h src/board.h
 
 clean:
 	@echo "this rule must clean everything up (including candidate files in testbed)"
 	$(MAKE) -C testbed clean
-	$(RM) -rf puissance4 *.o *.cand
+	$(RM) -rf puissance4 *.o tests_game tests_board tests_computer
 
 run: puissance4 
 	./$< 3 5 6
@@ -30,7 +31,7 @@ tests_rand_ai: puissance4
 tests_smart_ai: puissance4
 	$(MAKE) -C testbed/smart_ai
 
-tests_game: src/test_game.o src/game.o src/board.o
+tests_game: src/test_game.o src/board.o src/game.o src/computer.o
 	$(CC) $(CFLAGS) $^ -o tests_game $(LDLIBS) $(LDFLAGS)
 	./tests_game
 
@@ -38,5 +39,13 @@ tests_board: src/test_board.o src/board.o
 	$(CC) $(CFLAGS) $^ -o tests_board $(LDLIBS) $(LDFLAGS)
 	./tests_board
 
-run_tests: tests_game tests_board
+tests_computer: src/test_computer.o src/computer.o src/board.o src/game.o
+	$(CC) $(CFLAGS) $^ -o tests_computer $(LDLIBS) $(LDFLAGS)
+	./tests_computer
+
+run_tests: tests_game tests_board tests_computer
+	@echo "Running all tests..."
+	./tests_game
+	./tests_board
+	./tests_computer
 	@echo "All tests executed successfully."
\ No newline at end of file
diff --git a/puissance4.c b/puissance4.c
index f21647932014dfca9c3b2971c793d710655d792d..9f100df8d814161087f7d18539bc571ba7256613 100644
--- a/puissance4.c
+++ b/puissance4.c
@@ -1,17 +1,5 @@
 #include "puissance4.h"
 
-// #define AI_SEED 0
-// #define MIN_COLUMN 4
-// #define MIN_ROW 4
-
-// void flush_input();
-// 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);
-// void announce_winner(enum GAME_MODE game_mode, int current_turn);
-
 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]))) {
         printf("Usage: %s <mode> <row> <col>\n", argv[0]);
@@ -90,71 +78,6 @@ bool is_valid_board_size(int rows, int cols) {
     return rows >= MIN_ROW && cols >= MIN_COLUMN;
 }
 
-int select_random_column(int number_of_columns, int number_of_rows, int** board) {
-    int robot_selected_column = -999;
-    do {
-        robot_selected_column = rand() % number_of_columns + 1;
-    } while (is_column_full(robot_selected_column, number_of_rows, 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 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, number_of_rows, board);
-
-            board[temp_coordinate.x][temp_coordinate.y] = PLAYER2;
-            if (does_player_win(temp_coordinate, 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 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, 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, 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) {
-            return false;
-        }
-    }
-    return true;
-}
-
 void flush_input() {
     int c;
     while ((c = getchar()) != '\n' && c != EOF);
diff --git a/puissance4.h b/puissance4.h
index ba2d9ccb9749cea6a931cdc432d516c0c4b53d85..7ebd43755a5b51549332615c6af887d8ba1e5548 100644
--- a/puissance4.h
+++ b/puissance4.h
@@ -7,23 +7,18 @@
 #include <stdbool.h>
 #include "src/game.h"
 #include "src/board.h"
+#include "src/computer.h"
 
 #define AI_SEED 0
 #define MIN_COLUMN 4
 #define MIN_ROW 4
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include "src/game.h"
-#include "src/board.h"
-
 void announce_winner(enum GAME_MODE game_mode, int current_turn);
 bool is_valid_game_mode(int game_mode);
 bool is_valid_board_size(int rows, int cols);
-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);
-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);
+// bool is_column_full(int col, int rows, int** board);
 void flush_input();
 
 #endif
diff --git a/src/computer.c b/src/computer.c
new file mode 100644
index 0000000000000000000000000000000000000000..6f22569671b0a0b9d6dd87e103f75e1e15d29e77
--- /dev/null
+++ b/src/computer.c
@@ -0,0 +1,67 @@
+
+#include "computer.h"
+
+int select_smart_column(int number_of_columns, int number_of_rows, int** board) {
+    int robot_selected_column = -999;
+
+    // 1. 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, number_of_rows, board);
+
+            board[temp_coordinate.x][temp_coordinate.y] = PLAYER2;
+            if (does_player_win(temp_coordinate, 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;
+    }
+
+    // 2. 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, 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, 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;
+        }
+    }
+
+    // 3. 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;
+}
+
+int select_random_column(int number_of_columns, int number_of_rows, int** board) {
+    int robot_selected_column = -999;
+    do {
+        robot_selected_column = rand() % number_of_columns + 1;
+    } while (is_column_full(robot_selected_column, 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) {
+            return false;
+        }
+    }
+    return true;
+}
\ No newline at end of file
diff --git a/src/computer.h b/src/computer.h
new file mode 100644
index 0000000000000000000000000000000000000000..491015b112e2ed3db8f0d97eaeea36ea471518ff
--- /dev/null
+++ b/src/computer.h
@@ -0,0 +1,14 @@
+#ifndef _COMPUTER_H
+#define _COMPUTER_H
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "computer.h"
+#include "game.h"
+#include "board.h"
+
+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);
+bool is_column_full(int col, int rows, int** board);
+#endif
diff --git a/src/game.h b/src/game.h
index 75d431c01f90e91b85e815801471681b93969170..4e31cb1decdde29713252ec82b2b94da858a93c9 100644
--- a/src/game.h
+++ b/src/game.h
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include "board.h"
+#include "computer.h"
 
 enum GAME_MODE {
     PLAYER_VS_RANDOM_AI = 1,
diff --git a/src/test_board.c b/src/test_board.c
index 018c4936d89f519b02371112cdf2f43fa3542ed3..5e351ae08b21cc5c71f69632abf2f51983e9ac33 100644
--- a/src/test_board.c
+++ b/src/test_board.c
@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
-#include "../src/board.h"
+#include "board.h"
 
 #define GREEN "\033[1;32m"
 #define RED "\033[1;31m"
diff --git a/src/test_computer.c b/src/test_computer.c
new file mode 100644
index 0000000000000000000000000000000000000000..63a111d38d9fb2c1342d6db62edc0a1ea707f0aa
--- /dev/null
+++ b/src/test_computer.c
@@ -0,0 +1,99 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "computer.h"
+#include "game.h"
+
+int** setup_board(int rows, int cols, int default_value) {
+    int** board = create_board(rows, cols);
+    if (board == NULL) {
+        fprintf(stderr, "Error: Unable to allocate memory for the board.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    for (int i = 0; i < rows; i++) {
+        for (int j = 0; j < cols; j++) {
+            board[i][j] = default_value;
+        }
+    }
+
+    return board;
+}
+
+void reset_board(int rows, int cols, int** board) {
+    for (int i = 0; i < rows; i++) {
+        for (int j = 0; j < cols; j++) {
+            board[i][j] = EMPTY;
+        }
+    }
+}
+
+void test_is_column_full() {
+    int rows = 6, cols = 7;
+    int** board = setup_board(rows, cols, EMPTY);
+
+    // An empty column should not be considered full
+    assert(is_column_full(1, rows, board) == false);
+
+    // Fill a column completely and test again
+    for (int i = 0; i < rows; i++) {
+        board[i][0] = PLAYER1;
+    }
+    assert(is_column_full(1, rows, board) == true);
+
+    destroy_board(rows, board);
+}
+
+void test_select_smart_column() {
+    int rows = 6, cols = 7;
+    int** board = setup_board(rows, cols, EMPTY);
+
+    // Simulate a situation where the AI can win immediately
+    board[5][0] = PLAYER2;
+    board[4][0] = PLAYER2;
+    board[3][0] = PLAYER2;
+
+    assert(select_smart_column(cols, rows, board) == 1);
+    reset_board(rows, cols, board);
+
+    // Simulate a situation where the player can win on the next move
+    board[5][1] = PLAYER1;
+    board[4][1] = PLAYER1;
+    board[3][1] = PLAYER1;
+    assert(select_smart_column(cols, rows, board) == 2);
+
+    destroy_board(rows, board);
+}
+
+void test_select_random_column() {
+    int rows = 6, cols = 7;
+    int** board = setup_board(rows, cols, EMPTY);
+
+    // Select a random column on an empty board
+    int col = select_random_column(cols, rows, board);
+
+    assert(col == 2);  // The expected value based on the random seed
+
+    // Fill all columns except one
+    for (int j = 0; j < cols - 1; j++) {
+        for (int i = 0; i < rows; i++) {
+            board[i][j] = PLAYER1;
+        }
+    }
+
+    // The AI should select the only non-full column, which is column 7 (the last one)
+    col = select_random_column(cols, rows, board);
+    assert(col == 7);  // The last remaining column
+
+    destroy_board(rows, board);
+}
+
+
+int main() {
+    test_is_column_full();
+    test_select_smart_column();
+    test_select_random_column();
+
+    printf("All computer tests passed successfully.\n");
+    return EXIT_SUCCESS;
+}
diff --git a/tests_board b/tests_board
index 74e2f07dd6600edda11e746f20c1c567898064ad..4963c645ce1583ee18bdcea9857c70d6a42b9165 100755
Binary files a/tests_board and b/tests_board differ
diff --git a/tests_computer b/tests_computer
new file mode 100755
index 0000000000000000000000000000000000000000..a1c01814781908237943a909f10aeff832497a61
Binary files /dev/null and b/tests_computer differ
diff --git a/tests_game b/tests_game
new file mode 100755
index 0000000000000000000000000000000000000000..f1cfa60e87bb4232589ffc7d78236e1434260775
Binary files /dev/null and b/tests_game differ