From 233750ab72abb2101a9b35211b90c0318020b2c9 Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Sun, 23 Jan 2022 17:13:28 -0500 Subject: Highlight the previous move. This is particularly helpful when using the game to play on a real board --- src/move.c | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'src/move.c') diff --git a/src/move.c b/src/move.c index 2f96ca3..9f8df44 100644 --- a/src/move.c +++ b/src/move.c @@ -36,8 +36,10 @@ static void print_help() { "p - Print the board again\n"); } -static char *prompt_player(enum player_color current_player) { - print_board(get_board()); +static char *prompt_player(enum player_color current_player, + struct move *flipped_last_turn, + size_t flipped_last_turn_length) { + print_board(get_board(), flipped_last_turn, flipped_last_turn_length); switch (current_player) { case WHITE: return "Player 1 [h for help] > "; @@ -49,11 +51,14 @@ static char *prompt_player(enum player_color current_player) { } } -struct move prompt_get_move(enum player_color current_player) { +struct move prompt_get_move(enum player_color current_player, + struct move *flipped_last_turn, + size_t flipped_last_turn_length) { // Initialize move to an invalid move. struct move move = {-1, -1}; - char *prompt = prompt_player(current_player); + char *prompt = prompt_player(current_player, flipped_last_turn, + flipped_last_turn_length); do { char *input = readline(prompt); @@ -64,7 +69,7 @@ struct move prompt_get_move(enum player_color current_player) { if (STREQ(input, "h")) { print_help(); } else if (STREQ(input, "p")) { - print_board(get_board()); + print_board(get_board(), flipped_last_turn, flipped_last_turn_length); } else { sscanf(input, "%d %d", &move.row, &move.col); } @@ -82,8 +87,9 @@ struct move prompt_get_move(enum player_color current_player) { // Returns non-zero number if the move was valid. // Returns the number of flipped tiles. -int apply_move(enum player_color **board, enum player_color current_player, - struct move move) { +size_t apply_move(enum player_color **board, enum player_color current_player, + struct move move, struct move **flipped_spots, + size_t *flipped_spots_capacity) { // The move must be a positive position. if (move.row < 0 || move.col < 0) { @@ -107,6 +113,17 @@ int apply_move(enum player_color **board, enum player_color current_player, done_flipping_up_left = false, done_flipping_up_right = false, done_flipping_down_left = false, done_flipping_down_right = false; +#define add_flipped_spot(row_in, col_in) \ + if (flipped_spots != NULL && flipped_spots_capacity != NULL) { \ + if (num_flipped == *flipped_spots_capacity) { \ + *flipped_spots_capacity *= 2; \ + *flipped_spots = reallocarray(*flipped_spots, *flipped_spots_capacity, \ + sizeof(struct move)); \ + } \ + (*flipped_spots)[num_flipped].row = (row_in); \ + (*flipped_spots)[num_flipped].col = (col_in); \ + } + for (int i = 1; i < 8; i++) { if (!done_flipping_up && (move.row - i >= 0) && board[move.row - i][move.col] == current_player) { @@ -122,6 +139,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row - j][move.col] = current_player; + add_flipped_spot(move.row - j, move.col); num_flipped++; } } @@ -143,6 +161,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row + j][move.col] = current_player; + add_flipped_spot(move.row + j, move.col); num_flipped++; } } @@ -164,6 +183,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row][move.col - j] = current_player; + add_flipped_spot(move.row, move.col - j); num_flipped++; } } @@ -185,6 +205,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row][move.col + j] = current_player; + add_flipped_spot(move.row, move.col + j); num_flipped++; } } @@ -206,6 +227,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row - j][move.col - j] = current_player; + add_flipped_spot(move.row - j, move.col - j); num_flipped++; } } @@ -227,6 +249,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row - j][move.col + j] = current_player; + add_flipped_spot(move.row - j, move.col + j); num_flipped++; } } @@ -248,6 +271,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row + j][move.col - j] = current_player; + add_flipped_spot(move.row + j, move.col - j); num_flipped++; } } @@ -269,6 +293,7 @@ int apply_move(enum player_color **board, enum player_color current_player, if (flippable) { for (int j = 0; j < i; j++) { board[move.row + j][move.col + j] = current_player; + add_flipped_spot(move.row + j, move.col + j); num_flipped++; } } @@ -278,6 +303,8 @@ int apply_move(enum player_color **board, enum player_color current_player, } } +#undef add_flipped_spot + return num_flipped; } @@ -294,7 +321,7 @@ SCM scm_apply_move(SCM scm_move, SCM scm_board, SCM scm_player) { SCM res_board; - if (apply_move(board, player, move)) { + if (apply_move(board, player, move, NULL, NULL)) { res_board = scm_board_from_c_board(board); } else { res_board = SCM_EOL; @@ -314,7 +341,7 @@ SCM scm_get_num_flipped_by_move(SCM scm_move, SCM scm_board, SCM scm_player) { enum player_color player = SCM_UNBNDP(scm_player) ? get_current_player() : scm_player_to_c_player(scm_player); - SCM res_num = scm_from_int(apply_move(board, player, move)); + SCM res_num = scm_from_int(apply_move(board, player, move, NULL, NULL)); free_board(board); return res_num; @@ -409,7 +436,7 @@ bool is_valid_move(enum player_color **board, // necessarily mutate the board yet though. enum player_color **b = copy_board(board); // Apply the move to the copy of the board. - bool res = apply_move(b, current_player, move); + bool res = apply_move(b, current_player, move, NULL, NULL); free_board(b); -- cgit v1.2.3