Implement :
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 28 Apr 2017 22:03:41 +0000 (00:03 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 28 Apr 2017 22:03:41 +0000 (00:03 +0200)
* Already played shots linked list;
* Terminal min size detection;
* Some helper functions and declare helpful data structures.

Fix also a bunch of compiler warnings.

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
analyse_descendante
lib/constants.c
lib/constants.h
lib/debug.c
lib/othello.c
lib/othello.h
lib/ui.c
lib/ui.h
src/main.c

index 2baa9bce82d66c50ba332e15c61ea97583696e66..b3f559eb30044e34cca264e567eec3f7b9117fbe 100644 (file)
@@ -53,3 +53,12 @@ Sinon si case contient un pion adverse
     alors continuer l'exploration dans la même direction;
 Sinon si case contient pion du joueur
     alors les pions adverses vus précédement doivent être retournés
+
+explorer(i, j, dir)
+Si Vide ou Dehors
+    Rien à faire
+Sinon
+    Si PionAdverse
+       explorer CaseSuivante
+    Sinon 
+       RetournerPionsRencontrés
index 289bf044d315109ecaedd536e444c2b3651d61a0..7248975a9429671f4ab7d81ab40ed73b608041a4 100644 (file)
@@ -32,3 +32,12 @@ const unsigned int player_two = 2;
 
 const unsigned int hint_allowed = 3;
 const unsigned int hint_forbidden = 4;
+
+const unsigned int north = 5;
+const unsigned int north_east = 6;
+const unsigned int east = 7;
+const unsigned int south_east = 8;
+const unsigned int south = 9;
+const unsigned int south_west = 10;
+const unsigned int west = 11;
+const unsigned int north_west = 12;
index 186e5dba3485420051252baa43116bacb05cae9f..976b299b593bfad8b5eb5be475b883a6f327f333 100644 (file)
@@ -32,5 +32,14 @@ extern const unsigned int player_two; /* white */
 extern const unsigned int hint_allowed; /* legal place for a pawn */
 extern const unsigned int hint_forbidden; /* illegal place for a pawn */
 
+extern const unsigned int north;
+extern const unsigned int north_east;
+extern const unsigned int east;
+extern const unsigned int south_east;
+extern const unsigned int south;
+extern const unsigned int south_west;
+extern const unsigned int west;
+extern const unsigned int north_west;
+
 #endif /* CONSTANTS_H */
 
index e3229901502f1d0da3306b640faa1b57955ef5ef..a2bf9ee63242387fe8375c998fe5fa7ae1438c04 100644 (file)
@@ -22,5 +22,5 @@
 
 void dbg_mvprintw(int base_y, int base_x, const char* fmt, va_list varglist) {
 
-    mvprintw(base_y, base_x - strlen(fmt)/2, fmt, varglist);
+    mvprintw(base_y, base_x - snprintf(NULL, 0, fmt, varglist)/2, fmt, varglist);
 }
index 4bbf120d6ed2da3dc6dc43e7dc720b14f9356b9a..1115e92d82563ac0e795ba8d1d633c81d48f2004 100644 (file)
@@ -31,7 +31,7 @@ unsigned int current_player(unsigned int round_count) {
 }
 
 /* for consitency with ncurses, the board coordinates are in the following order:
- * O-x-->
+ * O--x-->
  * |
  * y
  * |
@@ -55,12 +55,12 @@ bool is_box_type(int y, int x, unsigned int pawn_array[board_size][board_size],
     }
 }
 
-/* helper function to set a value != empty at the (y, x) in the pawns array */
+/* helper function to set a value != empty at the (y, x) coordinates in the pawns array */
 int** set_pawn(int y, int x, unsigned int type, unsigned int pawn_array[board_size][board_size]) {
 
     if (is_box_type(y, x, pawn_array, empty)) {
         pawn_array[y-1][x-1] = type;
-        return pawn_array;
+        return (int**)pawn_array;
     } else {
         return NULL;
     }
@@ -73,7 +73,7 @@ static int** zero_pawns(unsigned int pawn_array[board_size][board_size]) {
             pawn_array = set_pawn(i, j, empty, pawn_array);
          }
     }
-    return pawn_array;
+    return (int**)pawn_array;
 }
 
 /* set the pawns in the start position */
@@ -84,7 +84,7 @@ int** init_pawns(unsigned int pawn_array[board_size][board_size]) {
     pawn_array = set_pawn(4, 5, black, pawn_array);
     pawn_array = set_pawn(4, 4, white, pawn_array);
     pawn_array = set_pawn(5, 5, white, pawn_array);
-    return pawn_array;
+    return (int**)pawn_array;
 }
 
 unsigned int count_pawn_type(unsigned int pawn_array[board_size][board_size], unsigned int type) {
@@ -95,7 +95,7 @@ unsigned int count_pawn_type(unsigned int pawn_array[board_size][board_size], un
     }
     for (unsigned int i = 1; i <= board_size; i++) {
         for (unsigned int j = 1; j <= board_size; j++) {
-            if (get_box_value(i, j, pawn_array) == type) {
+            if (is_box_type(i, j, pawn_array, type)) {
                 count++;
             }
         }
@@ -117,6 +117,7 @@ bool is_valid_input(int y, int x, unsigned int pawn_array[board_size][board_size
 
 bool is_board_full(unsigned int pawn_array[board_size][board_size]) {
 
+    /* an alternate method is to test the round count vs. 60 */
     for (unsigned int i = 1; i <= board_size; i++) {
         for (unsigned int j = 1; j <= board_size; j++) {
             if (is_box_type(i, j, pawn_array , empty)) {
@@ -138,14 +139,31 @@ unsigned int eval_winner(unsigned int nb_white, unsigned int nb_black) {
     }
 }
 
-void status_pawn(int y, int x, unsigned int pawn_array[board_size][board_size]) {
-
-}
-
-bool is_legal_box(int y, int x, int player, unsigned int pawn_array[board_size][board_size]) {
-
+void direction_to_coordinates(unsigned int direction, int* start_y, int* start_x) {
+
+    if (direction == north) {
+        *start_y = *start_y - 1;
+    } else if (direction == north_east) {
+        *start_y = *start_y - 1;
+        *start_x = *start_x + 1;
+    } else if (direction == east) {
+        *start_x = *start_x + 1;
+    } else if (direction == south_east) {
+        *start_y = *start_y + 1;
+        *start_x = *start_x + 1;
+    } else if (direction == south) {
+        *start_y = *start_y + 1;
+    } else if (direction == south_west) {
+        *start_y = *start_y + 1;
+        *start_x = *start_x - 1;
+    } else if (direction == west) {
+        *start_x = *start_x - 1;
+    } else if (direction == north_west) {
+        *start_y = *start_y - 1;
+        *start_x = *start_x - 1;
+    }
 }
 
-bool reverse_box(unsigned int pawn_array[board_size][board_size]) {
+bool explore(int y, int x, int direction) {
 
 }
index 24bf9fb30750f47dedb4b170ef58f5a2e7e57df4..a591405db2563216aba4452a265b9d895fdc9801 100644 (file)
 #include "constants.h"
 #include "list.h"
 
-struct shots_list {
+/* TODO: must be used to replace the explicit pawns 2D array */
+struct pawns_s {
+    unsigned int pawns[board_size][board_size];
+};
+
+/* linked list of played shots */
+struct shots_history_list_s {
+    struct list_head list;
+    unsigned int*** pawn_array_member; /* pointer to a cell of the pawns 2D array */
+    /* struct* pawns_s pawn */
+};
+
+/* linked list of can play shots */
+struct shots_exploration_s {
     struct list_head list;
-    unsigned int*** pawn_array_member;
+    int y;
+    int x;
+    unsigned int type;
 };
 
 unsigned int current_player(unsigned int round_count);
index ae14d1df861be54fe1d6160ecef48c86d660d3f2..be739aaa037d89ff66b96f7ec788425db1ece497 100644 (file)
--- a/lib/ui.c
+++ b/lib/ui.c
@@ -129,7 +129,7 @@ void print_pawns(int base_y, int base_x, unsigned int pawn_array[board_size][boa
     }
 }
 
-int map_col_letter_to_int(char c) {
+int map_col_letter_to_index(char c) {
     
     if (c == 'a' || c == 'A') {
         return 1;
@@ -152,6 +152,30 @@ int map_col_letter_to_int(char c) {
     }
 }
 
+/* return capital letters */
+char map_col_index_to_letter(int index) {
+    
+    if (index == 1) {
+        return 'A';
+    } else if (index == 2) {
+        return 'B';
+    } else if (index == 3) {
+        return 'C';
+    } else if (index == 4) {
+        return 'D';
+    } else if (index == 5) {
+        return 'E';
+    } else if (index == 6) {
+        return 'F';
+    } else if (index == 7) {
+        return 'G';
+    } else if (index == 9) {
+        return 'H';
+    } else {
+        return -1;
+    }
+}
+
 int prompt_values(WINDOW* windows, int base_y, int base_x, const char* msg, int* y, char* x) {
     mvwprintw(windows, base_y, base_x, "%s\n", msg);
     int retVal = mvwscanw(windows, base_y + 1, base_x + strlen(msg)/2, "%d%c", y, x);
index b24b6740ef63e3320b85364365fecabdb9bf58aa..c93a091f681cec305b33cd1e3f0f7aee9cbf3781 100644 (file)
--- a/lib/ui.h
+++ b/lib/ui.h
@@ -25,7 +25,8 @@
 
 int prompt_values(WINDOW* windows, int base_y, int base_x, const char* msg, int* y, char* x);
 
-int map_col_letter_to_int(char c);
+int map_col_letter_to_index(char c);
+char map_col_index_to_letter(int index);
 
 /* ncurses printing */
 void print_board(int y, int x);
index b8c0c5e4c9bd1b05ac2ab4d83e5ab63f85f1def5..6a56eed094f9393d6c8a598af3873e370a6b7f52 100644 (file)
@@ -8,20 +8,17 @@
 #include "debug.h"
 
 int main() {
-    int min_y = 26, min_x = 42;
+    int min_y = 26 + 6, min_x = 42 + 14 + 15 + 4;
     int row = 0, col = 0;
     unsigned int round = 0;
     unsigned int player = player_one; /* first player is black */
     bool exit_condition = false;
     unsigned int nb_white = 0, nb_black = 0;
 
-    LIST_HEAD(shots_list);
-
     char* title_msg = "Jeu Othello";
-    char* score_white_msg = "Pions blancs: %d";
-    char* score_black_msg = "Pions noirs: %d";
-    char* player_msg = "Joueur %d joue !";
-    char* winner_msg = "Joueur %d gagne !";
+    char* score_msg = "Pions %s: %d";
+    char* player_msg = "Joueur %d (%s) joue !";
+    char* winner_msg = "Joueur %d (%s) gagne !";
     char* draw_msg = "Egalite !";
 
     unsigned int pawns[board_size][board_size] = {{}};
@@ -30,11 +27,17 @@ int main() {
     initscr();
     if (has_colors() == false) {
         endwin();
-        printf("Votre terminal ne supporte pas les couleurs\n");
+        printf("Votre terminal ne supporte pas les couleurs.\n");
         exit(EXIT_FAILURE);
     }
     start_color();
     getmaxyx(stdscr, row, col);
+    if (row < min_y || col < min_x) {
+        endwin();
+        printf("Votre terminal est trop petit pour afficher le jeu.\n");
+        printf("Merci d'agrandir la fenetre de votre terminal.\n");
+        exit(EXIT_FAILURE);
+    }
     /* FIXME: fail if the screen size is too small */
     echo();
     curs_set(0);
@@ -54,41 +57,51 @@ int main() {
 
         player = current_player(round);
 
-        mvprintw(center_y - 26/2 - 2, (center_x - strlen(player_msg)/2), player_msg, player);
+        if (player == player_one) {
+            mvprintw(center_y - 26/2 - 2, center_x - snprintf(NULL, 0, player_msg, player, "noir")/2, player_msg, player, "noir");
+        } else {
+            mvprintw(center_y - 26/2 - 2, center_x - snprintf(NULL, 0, player_msg, player, "blanc")/2, player_msg, player, "blanc");
+        }
 
         nb_white = count_pawn_type(pawns, white);
         nb_black = count_pawn_type(pawns, black);
         
-        mvprintw(center_y, center_x - 42/2 - strlen(score_white_msg) - 2, score_white_msg, nb_white);
-        mvprintw(center_y, center_x + 42/2 + 2, score_black_msg, nb_black);
+        mvprintw(center_y, center_x - 42/2 - snprintf(NULL, 0, score_msg, "noirs", nb_black) - 2, score_msg, "noirs", nb_black);
+        mvprintw(center_y, center_x + 42/2 + 2, score_msg, "blancs", nb_white);
 
         int y;
         char x;
         bool input_ok = false;
         do {
             y = 0;
-            x = "";
+            x = (char)"";
             char* prompt_msg = "Prochain pion ? (ligne colonne - chiffre lettre):";
             int prmt_rt = prompt_values(stdscr, center_y + 26/2 + 1, center_x - strlen(prompt_msg)/2, prompt_msg, &y, &x);
-            if (is_valid_input(y, map_col_letter_to_int(x), pawns) && prmt_rt == 1) {
+            if (is_valid_input(y, map_col_letter_to_index(x), pawns) && prmt_rt == 1) {
                 input_ok = true;
             }
         } while (!input_ok);
-        pawns[board_size][board_size] = set_pawn(y, map_col_letter_to_int(x), player, pawns);
-        struct shots_list shot_current;
-        shot_current.pawn_array_member = &pawns[y-1][x-1];
-        //list_add(shot_current.list, shots_list.list);
+        pawns[board_size][board_size] = set_pawn(y, map_col_letter_to_index(x), player, pawns);
+        struct shots_history_list_s shots_history;
+        INIT_LIST_HEAD(&shots_history.list);
+        struct shots_history_list_s shots_elmt; 
+        shots_elmt.pawn_array_member = &pawns[y-1][x-1];
+        list_add(&shots_elmt.list, &shots_history.list);
 
         round++; /* increment the round count */
 
         refresh();
 
         /* here are all the end of the game conditions */
-        //if (is_board_full(pawns) || round == 60) {
+        //if (is_board_full(pawns) || (round == 60)) {
         if (is_board_full(pawns)) {
             int winner = eval_winner(nb_white, nb_black);
             if (winner != 0) {
-                mvprintw(center_y - 26/2 - 2, (center_x - strlen(winner_msg)/2), winner_msg, winner);
+                if (winner == player_one) {
+                    mvprintw(center_y - 26/2 - 2, center_x - snprintf(NULL, 0, winner_msg, winner, "noir"), winner_msg, winner, "noir");
+                } else {
+                    mvprintw(center_y - 26/2 - 2, center_x - snprintf(NULL, 0, winner_msg, winner, "blanc"), winner_msg, winner, "blanc");
+                }
             } else {
                 mvprintw(center_y - 26/2 - 2, (center_x - strlen(draw_msg)/2), draw_msg);
             }