/* 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 #include #include #include #include #include #include "othello.h" #include "othello_board.h" #include "othello_move.h" #define STREQ(a, b) (strcmp(a, b) == 0) static enum player_color current_player; #define other_player (current_player == WHITE ? BLACK : WHITE) enum player_color get_current_player(void) { return current_player; } SCM scm_get_current_player() { return scm_player_from_c_player(current_player); } SCM scm_get_other_player() { return scm_player_from_c_player(other_player); } SCM scm_player_from_c_player(enum player_color player) { switch (player) { case WHITE: return scm_from_utf8_symbol("white"); case BLACK: return scm_from_utf8_symbol("black"); default: return scm_from_utf8_symbol("empty"); } } enum player_color scm_player_to_c_player(SCM player) { if (scm_is_true(scm_eq_p(player, scm_from_utf8_symbol("white")))) { return WHITE; } else if (scm_is_true(scm_eq_p(player, scm_from_utf8_symbol("black")))) { return BLACK; } else { return EMPTY; } } static struct move current_player_move(enum player_color current_player, char *player_one_strategy_path, char *player_two_strategy_path, struct move *flipped_by_last_turn, size_t flipped_by_last_turn_length) { struct move move = {-1, -1}; if ((current_player == WHITE && player_one_strategy_path == NULL) || (current_player == BLACK && player_two_strategy_path == NULL)) { move = prompt_get_move(current_player, flipped_by_last_turn, flipped_by_last_turn_length); } else if (current_player == WHITE) { move = get_scm_move(player_one_strategy_path); } else if (current_player == BLACK) { move = get_scm_move(player_two_strategy_path); } return move; } enum player_color game_loop(char *player_one_strategy_path, char *player_two_strategy_path, int *white_score, int *black_score) { initialize_board(); if (player_one_strategy_path == NULL || player_two_strategy_path == NULL) { using_history(); } current_player = WHITE; struct move *flipped_by_last_turn = malloc(sizeof(struct move)); size_t flipped_by_last_turn_length = 0; size_t flipped_by_last_turn_capacity = 1; while (has_valid_moves(get_board(), current_player)) { struct move move = current_player_move( current_player, player_one_strategy_path, player_two_strategy_path, flipped_by_last_turn, flipped_by_last_turn_length); if ((flipped_by_last_turn_length = apply_move( get_board(), current_player, move, &flipped_by_last_turn, &flipped_by_last_turn_capacity))) { current_player = other_player; } } if (player_one_strategy_path == NULL || player_two_strategy_path == NULL) { rl_clear_history(); } free(flipped_by_last_turn); return get_winner(get_board(), current_player, white_score, black_score); } #undef other_player