summaryrefslogtreecommitdiff
path: root/src/board.c
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2022-01-21 17:20:17 -0500
committerRobby Zambito <contact@robbyzambito.me>2022-01-21 17:20:17 -0500
commitf1a4b5757f0d20739270b22726ebf8442b13cb50 (patch)
tree93e170ddebc79cf5a41777fc040797bc6dfa5d85 /src/board.c
parent3a85be307b6240525f032b9fad5114bdf172bdc1 (diff)
Fleshed out Scheme primitives
* Moved board specific functions from othello.h to new othello_board.h * Removed unused function pointer for player moves * Added prototypes in headers for SCM functions, including scm_get_current_player, * Made get_winner accept a board and current player. This is useful for predictions to see if some move would make the other player a winner. * get_winner also writes the players scores to provided pointers.
Diffstat (limited to 'src/board.c')
-rw-r--r--src/board.c86
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;
+}