diff --git a/main.c b/main.c
index ede0dfe0247b93909169e9062c9b7ff902012a40..13e3d3e3861622001ddcf7a62129e6070f94d2a2 100644
--- a/main.c
+++ b/main.c
@@ -8,29 +8,68 @@
 #include <time.h>
 #include "puissance.h"
 
-int main() {
+void play_against_random_ai(puissance game) {
+    int selected_col_index = -1;
+
+    while(game.state == ONGOING) {
+        if (game.current_player == PLAYER_ONE) {
+            printf("Waiting for player one (" PLAYER_ONE_STRING ")...\n");
+            do {
+                scanf("%d", &selected_col_index);
+                selected_col_index -= 1;
+            } while (manual_play(&game, selected_col_index) == false);
+        } else {
+            random_play(&game);
+        }
+        print_game(game);
+    }
+}
+
+void play_against_human(puissance game) {
+    int selected_col_index = -1;
+
+    while(game.state == ONGOING) {
+        if (game.current_player == PLAYER_ONE) {
+            printf("Waiting for player one (" PLAYER_ONE_STRING ")...\n");
+
+        } else {
+            printf("Waiting for player two (" PLAYER_TWO_STRING ")...\n");
+        }
+
+        do {
+            scanf("%d", &selected_col_index);
+            selected_col_index -= 1;
+        } while (manual_play(&game, selected_col_index) == false);
+        print_game(game);
+    }
+}
+
+int main(int argc, char *argv[]) {
     srand(time(NULL));
     puissance game;
 
-    game_init(&game, RAND_AI, DEFAULT_ROW, DEFAULT_COL);
-    manual_play(&game, 0);
-    manual_play(&game, 1);
-    print_game(game);
-    manual_play(&game, 1);
-    manual_play(&game, 2);
-    print_game(game);
-    manual_play(&game, 3);
-    manual_play(&game, 2);
-    print_game(game);
-    manual_play(&game, 2);
-    manual_play(&game, 3);
-    print_game(game);
-    manual_play(&game, 4);
-    manual_play(&game, 3);
-    print_game(game);
-    manual_play(&game, 3);
+    if (argc != 4) {
+        printf("The program must have 3 arguments.\n");
+        return EXIT_FAILURE;
+    }
+
+    GameMode mode = atoi(argv[1]) - 1;
+    int nb_rows = atoi(argv[2]);
+    int nb_cols = atoi(argv[3]);
+
+    game_init(&game, mode, nb_rows, nb_cols);
     print_game(game);
 
+    switch (mode) {
+        case RAND_AI:
+            play_against_random_ai(game);
+        case SMART_AI:
+            break;
+        case TWO_PLAYERS:
+            play_against_human(game);
+            break;
+    }
+
     game_destroy(&game);
     
     return EXIT_SUCCESS;
diff --git a/puissance.c b/puissance.c
index 501b57fa9783dc1f2d3446e33ff28eff9bd477c0..cff3d57ee334893ef97c5b4ea683251d4eb4a2dc 100644
--- a/puissance.c
+++ b/puissance.c
@@ -169,24 +169,17 @@ GameResult horizontal_game_check(puissance *p, int last_col_index_played) {
     int last_row_index_played = get_available_row_index(p, last_col_index_played) + 1;
     int last_played_value = p->data[last_row_index_played][last_col_index_played];
 
-    // Verify the left
-    if (last_col_index_played - NB_VERIFICATION_FOR_WIN >= 0) {
-        four_aligned = true;
-        for (int i = 1; i <= NB_VERIFICATION_FOR_WIN; i++) {
-            if (last_played_value != p->data[last_row_index_played][last_col_index_played - i]) {
-                four_aligned = false;
-                break;
-            }
+    int same_aligned = 0;
+    for (int i = 0; i < p->col; i++) {
+        if (last_played_value == p->data[last_row_index_played][i]) {
+            same_aligned++;
+        } else {
+            same_aligned = 0;
         }
-    }
-    // Verify the right
-    if (last_col_index_played + NB_VERIFICATION_FOR_WIN < p->col && four_aligned == false) {
-        four_aligned = true;
-        for (int i = 1; i <= NB_VERIFICATION_FOR_WIN; i++) {
-            if (last_played_value != p->data[last_row_index_played][last_col_index_played + i]) {
-                four_aligned = false;
-                break;
-            }
+
+        if (same_aligned == NB_SAME_VALUE_ALIGNED_FOR_WIN) {
+            four_aligned = true;
+            break;
         }
     }
 
@@ -275,7 +268,7 @@ GameResult display_game_result(GameResult gr) {
 int get_available_row_index(puissance *p, int selected_col_index) {
     // Verify the index selected
     if (selected_col_index >= p->col || selected_col_index < 0) {
-        return EMPTY_CELL_VALUE;
+        return EMPTY_CELL_VALUE; // Bad index
     }
 
     for (int i = p->row - 1; i >= 0; i--) {
@@ -283,13 +276,13 @@ int get_available_row_index(puissance *p, int selected_col_index) {
             return i;
         }
     }
-    return EMPTY_CELL_VALUE;
+    return -1; // No remaining row
 }
 
 bool manual_play(puissance *p, int selected_col_index) {
     // Get the available row index and verify that the column is not full.
     int row_index = get_available_row_index(p, selected_col_index);
-    if (row_index == EMPTY_CELL_VALUE) {
+    if (row_index < 0) {
         return false;
     }