diff --git a/main.c b/main.c
index 8f572c64f66ae177dfd863e038dbc4a7caffcfa0..dfd9a11273d46915da79d136855adb7c5f58d432 100644
--- a/main.c
+++ b/main.c
@@ -13,12 +13,16 @@ int main() {
     puissance game;
 
     game_init(&game, RAND_AI, DEFAULT_ROW, DEFAULT_COL);
+    manual_play(&game, 1);
+    manual_play(&game, 0);
+    manual_play(&game, 1);
     print_game(game);
-    random_play(&game);
+    manual_play(&game, 0);
+    manual_play(&game, 2);
+    manual_play(&game, 0);
+    manual_play(&game, 3);
     print_game(game);
-    random_play(&game);
-    print_game(game);
-    random_play(&game);
+    manual_play(&game, 0);
     print_game(game);
 
     game_destroy(&game);
diff --git a/puissance.c b/puissance.c
index a00c0c89ded00745cb37f9e9ecf23f9a8b43e886..b5fd37b8ef85d49c33e9168ca2741e797dfb9e29 100644
--- a/puissance.c
+++ b/puissance.c
@@ -10,6 +10,7 @@
 
 void game_init(puissance *p, GameMode mode, int row, int col) {
     p->mode = mode;
+    p->state = ONGOING;
     p->current_player = PLAYER_ONE;
     p->row = row;
     p->col = col;
@@ -111,10 +112,72 @@ void print_game(puissance p) {
     printf("%s", display);
     // Clear the string to avoid SIGABRT
     display[0] = '\0';
+
+    if (p.state != ONGOING) {
+        display_game_result(p.state);
+    }
 }
 
-void verify_game(puissance p) {
+GameResult vertical_game_check(puissance p, int last_col_index_played) {
+    bool four_aligned = false;
+    // Get the row index
+    int last_row_index_played = get_available_row_index(&p, last_col_index_played);
+    if (last_row_index_played != EMPTY_CELL_VALUE) {
+        last_row_index_played += 1; // Adjust the index
+    }
+
+    // Verify if we have enough vertical space.
+    if (last_row_index_played + NB_SAME_VALUE_ALIGNED_FOR_WIN - 1 < p.row) {
+        int last_played_value = p.data[last_row_index_played][last_col_index_played];
+        four_aligned = true;
+
+        // Verify if the aligned value are the same
+        for (int i = 1; i <= NB_SAME_VALUE_ALIGNED_FOR_WIN - 1; i++) {
+            if (last_played_value != p.data[last_row_index_played + i][last_col_index_played]) {
+                four_aligned = false;
+                break;
+            }
+        }
 
+        if (four_aligned) {
+            // Return the player who have won.
+            if (p.current_player == PLAYER_ONE) {
+                return PLAYER_ONE_WIN;
+            } else {
+                return PLAYER_TWO_WIN;
+            }
+        }
+    }
+
+    return ONGOING;
+}
+
+GameResult verify_game(puissance *p, int last_col_index_played) {
+    GameResult result = ONGOING;
+    // Vertical check
+    result = vertical_game_check(*p, last_col_index_played);
+
+    if (result != ONGOING) {
+        p->state = result;
+        return result;
+    }
+
+    p->state = result;
+    return result;
+}
+
+GameResult display_game_result(GameResult gr) {
+    if (gr == PLAYER_ONE_WIN) {
+        printf("The player one (" PLAYER_ONE_STRING ") win !\n");
+    }
+    if (gr == PLAYER_TWO_WIN) {
+        printf("The player two (" PLAYER_TWO_STRING ") win !\n");
+    }
+    if (gr == DRAW) {
+        printf("It's a draw !\n");
+    }
+
+    return gr;
 }
 
 int get_available_row_index(puissance *p, int selected_col_index) {
@@ -141,11 +204,16 @@ bool manual_play(puissance *p, int selected_col_index) {
     // Play
     p->data[row_index][selected_col_index] = p->current_player;
 
+    // Verify the game
+    GameResult result = verify_game(p, selected_col_index);
+
     // Switch the current player
-    if (p->current_player == PLAYER_ONE) {
-        p->current_player = PLAYER_TWO;
-    } else {
-        p->current_player = PLAYER_ONE;
+    if (result == ONGOING) {
+        if (p->current_player == PLAYER_ONE) {
+            p->current_player = PLAYER_TWO;
+        } else {
+            p->current_player = PLAYER_ONE;
+        }
     }
 
     // Valid the action
diff --git a/puissance.h b/puissance.h
index 4a56adedcd757bf399dd315e0d739ec1ac18c640..662bff9490ac4f8240fd0ebfb21b1e4a5fc2903b 100644
--- a/puissance.h
+++ b/puissance.h
@@ -16,6 +16,7 @@
 #define PLAYER_ONE_STRING "X"
 #define PLAYER_TWO_STRING "O"
 #define EMPTY_CELL_VALUE -1
+#define NB_SAME_VALUE_ALIGNED_FOR_WIN 4
 
 typedef enum {
     RAND_AI,
@@ -37,6 +38,7 @@ typedef enum {
 
 typedef struct _puissance {
     GameMode mode;
+    GameResult state;
     Player current_player;
     int row;
     int col;
@@ -45,7 +47,8 @@ typedef struct _puissance {
 
 void game_init(puissance *p, GameMode mode, int row, int col);
 void print_game(puissance p);
-void verify_game(puissance p);
+GameResult verify_game(puissance *p, int last_col_index_played);
+GameResult display_game_result(GameResult gr);
 int get_available_row_index(puissance *p, int selected_col_index);
 bool manual_play(puissance *p, int selected_col_index);
 bool random_play(puissance *p);