diff options
Diffstat (limited to 'src/valid_moves.c')
-rw-r--r-- | src/valid_moves.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/valid_moves.c b/src/valid_moves.c new file mode 100644 index 0000000..bcbbd46 --- /dev/null +++ b/src/valid_moves.c @@ -0,0 +1,105 @@ +#include <stdbool.h> + +#include "othello.h" + +bool is_valid_move(const player_color board[8][8], + const player_color current_player, const struct move move) { + // The move must be a positive position + if (move.row < 0 || move.col < 0) { + return false; + } + // The move must be an empty spot to be valid + if (board[move.row][move.col] != EMPTY) { + return false; + } + + const player_color other_color = current_player == WHITE ? BLACK : WHITE; + + bool is_valid_up = false; + bool is_valid_down = false; + bool is_valid_left = false; + bool is_valid_right = false; + + if (!is_valid_up && !is_valid_down && !is_valid_left && !is_valid_right) { + // Check if valid up + bool would_flip_oppenent = false; + bool has_other_end = false; + for (int i = move.row - 1; i > 0 && !has_other_end; i--) { + if (board[i][move.col] == current_player) { + has_other_end = true; + } else if (board[i][move.col] == other_color) { + would_flip_oppenent = true; + } else { + // We have reached an empty tile + break; + } + } + is_valid_up = has_other_end && would_flip_oppenent; + } + + if (!is_valid_up && !is_valid_down && !is_valid_left && !is_valid_right) { + // Check if valid down + bool would_flip_oppenent = false; + bool has_other_end = false; + for (int i = move.row + 1; i < 8 && !has_other_end; i++) { + if (board[i][move.col] == current_player) { + has_other_end = true; + } else if (board[i][move.col] == other_color) { + would_flip_oppenent = true; + } else { + // We have reached an empty tile + break; + } + } + is_valid_down = has_other_end && would_flip_oppenent; + } + + if (!is_valid_up && !is_valid_down && !is_valid_left && !is_valid_right) { + // Check if valid left + bool would_flip_oppenent = false; + bool has_other_end = false; + for (int i = move.col - 1; i > 0 && !has_other_end; i--) { + if (board[move.row][i] == current_player) { + has_other_end = true; + } else if (board[move.row][i] == other_color) { + would_flip_oppenent = true; + } else { + // We have reached an empty tile + break; + } + } + is_valid_left = has_other_end && would_flip_oppenent; + } + + if (!is_valid_up && !is_valid_down && !is_valid_left && !is_valid_right) { + // Check if valid right + bool would_flip_oppenent = false; + bool has_other_end = false; + for (int i = move.col + 1; i < 8 && !has_other_end; i++) { + if (board[move.row][i] == current_player) { + has_other_end = true; + } else if (board[move.row][i] == other_color) { + would_flip_oppenent = true; + } else { + // We have reached an empty tile + break; + } + } + is_valid_right = has_other_end && would_flip_oppenent; + } + + return is_valid_up || is_valid_down || is_valid_left || is_valid_right; +} + +bool has_valid_moves(const player_color board[8][8], + const player_color current_player) { + bool result = false; + struct move move; + for (move.row = 0; move.row < 8 && !result; move.row++) { + for (move.col = 0; move.col < 8 && !result; move.col++) { + result = is_valid_move(board, current_player, move); + } + } + + return result; +} |