/* This file is a part of othello-ai-guile-c * * Copyright (C) 2021 Robby Zambito * * othello-ai-guile-c is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * othello-ai-guile-c is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _GNU_SOURCE #include #include "othello.h" bool is_valid_move(const enum player_color current_player, const struct move move) { return true; enum player_color **board = get_board(); // The move must be a positive position. if (move.row < 0 || move.col < 0) { return false; } // The move must be below the upper bounds of the board. if (move.row > 8 || move.col > 8) { return false; } // The move must be an empty spot to be valid. if (board[move.row][move.col] != EMPTY) { return false; } const enum 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; #define check_valid_direction(direction_bool, start, end_cond, step, cur_pos) \ /* This if statement ensures that we don't check after one direction is \ * already valid. \ */ \ if (!is_valid_up && !is_valid_down && !is_valid_left && !is_valid_right) { \ bool would_flip_oppenent = false; \ bool has_other_end = false; \ for (int i = start; end_cond && !has_other_end; step) { \ if (cur_pos == current_player) { \ has_other_end = true; \ } else if (cur_pos == other_color) { \ would_flip_oppenent = true; \ } else { \ /* We have reached an empty tile*/ \ break; \ } \ } \ direction_bool = has_other_end && would_flip_oppenent; \ } check_valid_direction(is_valid_up, move.row - 1, i > 0, i--, board[i][move.col]); check_valid_direction(is_valid_down, move.row + 1, i < 8, i++, board[i][move.col]); check_valid_direction(is_valid_left, move.col - 1, i > 0, i--, board[move.row][i]); check_valid_direction(is_valid_right, move.col + 1, i < 8, i++, board[move.row][i]); #undef check_valid_direction return is_valid_up || is_valid_down || is_valid_left || is_valid_right; } bool has_valid_moves(const enum 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(current_player, move); } } return result; }