X-Git-Url: https://git.piment-noir.org/?p=Project_algorithmic_C.git;a=blobdiff_plain;f=lib%2Fothello.c;h=e1290b4f3f39e6455e8711e784404827552c77aa;hp=1115e92d82563ac0e795ba8d1d633c81d48f2004;hb=a80646b74eca11c71696dedeb674870437c5bb6f;hpb=45ce2fe369cead248855111baa5fe0c0495acf69 diff --git a/lib/othello.c b/lib/othello.c index 1115e92..e1290b4 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,7 +32,16 @@ unsigned int current_player(unsigned int round_count) { } } -/* for consitency with ncurses, the board coordinates are in the following order: +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,46 +66,63 @@ 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) coordinates 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; + } +} + +/* 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 (is_box_type(y, x, pawn_array, empty)) { + if (type > 0 && type < 3 && \ + is_valid_coordinates(y, x)) { pawn_array[y-1][x-1] = type; - return (int**)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); + } +} + +void zero_pawns(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++) { - pawn_array = set_pawn(i, j, empty, pawn_array); + for (int i = 1; i <= board_size; i++) { + for (int j = 1; j <= board_size; j++) { + set_pawn(i, j, empty, pawn_array); } } - return (int**)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 (int**)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++) { + 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,23 +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]) { /* 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++) { + 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; } @@ -139,31 +180,51 @@ unsigned int eval_winner(unsigned int nb_white, unsigned int nb_black) { } } -void direction_to_coordinates(unsigned int direction, int* start_y, int* start_x) { +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_reserved = 0; + int moving_y = y, moving_x = 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; + /* count for pawn 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_reserved++; + direction_to_coordinates(direction, &moving_y, &moving_x); + } + + /* now reverse the needed panws */ + if (nb_pawns_reserved > 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_reserved; } -bool explore(int y, int x, int direction) { +/* 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_reserved = 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_reserved += reverse_one_direction(y, x, direction, current_player, pawn_array); + } + + if (nb_pawns_reserved == 0) { + return 0; + } + set_pawn(y, x, current_player, pawn_array); + return nb_pawns_reserved; }