X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Fothello.c;h=12470ee23594486a59a00e6195fa93be463371ac;hb=05e27bbf06669a1cc96112c9b133d95120b23a33;hp=b57689483770d73f30c1203e40b77f79c8588eb9;hpb=54f1c58cef6764fdd611eedc267e7491e777c09b;p=Project_algorithmic_C.git diff --git a/lib/othello.c b/lib/othello.c index b576894..12470ee 100644 --- a/lib/othello.c +++ b/lib/othello.c @@ -18,8 +18,10 @@ #include #include +#include #include "othello.h" +#include "debug.h" unsigned int current_player(unsigned int round_count) { @@ -30,8 +32,17 @@ unsigned int current_player(unsigned int round_count) { } } -/* for consitency with ncurses, the board coordinates are in the following order: - * O-x--> +unsigned int current_opponent(unsigned int current_player) { + + if (current_player == player_one) { + return player_two; + } else { + return player_one; + } +} + +/* for consistency with ncurses, the board coordinates are in the following order: + * O--x--> * | * y * | @@ -55,47 +66,64 @@ 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 */ -int** set_pawn(int y, int x, unsigned int type, unsigned int pawn_array[board_size][board_size]) { +static bool is_valid_coordinates(int y, int x) { + + if ((y > 0 && y < board_size + 1) && \ + (x > 0 && x < board_size + 1)) { + return true; + } else { + return false; + } +} - if (is_box_type(y, x, pawn_array, empty)) { +/* helper function to set a correct value at the (y, x) coordinates in the pawns array */ +void set_pawn(int y, int x, unsigned int type, unsigned int pawn_array[board_size][board_size]) { + + if (type > 0 && type < 3 && \ + is_valid_coordinates(y, x)) { pawn_array[y-1][x-1] = type; - return pawn_array; - } else { - return NULL; } } -static int** zero_pawns(unsigned int pawn_array[board_size][board_size]) { +/* reverse the pawn at (y, x) coordinates if it exists */ +static void reverse_pawn(int y, int x, unsigned int pawn_array[board_size][board_size]) { + + if (is_box_type(y, x, pawn_array, black)) { + set_pawn(y, x, white, pawn_array); + } else if (is_box_type(y, x, pawn_array, white)) { + set_pawn(y, x, black, pawn_array); + } +} - for (unsigned int i = 1; i <= board_size; i++) { - for (unsigned int j = 1; j <= board_size; j++) { - pawn_array = set_pawn(i, j, empty, pawn_array); +void zero_pawns(unsigned int pawn_array[board_size][board_size]) { + + for (int i = 1; i <= board_size; i++) { + for (int j = 1; j <= board_size; j++) { + set_pawn(i, j, empty, pawn_array); } } - return pawn_array; } /* set the pawns in the start position */ -int** init_pawns(unsigned int pawn_array[board_size][board_size]) { - - pawn_array = zero_pawns(pawn_array); - pawn_array = set_pawn(5, 4, black, pawn_array); - 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; +void init_pawns(unsigned int pawn_array[board_size][board_size]) { + + /* the 2D array zeroing is not necessary if it is properly initialized to zero */ + zero_pawns(pawn_array); + set_pawn(5, 4, black, pawn_array); + set_pawn(4, 5, black, pawn_array); + set_pawn(4, 4, white, pawn_array); + set_pawn(5, 5, white, pawn_array); } -unsigned int count_pawn_type(unsigned int pawn_array[board_size][board_size], unsigned int type) { +unsigned int count_pawns_type(unsigned int pawn_array[board_size][board_size], unsigned int type) { unsigned int count = 0; if (type > 2) { - return -1; + return 0; } - 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) { + for (int i = 1; i <= board_size; i++) { + for (int j = 1; j <= board_size; j++) { + if (is_box_type(i, j, pawn_array, type)) { count++; } } @@ -103,22 +131,36 @@ unsigned int count_pawn_type(unsigned int pawn_array[board_size][board_size], un return count; } -bool is_valid_input(int y, int x, unsigned int pawn_array[board_size][board_size]) { - - /* FIXME: separate the tests to permit to print explicit error messages */ - if ((y > 0 && y < board_size + 1) && \ - (x > 0 && x < board_size + 1) && \ - is_box_type(y, x, pawn_array, empty)) { - return true; - } else { - return false; +static 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 is_board_full(unsigned int pawn_array[board_size][board_size]) { - for (unsigned int i = 1; i <= board_size; i++) { - for (unsigned int j = 1; j <= board_size; j++) { + /* an alternate method is to test the round count vs. 60 */ + for (int i = 1; i <= board_size; i++) { + for (int j = 1; j <= board_size; j++) { if (is_box_type(i, j, pawn_array , empty)) { return false; } @@ -127,14 +169,62 @@ bool is_board_full(unsigned int pawn_array[board_size][board_size]) { return true; } -void status_pawn(int y, int x, unsigned int pawn_array[board_size][board_size]) { +unsigned int eval_winner(unsigned int nb_white, unsigned int nb_black) { + if (nb_white > nb_black) { + return player_two; + } else if (nb_white < nb_black) { + return player_one; + } else { + return 0; + } } -bool is_legal_box(int y, int x, int player, unsigned int pawn_array[board_size][board_size]) { +static unsigned int reverse_one_direction(int y, int x, int direction, unsigned int current_player, unsigned int pawn_array[board_size][board_size]) { + unsigned int nb_pawns_reversed = 0; + int moving_y = y, moving_x = x; + + /* count for pawns to reverse in the chosen direction */ + direction_to_coordinates(direction, &moving_y, &moving_x); + while (true) { + if (!is_valid_coordinates(moving_y, moving_x) || is_box_type(moving_y, moving_x, pawn_array, empty)) { + return 0; + } + if (is_box_type(moving_y, moving_x, pawn_array, current_player)) { + break; + } + nb_pawns_reversed++; + direction_to_coordinates(direction, &moving_y, &moving_x); + } + /* now reverse the needed pawns */ + if (nb_pawns_reversed > 0) { + moving_y = y, moving_x = x; + direction_to_coordinates(direction, &moving_y, &moving_x); + while (!is_box_type(moving_y, moving_x, pawn_array, current_player)) { + reverse_pawn(moving_y, moving_x, pawn_array); + direction_to_coordinates(direction, &moving_y, &moving_x); + } + } + return nb_pawns_reversed; } -bool reverse_box(unsigned int pawn_array[board_size][board_size]) { +/* play the shot if legal and flip or reverse the necessary pawns */ +unsigned int valid_shot(int y, int x, unsigned int current_player, unsigned int pawn_array[board_size][board_size]) { + unsigned int nb_pawns_reversed = 0; + + if (!is_valid_coordinates(y, x) || !is_box_type(y, x, pawn_array, empty)) { + return 0; + } + + for (unsigned int direction = north; direction <= north_west; direction++) { + nb_pawns_reversed += reverse_one_direction(y, x, direction, current_player, pawn_array); + } + + if (nb_pawns_reversed == 0) { + return 0; + } + set_pawn(y, x, current_player, pawn_array); + return nb_pawns_reversed; }