diff options
Diffstat (limited to 'src/board.c')
-rw-r--r-- | src/board.c | 86 |
1 files changed, 81 insertions, 5 deletions
diff --git a/src/board.c b/src/board.c index 6859952..a03fddd 100644 --- a/src/board.c +++ b/src/board.c @@ -18,14 +18,20 @@ #define _GNU_SOURCE +#include <libguile.h> #include <stdlib.h> #include "othello.h" +#include "othello_board.h" #include "othello_move.h" static enum player_color **board; -enum player_color **get_board(void) { return board; } +enum player_color **get_board() { return board; } + +SCM scm_get_board() { + return scm_board_from_c_board(board); +} void initialize_board() { board = calloc(8, sizeof(enum player_color *)); @@ -47,23 +53,42 @@ void initialize_board() { board[4][4] = WHITE; } -enum player_color get_winner() { - int white_score = 0, black_score = 0; +enum player_color get_winner(enum player_color **board, + enum player_color current_player, int *white_score, + int *black_score) { + + int ws = 0, bs = 0; for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { // This takes advantage of the fact that the 1 is the same thing as a // true, and 0 is the same thing as a false. This will count the number of // white and black spaces. - white_score += (int)(board[row][col] == WHITE); - black_score += (int)(board[row][col] == BLACK); + ws += (int)(board[row][col] == WHITE); + bs += (int)(board[row][col] == BLACK); } } + if (white_score != NULL) { + *white_score = ws; + } + if (black_score != NULL) { + *black_score = bs; + } + return white_score > black_score ? WHITE : black_score > white_score ? BLACK : EMPTY; } +SCM scm_get_winner(SCM scm_board, SCM scm_current_player) { + enum player_color **board = scm_board_to_c_board(scm_board); + enum player_color current_player = scm_player_to_c_player(scm_current_player); + + bool res = get_winner(board, current_player, NULL, NULL); + free_board(board); + return scm_from_bool(res); +} + // Should be freed be the caller enum player_color **copy_board(enum player_color **other) { enum player_color **board = calloc(8, sizeof(enum player_color *)); @@ -84,3 +109,54 @@ void free_board(enum player_color **board) { } free(board); } + +SCM scm_board_from_c_board(enum player_color **board) { + // 2D list of empty rows + SCM scm_board = + scm_make_list(scm_from_int(8), SCM_EOL); + + for (int i = 0; i < 8; i++) { + // cons up each row. + for (int j = 7; j >= 0; j--) { + if (board[i][j] == WHITE) { + scm_list_set_x(scm_board, scm_from_int(i), + scm_cons(scm_from_utf8_symbol("white"), + scm_list_ref(scm_board, scm_from_int(i)))); + } else if (board[i][j] == BLACK) { + scm_list_set_x(scm_board, scm_from_int(i), + scm_cons(scm_from_utf8_symbol("black"), + scm_list_ref(scm_board, scm_from_int(i)))); + } else { + scm_list_set_x(scm_board, scm_from_int(i), + scm_cons(scm_from_utf8_symbol("empty"), + scm_list_ref(scm_board, scm_from_int(i)))); + } + } + } + + return scm_board; +} + +enum player_color **scm_board_to_c_board(SCM scm_board) { + enum player_color **board = calloc(8, sizeof(enum player_color *)); + for (int i = 0; i < 8; i++) { + board[i] = calloc(8, sizeof(enum player_color)); + for (int j = 0; j < 8; j++) { + if (scm_is_true( + scm_eq_p(scm_list_ref(scm_list_ref(scm_board, scm_from_int(i)), + scm_from_int(j)), + scm_from_utf8_symbol("white")))) { + board[i][j] = WHITE; + } else if (scm_is_true(scm_eq_p( + scm_list_ref(scm_list_ref(scm_board, scm_from_int(i)), + scm_from_int(j)), + scm_from_utf8_symbol("black")))) { + board[i][j] = BLACK; + } else { + board[i][j] = EMPTY; + } + } + } + + return board; +} |