From d52e4a597cfa9215e84f547ee9eb5c15a5f55e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoffer=20M=C3=BCller=20Madsen?= Date: Wed, 14 Mar 2018 11:07:43 +0100 Subject: [PATCH] pubeval is now a C-extension to Python --- bot.py | 9 +--- pubeval.py | 82 ---------------------------------- pubeval/pubeval.c | 111 +++++++++++++++++++++++++++++----------------- pubeval/setup.py | 9 ++++ 4 files changed, 81 insertions(+), 130 deletions(-) delete mode 100644 pubeval.py create mode 100644 pubeval/setup.py diff --git a/bot.py b/bot.py index 5ab9614..b15c8dc 100644 --- a/bot.py +++ b/bot.py @@ -6,6 +6,7 @@ from board import Board import subprocess import random import sys +import pubeval class Bot: @@ -51,13 +52,7 @@ class Bot: # TODO: Test this, the score results should be deterministic def make_pubeval_move(self, board, sym, roll): legal_moves = Board.calculate_legal_states(tuple(board), sym, roll) - moves_and_scores = [] - for board in legal_moves: - call_argument = ["./pubeval/pubeval"] - for x in Board.board_features_to_pubeval(board, sym): - call_argument.append(str(x)) - data = subprocess.check_output(call_argument) - moves_and_scores.append([board, float(bytes.decode(data))]) + moves_and_scores = [(board, pubeval.eval(board)) for board in legal_moves] scores = [ x[1] for x in moves_and_scores ] best_move_pair = moves_and_scores[np.array(scores).argmax()] return best_move_pair diff --git a/pubeval.py b/pubeval.py deleted file mode 100644 index 124c36a..0000000 --- a/pubeval.py +++ /dev/null @@ -1,82 +0,0 @@ -class Pubeval: - - - def __init__(self): - self.x = [] - self.wc = [ - 0.25696, -0.66937, -1.66135, -2.02487, -2.53398, -0.16092, -1.11725, -1.06654, - -0.92830, -1.99558, -1.10388, -0.80802, 0.09856, -0.62086, -1.27999, -0.59220, - -0.73667, 0.89032, -0.38933, -1.59847, -1.50197, -0.60966, 1.56166, -0.47389, - -1.80390, -0.83425, -0.97741, -1.41371, 0.24500, 0.10970, -1.36476, -1.05572, - 1.15420, 0.11069, -0.38319, -0.74816, -0.59244, 0.81116, -0.39511, 0.11424, - -0.73169, -0.56074, 1.09792, 0.15977, 0.13786, -1.18435, -0.43363, 1.06169, - -0.21329, 0.04798, -0.94373, -0.22982, 1.22737, -0.13099, -0.06295, -0.75882, - -0.13658, 1.78389, 0.30416, 0.36797, -0.69851, 0.13003, 1.23070, 0.40868, - -0.21081, -0.64073, 0.31061, 1.59554, 0.65718, 0.25429, -0.80789, 0.08240, - 1.78964, 0.54304, 0.41174, -1.06161, 0.07851, 2.01451, 0.49786, 0.91936, - -0.90750, 0.05941, 1.83120, 0.58722, 1.28777, -0.83711, -0.33248, 2.64983, - 0.52698, 0.82132, -0.58897, -1.18223, 3.35809, 0.62017, 0.57353, -0.07276, - -0.36214, 4.37655, 0.45481, 0.21746, 0.10504, -0.61977, 3.54001, 0.04612, - -0.18108, 0.63211, -0.87046, 2.47673, -0.48016, -1.27157, 0.86505, -1.11342, - 1.24612, -0.82385, -2.77082, 1.23606, -1.59529, 0.10438, -1.30206, -4.11520, - 5.62596, -2.75800 - ] - - - self.wr = [ - 0.00000, -0.17160, 0.27010, 0.29906, -0.08471, 0.00000, -1.40375, -1.05121, - 0.07217, -0.01351, 0.00000, -1.29506, -2.16183, 0.13246, -1.03508, 0.00000, - -2.29847, -2.34631, 0.17253, 0.08302, 0.00000, -1.27266, -2.87401, -0.07456, - -0.34240, 0.00000, -1.34640, -2.46556, -0.13022, -0.01591, 0.00000, 0.27448, - 0.60015, 0.48302, 0.25236, 0.00000, 0.39521, 0.68178, 0.05281, 0.09266, - 0.00000, 0.24855, -0.06844, -0.37646, 0.05685, 0.00000, 0.17405, 0.00430, - 0.74427, 0.00576, 0.00000, 0.12392, 0.31202, -0.91035, -0.16270, 0.00000, - 0.01418, -0.10839, -0.02781, -0.88035, 0.00000, 1.07274, 2.00366, 1.16242, - 0.22520, 0.00000, 0.85631, 1.06349, 1.49549, 0.18966, 0.00000, 0.37183, - -0.50352, -0.14818, 0.12039, 0.00000, 0.13681, 0.13978, 1.11245, -0.12707, - 0.00000, -0.22082, 0.20178, -0.06285, -0.52728, 0.00000, -0.13597, -0.19412, - -0.09308, -1.26062, 0.00000, 3.05454, 5.16874, 1.50680, 5.35000, 0.00000, - 2.19605, 3.85390, 0.88296, 2.30052, 0.00000, 0.92321, 1.08744, -0.11696, - -0.78560, 0.00000, -0.09795, -0.83050, -1.09167, -4.94251, 0.00000, -1.00316, - -3.66465, -2.56906, -9.67677, 0.00000, -2.77982, -7.26713, -3.40177,-12.32252, - 0.00000, 3.42040 - ] - - def setx(self,pos): - - self.x = [0]*122 - - for j in range(1,25): - jm1 = j-1 - n = pos[25-j] - if n != 0: - if n == -1: - self.x[5*jm1+0] = 1.0 - if n == 1: - self.x[5*jm1+1] = 1.0 - if n >= 2: - self.x[5*jm1+2] = 1.0 - if n == 3: - self.x[5*jm1+3] = 1.0 - if n >= 4: - self.x[5*jm1+4] = (n-3)/2.0 - self.x[120] = -(pos[0]/2.0) - self.x[121] = (pos[26]/15.0) - - def pubeval(self, race, pos): - - if pos[26] == 15: - return 99999999.0 - - self.setx(pos) - - score = 0.0 - if race: - for i in range(122): - score = score + self.wr[i]*self.x[i] - else: - for i in range(122): - score = score + self.wc[i]*self.x[i] - return score - - diff --git a/pubeval/pubeval.c b/pubeval/pubeval.c index 62dfa65..26c3f8b 100644 --- a/pubeval/pubeval.c +++ b/pubeval/pubeval.c @@ -1,5 +1,4 @@ -#include -#include +#include static float x[122]; @@ -41,9 +40,33 @@ static const float wr[122] = { 0.00000, 3.42040 }; +void setx(int pos[]) +{ + /* sets input vector x[] given board position pos[] */ + extern float x[]; + int j, jm1, n; + /* initialize */ + for(j=0;j<122;++j) x[j] = 0.0; -float pubeval(race,pos) -int race,pos[]; + /* first encode board locations 24-1 */ + for(j=1;j<=24;++j) { + jm1 = j - 1; + n = pos[25-j]; + if(n!=0) { + if(n==-1) x[5*jm1+0] = 1.0; + if(n==1) x[5*jm1+1] = 1.0; + if(n>=2) x[5*jm1+2] = 1.0; + if(n==3) x[5*jm1+3] = 1.0; + if(n>=4) x[5*jm1+4] = (float)(n-3)/2.0; + } + } + /* encode opponent barmen */ + x[120] = -(float)(pos[0])/2.0; + /* encode computer's menoff */ + x[121] = (float)(pos[26])/15.0; +} + +float pubeval(int race, int pos[]) { /* Backgammon move-selection evaluation function for benchmark comparisons. Computes a linear @@ -101,45 +124,51 @@ int race,pos[]; return(score); } -setx(pos) -int pos[]; -{ - /* sets input vector x[] given board position pos[] */ - extern float x[]; - int j, jm1, n; - /* initialize */ - for(j=0;j<122;++j) x[j] = 0.0; - - /* first encode board locations 24-1 */ - for(j=1;j<=24;++j) { - jm1 = j - 1; - n = pos[25-j]; - if(n!=0) { - if(n==-1) x[5*jm1+0] = 1.0; - if(n==1) x[5*jm1+1] = 1.0; - if(n>=2) x[5*jm1+2] = 1.0; - if(n==3) x[5*jm1+3] = 1.0; - if(n>=4) x[5*jm1+4] = (float)(n-3)/2.0; - } - } - /* encode opponent barmen */ - x[120] = -(float)(pos[0])/2.0; - /* encode computer's menoff */ - x[121] = (float)(pos[26])/15.0; -} - -int main(int argc, char**argv) { - int test[28]; //= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - int i = 0; - char *ptr; +static PyObject* +pubeval_eval(PyObject *self, PyObject *args) { + long numValues; + int board[28]; + float eval_score; + PyObject* tuple_obj; + PyObject* val_obj; + PyObject* return_obj; + + if (! PyArg_ParseTuple(args, "O!", &PyTuple_Type, &tuple_obj)) + return NULL; - for (i=1; i