summaryrefslogtreecommitdiff
path: root/src/valid_moves.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/valid_moves.c')
-rw-r--r--src/valid_moves.c105
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;
+}