From 383dd7aa4b8cbfda861a7532bd7b3c0df85b3137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoffer=20M=C3=BCller=20Madsen?= Date: Fri, 11 May 2018 20:13:43 +0200 Subject: [PATCH] code works again; quack gave ~3 times improvement for calc_moves --- board.py | 19 ------------ quack/quack.c | 81 ++++++++++++++++++++++----------------------------- 2 files changed, 35 insertions(+), 65 deletions(-) diff --git a/board.py b/board.py index 6e9aeb1..0f403ed 100644 --- a/board.py +++ b/board.py @@ -187,25 +187,6 @@ class Board: def calc_moves(board, face_value): return quack.calc_moves(board, player, face_value) - idxs_with_checkers = Board.idxs_with_checkers_of_player(board, player) - if len(idxs_with_checkers) == 0: - return [board] - boards = [(Board.do_move(board, - player, - (idx, idx + (face_value * player))) - if Board.is_move_valid(board, - player, - face_value, - (idx, idx + (face_value * player))) - else None) - for idx in idxs_with_checkers] - # print("pls:",boards) - board_list = list(filter(None, boards)) # Remove None-values - # if len(board_list) == 0: - # return [board] - # print("board list:", board_list) - return board_list - # Problem with cal_moves: Method can return empty list (should always contain at least same board). # *Update*: Seems to be fixed. diff --git a/quack/quack.c b/quack/quack.c index 61e3e53..8292f39 100644 --- a/quack/quack.c +++ b/quack/quack.c @@ -5,7 +5,7 @@ static PyObject* QuackError; typedef struct board_list board_list; struct board_list { int size; - PyObject** list; + PyObject* list[16]; }; /* Utility functions */ @@ -14,11 +14,8 @@ int sign(int x) { } int abs(int x) { - if (x >= 0) { - return x; - } else { - return -x; - } + if (x >= 0) return x; + else return -x; } /* end utility functions */ @@ -124,7 +121,7 @@ int is_move_valid(int board[], int player, int face_value, int move[]) { ; } -int* do_move(int board[], int player, int move[]) { +void do_move(int board[], int player, int move[]) { int from_idx = move[0]; int to_idx = move[1]; @@ -132,7 +129,7 @@ int* do_move(int board[], int player, int move[]) { board[from_idx] -= player; /* Return early if bearing off */ - if (to_idx < 1 || to_idx > 24) return board; + if (to_idx < 1 || to_idx > 24) return; /* Hit opponent checker */ if (board[to_idx] * player == -1) { @@ -146,37 +143,39 @@ int* do_move(int board[], int player, int move[]) { /* 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) { +int* do_move_clone(int board[], int player, int move[]) { + int* new_board = malloc(sizeof(int) * 26); + if (new_board == NULL) { fprintf(stderr, "malloc failed\n"); abort(); } + for (int i = 0; i < 26; i++) { + new_board[i] = board[i]; + } + + do_move(new_board, player, move); + return new_board; +} + +PyObject* store_board_to_pyobject(int board[]) { + PyObject* board_tuple = PyTuple_New(26); + for (int i = 0; i < 26; i++) { + PyTuple_SetItem(board_tuple, i, Py_BuildValue("i", board[i])); + } + return board_tuple; +} + +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 }; + if (checker_idxs[0] == 0) { boards.size = 1; - PyObject* board_tuple = PyTuple_New(26); - board_to_pyboard(board_tuple, board); + PyObject* board_tuple = store_board_to_pyobject(board); boards.list[0] = board_tuple; return boards; } @@ -186,27 +185,20 @@ board_list calc_moves(int board[], int player, int face_value) { 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); + PyObject* board_tuple = store_board_to_pyobject(new_board); // segfault maybe :'( - //free(new_board); + free(new_board); - boards.list[i] = board_tuple; + boards.list[ctr] = board_tuple; ctr++; } } boards.size = ctr; - printf("boards.size: %i\n\n",boards.size); - - return boards; } @@ -319,8 +311,7 @@ quack_do_move(PyObject *self, PyObject *args) { do_move(board, player, move); - PyObject* board_tuple = PyTuple_New(26); - board_to_pyboard(board_tuple, board); + PyObject* board_tuple = store_board_to_pyobject(board); return Py_BuildValue("O", board_tuple); } @@ -345,13 +336,11 @@ quack_calc_moves(PyObject *self, PyObject *args) { PyObject* boards_list = PyList_New(0); for (int i = 0; i < boards.size; i++) { - printf("%i\n",i); if (PyList_Append(boards_list, boards.list[i])) { printf("list insertion failed at index %i\n",i); + abort(); } - //free(boards.list[i]); } - //free(boards.list); return Py_BuildValue("O", boards_list); }