diff --git a/quack/quack.c b/quack/quack.c index b09e722..61e3e53 100644 --- a/quack/quack.c +++ b/quack/quack.c @@ -2,6 +2,12 @@ static PyObject* QuackError; +typedef struct board_list board_list; +struct board_list { + int size; + PyObject** list; +}; + /* Utility functions */ int sign(int x) { return (x > 0) - (x < 0); @@ -88,6 +94,8 @@ int can_bear_off(int board[], int player, int from_idx) { return 1; } + + /* end helper functions */ int is_move_valid(int board[], int player, int face_value, int move[]) { @@ -116,7 +124,127 @@ int is_move_valid(int board[], int player, int face_value, int move[]) { ; } +int* do_move(int board[], int player, int move[]) { + int from_idx = move[0]; + int to_idx = move[1]; + + /* "lift" checker */ + board[from_idx] -= player; + + /* Return early if bearing off */ + if (to_idx < 1 || to_idx > 24) return board; + + /* Hit opponent checker */ + if (board[to_idx] * player == -1) { + /* Move checker to bar */ + if (player == 1) board[25] -= player; + else board[0] -= player; + + board[to_idx] = 0; + } + + /* Put down checker */ + board[to_idx] += player; + + return board; +} + +int* do_move_clone(int board[], int player, int move[]) { + int new_board[26]; + for (int i = 0; i < 26; i++) { + new_board[i] = board[i]; + } + return do_move(new_board, player, move); +} + +void board_to_pyboard(PyObject* board_tuple, int board[]) { + for (int i = 0; i < 26; i++) { + PyTuple_SetItem(board_tuple, i, Py_BuildValue("i", board[i])); + } + return; +} + +board_list calc_moves(int board[], int player, int face_value) { + int* checker_idxs = idxs_with_checkers_of_player(board, player); + board_list boards = { .size = 0, + .list = malloc((15 + 1) * sizeof(PyObject*)) }; + if (boards.list == NULL) { + fprintf(stderr, "malloc failed\n"); + abort(); + } + + if (checker_idxs[0] == 0) { + boards.size = 1; + PyObject* board_tuple = PyTuple_New(26); + board_to_pyboard(board_tuple, board); + boards.list[0] = board_tuple; + return boards; + } + + int ctr = 0; + for (int i = 1; i <= checker_idxs[0]; i++) { + int move[2]; + move[0] = checker_idxs[i]; + move[1] = checker_idxs[i] + (face_value * player); + for (int i = 0; i < 2; i++) { + printf("move[%i]: %i\n", i, move[i]); + } + if (is_move_valid(board, player, face_value, move)) { + printf("legal\n"); + int* new_board = do_move_clone(board, player, move); + PyObject* board_tuple = PyTuple_New(26); + board_to_pyboard(board_tuple, new_board); + + // segfault maybe :'( + //free(new_board); + + boards.list[i] = board_tuple; + ctr++; + } + } + + boards.size = ctr; + printf("boards.size: %i\n\n",boards.size); + + + return boards; +} + /* Meta definitions */ +int extract_board(int *board, PyObject* board_tuple_obj) { + long numValuesBoard; + numValuesBoard = PyTuple_Size(board_tuple_obj); + if (numValuesBoard != 26) { + PyErr_SetString(QuackError, "Board tuple must have 26 entries"); + return 1; + } + + PyObject* board_val_obj; + // Iterate over tuple to retreive positions + for (int i=0; i