From c5c54396bdf8ef14c17a0bc5b8f0fda74aa958cf Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Tue, 18 Jan 2022 22:37:04 -0500 Subject: * Made print_board accept a board to print. * free_board should not return anything. * is_valid_move and has_valid_moves accept a board. * Implemented primitives for Scheme strategies to get the current player, and to get the board, and the validity of a move. * Removed game logic from is_valid_move. Instead simply apply the move to a temp board, and see if the move worked. * Created a very simple strategy for testing these primitives. It only hardcodes the first move, and then fails since that move is no longer valid. --- src/move.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 8 deletions(-) (limited to 'src/move.c') 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); } -- cgit v1.2.3