summaryrefslogtreecommitdiff
path: root/src/move.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/move.c')
-rw-r--r--src/move.c96
1 files changed, 88 insertions, 8 deletions
diff --git a/src/move.c b/src/move.c
index 60cf58b..aaaaf9e 100644
--- a/src/move.c
+++ b/src/move.c
@@ -66,7 +66,7 @@ struct move prompt_get_move(enum player_color current_player) {
if (STREQ(input, "h")) {
print_help();
} else if (STREQ(input, "p")) {
- print_board();
+ print_board(get_board());
/*} else if (STREQ(input, "g")) {*/
/*int argc = 1;*/
/*char **argv = calloc(1, sizeof(char *));*/
@@ -84,7 +84,7 @@ struct move prompt_get_move(enum player_color current_player) {
}
free(input);
- } while (!is_valid_move(current_player, move));
+ } while (!is_valid_move(get_board(), current_player, move));
return move;
}
@@ -185,15 +185,15 @@ static SCM scm_get_board(void) {
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_c_eval_string("'w"),
+ 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_c_eval_string("'b"),
+ 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_c_eval_string("'e"),
+ scm_cons(scm_from_utf8_symbol("empty"),
scm_list_ref(scm_board, scm_from_int(i))));
}
}
@@ -201,14 +201,94 @@ static SCM scm_get_board(void) {
return scm_board;
}
+static struct move scm_move_to_c_move(SCM scm_move) {
+ struct move move = {-1, -1};
+ move.row = scm_to_int(scm_car(scm_move));
+ move.col = scm_to_int(scm_cdr(scm_move));
+ return move;
+}
+
+static SCM scm_current_player(void) {
+ switch (get_current_player()) {
+ case WHITE:
+ return scm_from_utf8_symbol("white");
+ case BLACK:
+ return scm_from_utf8_symbol("black");
+ default:
+ return scm_from_utf8_symbol("empty");
+ }
+}
+
+static SCM scm_is_valid_move(SCM scm_board, SCM scm_player, SCM scm_move) {
+ 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;
+ }
+ }
+ }
+
+ enum player_color current_player = BLACK;
+
+ struct move move = scm_move_to_c_move(scm_move);
+ return scm_from_bool(is_valid_move(board, current_player, move));
+}
+
+// Return the list of valid moves on a board for a player
+static SCM scm_valid_moves(SCM scm_board, SCM player) {
+ 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));
+ }
+
+ enum player_color current_player = EMPTY;
+
+ if (scm_is_true(scm_eq_p(player, scm_from_utf8_symbol("white")))) {
+ current_player = WHITE;
+ } else if (scm_is_true(scm_eq_p(player, scm_from_utf8_symbol("black")))) {
+ current_player = BLACK;
+ }
+ current_player = BLACK;
+
+ SCM result = scm_make_list(scm_from_int(0), NULL);
+ for (int i = 0; i < 8; i++) {
+ for (int j = 0; j < 8; j++) {
+ struct move move = {i, j};
+ if (is_valid_move(board, current_player, move)) {
+ result = scm_cons(scm_cons(scm_from_int(i), scm_from_int(j)), result);
+ }
+ }
+ }
+
+ free_board(board);
+ return result;
+}
+
struct move get_scm_move(char *strategy_path) {
// Initialize move to an invalid move.
struct move move = {-1, -1};
scm_init_guile();
+
+ // Initialize primitives
scm_c_define_gsubr("get-board", 0, 0, 0, scm_get_board);
+ scm_c_define_gsubr("current-player", 0, 0, 0, scm_current_player);
+ scm_c_define_gsubr("valid-move?", 3, 0, 0, scm_is_valid_move);
+ scm_c_define_gsubr("valid-moves", 2, 0, 0, scm_valid_moves);
+ // Read the move from scheme
SCM scm_move = scm_c_primitive_load(strategy_path);
- move.row = scm_to_int(scm_car(scm_move));
- move.col = scm_to_int(scm_cdr(scm_move));
- return move;
+
+ return scm_move_to_c_move(scm_move);
}