diff --git a/main.c b/main.c
index 87eef38c84fec09802a5cb80fd8e2530f4c0c9c0..209af01f8fd18e3d0bc26d8dbe4943d1da6f2faf 100644
--- a/main.c
+++ b/main.c
@@ -24,6 +24,23 @@ void play_against_random_ai(puissance game) {
     }
 }
 
+void play_against_smart_ai(puissance game) {
+    int selected_col_index = -1;
+
+    while(game.state == ONGOING) {
+        if (game.current_player == PLAYER_ONE) {
+            printf("\nColumn number? (starts at 1):");
+            do {
+                scanf("%d", &selected_col_index);
+                selected_col_index -= 1;
+            } while (manual_play(&game, selected_col_index) == false);
+        } else {
+            smart_play(&game);
+        }
+        print_game(game);
+    }
+}
+
 void play_against_human(puissance game) {
     int selected_col_index = -1;
 
@@ -57,7 +74,9 @@ int main(int argc, char *argv[]) {
     switch (mode) {
         case RAND_AI:
             play_against_random_ai(game);
+            break;
         case SMART_AI:
+            play_against_smart_ai(game);
             break;
         case TWO_PLAYERS:
             play_against_human(game);
diff --git a/puissance.c b/puissance.c
index e803c3ffeb93bedb439a104711d3424764b6b288..9026ba1109a0f037e7e63018f644bc540a96ca5f 100644
--- a/puissance.c
+++ b/puissance.c
@@ -27,6 +27,21 @@ void game_init(puissance *p, GameMode mode, int row, int col) {
     }
 }
 
+puissance game_copy(puissance *p) {
+    puissance copy;
+    game_init(&copy, p->mode, p->row, p->col);
+    copy.state = p->state;
+    copy.current_player = p->current_player;
+
+    for (int r = 0; r < copy.row; r++) {
+        for (int c = 0; c < copy.col; c++) {
+            copy.data[r][c] = p->data[r][c];
+        }
+    }
+
+    return copy;
+}
+
 void print_top(char *display, int col) {
     // Print top
     strcat(display, "\n┌");
@@ -354,9 +369,39 @@ bool random_play(puissance *p) {
 }
 
 bool smart_play(puissance *p) {
-    bool valid_action = true;
+    bool move_validated = false;
+    // Search for a wining action
+    for (int i = 0; i < p->col; i++) {
+        puissance copy = game_copy(p);
 
-    return valid_action;
+        if (manual_play(&copy, i)) {
+            if (copy.state != ONGOING) {
+                move_validated = manual_play(p, i);
+            }
+        }
+        game_destroy(&copy);
+        if (move_validated) {
+            return move_validated;
+        }
+    }
+
+    // Try to prevent the user to win
+    for (int i = 0; i < p->col; i++) {
+        puissance copy = game_copy(p);
+        copy.current_player = PLAYER_ONE;
+
+        if (manual_play(&copy, i)) {
+            if (copy.state != ONGOING) {
+                move_validated = manual_play(p, i);
+            }
+        }
+        game_destroy(&copy);
+        if (move_validated) {
+            return move_validated;
+        }
+    }
+    // If nothing has been done, do something random
+    return random_play(p);
 }
 
 void game_destroy(puissance *p) {
diff --git a/puissance.h b/puissance.h
index 7baf727918cec34d47d7322c422b61b2230d576c..1e866bd0707390dedb191316d7507db31cee926f 100644
--- a/puissance.h
+++ b/puissance.h
@@ -47,6 +47,7 @@ typedef struct _puissance {
 } puissance;
 
 void game_init(puissance *p, GameMode mode, int row, int col);
+puissance game_copy(puissance *p);
 void print_game(puissance p);
 GameResult verify_game(puissance *p, int last_col_index_played);
 GameResult display_game_result(puissance p);