TP 13 exo2: Robustify the current tic-tac-toe implementation
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 23 Mar 2017 19:48:52 +0000 (20:48 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 23 Mar 2017 19:48:52 +0000 (20:48 +0100)
* Make the round count follow the coordinates array index.
  And simplify all the loop and conditions depending on it;

* Implement the feature allowing to play again.

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
TP_13/exo2/lib/coordinates.c
TP_13/exo2/lib/coordinates.h
TP_13/exo2/src/main.c

index 2f02405f9f24f4d678cd297bfd739d7702e01a72..883f11962521c4561d197b67da734490a003eed6 100644 (file)
@@ -25,6 +25,11 @@ void init_coordinates(coordinates_t* coordinates_array) {
     }
 }
 
+void reinit_coordinates(coordinates_t* coordinates_array) {
+
+    init_coordinates(coordinates_array);
+}
+
 coordinates_t set_coordinates(int y, int x, unsigned type) {
     coordinates_t new_coordinates;
 
@@ -44,8 +49,8 @@ unsigned add_coordinates(coordinates_t new_coordinates, coordinates_t* coordinat
     /* valid coordinates are in the [1-3] range */
     if (new_coordinates.y < 1 || new_coordinates.y > 3 || new_coordinates.x < 1 || new_coordinates.x > 3) {
         return 3; /* error value for invalid coordinates */
-    } else if (round == MAX_COORDINATES) {
-        /* round is off-by-one */
+    } else if (round == MAX_COORDINATES - 1) {
+        /* round is off-by-one vs. MAX_COORDINATES */
         coordinates_array[MAX_COORDINATES - 1] = new_coordinates;
         return 1; /* error value for full array */
     }
@@ -65,7 +70,7 @@ static bool chk_line(coordinates_t* coordinates_array, int line_number, unsigned
     unsigned nb_o_align = 0;
     unsigned nb_x_align = 0;
 
-    for (unsigned i = 0; i < round; i++) {
+    for (unsigned i = 0; i <= round; i++) {
         /* check if they are all the same */
         if ((coordinates_array + i)->y == line_number && (coordinates_array + i)->type == 0) {
             nb_o_align++;
@@ -84,7 +89,7 @@ static bool chk_column(coordinates_t* coordinates_array, int column_number, unsi
     unsigned nb_o_align = 0;
     unsigned nb_x_align = 0;
 
-    for (unsigned i = 0; i < round; i++) {
+    for (unsigned i = 0; i <= round; i++) {
         /* check if they are all the same */
         if ((coordinates_array + i)->x == column_number && (coordinates_array + i)->type == 0) {
             nb_o_align++;
@@ -104,7 +109,7 @@ static bool chk_diagonals(coordinates_t* coordinates_array, unsigned round) {
     unsigned nb_o_diag_one = 0, nb_o_diag_two = 0;
     unsigned nb_x_diag_one = 0, nb_x_diag_two = 0;
 
-    for (unsigned i = 0; i < round; i++) {
+    for (unsigned i = 0; i <= round; i++) {
         /* dumb count of each elements type in the two diagonals */
         for (int y_x_diag = 1; y_x_diag < 4; y_x_diag++) {
             if ((coordinates_array + i)->y == y_x_diag && (coordinates_array + i)->x == y_x_diag && (coordinates_array + i)->type == 0) {
@@ -129,8 +134,8 @@ static bool chk_diagonals(coordinates_t* coordinates_array, unsigned round) {
 
 bool chk_win_conditions(coordinates_t* coordinates_array, unsigned round) {
 
-    /* winning conditions begin at round = 5 */
-    if (round > 4) {
+    /* winning conditions begin at round = 4 */
+    if (round > 3) {
         if (chk_diagonals(coordinates_array, round)) {
             return true;
         }
index b396c3d890c92896336d04c5b8cd41613090dfbc..e236e3b75d7d634914c35a3c0f53e0ce812b0a12 100644 (file)
@@ -31,6 +31,7 @@ typedef struct coordinates_s {
 } coordinates_t;
 
 void init_coordinates(coordinates_t* coordinates_array);
+void reinit_coordinates(coordinates_t* coordinates_array);
 coordinates_t set_coordinates(int y, int x, unsigned type);
 unsigned add_coordinates(coordinates_t new_coordinates, coordinates_t* coordinates_array, unsigned round);
 bool chk_win_conditions(coordinates_t* coordinates_array, unsigned round);
index 8978ef2eee6ed33ce70c14b70a4f956e428769c7..d57be23271c7e3d812ee9fba647d722fd4e7a02f 100644 (file)
@@ -7,10 +7,10 @@
 #include "coordinates.h"
 
 int main() {
-    int row, col, errno = 0, round = 0, player = 0, key_pressed;
+    int row, col, errno = 0, round = 0, player = 0, key_pressed = 0;
     bool winning_condition = false;
     bool loop_exit_condition = false;
-    const int str_max_length = 255;
+    const int str_max_length = 50;
     /* FIXME: make a strings handling library */
     char* top_msg = malloc(str_max_length * sizeof(char));
     char* back_msg = malloc(str_max_length * sizeof(char));
@@ -30,12 +30,8 @@ int main() {
     int base_y = row/2 - 4;
     int base_x = col/2 - 7;
 
-    print_board(base_y, base_x);
-
     do {
-        if (errno == 0) round++;
-
-        if (round % 2 == 0) {
+        if (round % 2 != 0) {
             player = 1;
             top_msg = "Joueur 2 joue";
         } else {
@@ -45,6 +41,8 @@ int main() {
 
         mvprintw(base_y - 2, (base_x + 7 - strlen(top_msg)/2), top_msg);
 
+        print_board(base_y, base_x);
+
         print_coordinates(coordinates_array, base_y, base_x);
 
         /* FIXME: group the winning case code blocks */
@@ -88,11 +86,15 @@ int main() {
             winning_condition = chk_win_conditions(coordinates_array, round);
         }
 
+        if (errno == 0) {
+            round++;
+        }
+
         if (winning_condition) {
             if (player == 0) {
-                back_msg = "Joureur 1 gagne !";
+                back_msg = "Joueur 1 gagne !";
             } else {
-                back_msg = "Joureur 2 gagne !";
+                back_msg = "Joueur 2 gagne !";
             }
         }
 
@@ -106,8 +108,9 @@ int main() {
             } else if (errno == 4) {
                 back_msg = "Erreur inconnue";
             } else if (errno == 0) {
-                /* FIXME: properly zero the string */
+                /* FIXME: properly zero the string to avoid the clear() */
                 back_msg = "";
+                clear();
             }
         }
 
@@ -116,18 +119,29 @@ int main() {
         if (winning_condition || errno == 1) {
             /* print the updated coordinates before exiting */
             print_coordinates(coordinates_array, base_y, base_x);
-            exit_msg = "Pressez une touche pour sortir";
+            exit_msg = "Pressez une touche pour sortir ou \'r\' pour rejouer";
             mvprintw(base_y + 12, (base_x + 7 - strlen(exit_msg)/2), exit_msg);
             loop_exit_condition = true;
+            if (loop_exit_condition) {
+                int key_exit = 0;
+                /* getch() is blocking */
+                key_exit = getch();
+                if (key_exit == 'r') {
+                    round = 0;
+                    player = 0;
+                    errno = 0;
+                    reinit_coordinates(coordinates_array);
+                    winning_condition = false;
+                    loop_exit_condition = false;
+                    clear();
+                }
+            }
         }
 
         refresh();
 
     } while (!loop_exit_condition);
 
-    /* getch() is blocking */
-    getch();
-
     endwin();
 
     if (!top_msg)