pubeval is now a C-extension to Python
This commit is contained in:
parent
153776d83e
commit
d52e4a597c
9
bot.py
9
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
|
||||
|
|
82
pubeval.py
82
pubeval.py
|
@ -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
|
||||
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <Python.h>
|
||||
|
||||
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[];
|
||||
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;
|
||||
|
||||
numValues = PyTuple_Size(tuple_obj);
|
||||
|
||||
if (numValues < 0) return NULL;
|
||||
|
||||
// Iterate over tuple to retreive positions
|
||||
for (int i=0; i<numValues; i++) {
|
||||
val_obj = PyTuple_GetItem(tuple_obj, i);
|
||||
board[i] = PyLong_AsLong(val_obj);
|
||||
}
|
||||
|
||||
eval_score = pubeval(0, board);
|
||||
return_obj = Py_BuildValue("f", eval_score);
|
||||
return return_obj;
|
||||
}
|
||||
|
||||
static PyMethodDef pubeval_methods[] = {
|
||||
{
|
||||
/* 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;
|
||||
"eval", pubeval_eval, METH_VARARGS,
|
||||
"Returns evaluation results for the given board position."
|
||||
},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
for (i=1; i<argc; i++) {
|
||||
// printf("%s\n", argv[i]);
|
||||
test[i-1] = (int) strtol(argv[i], &ptr, 10);
|
||||
}
|
||||
|
||||
printf("%f\n", pubeval(0, test));
|
||||
|
||||
return 0;
|
||||
static struct PyModuleDef pubeval_definition = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"pubeval",
|
||||
"A Python module that implements Gerald Tesauro's pubeval function for evaluation backgammon positions.",
|
||||
-1,
|
||||
pubeval_methods
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit_pubeval(void) {
|
||||
//Py_Initialize();
|
||||
return PyModule_Create(&pubeval_definition);
|
||||
}
|
||||
|
|
9
pubeval/setup.py
Normal file
9
pubeval/setup.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from distutils.core import setup, Extension
|
||||
|
||||
pubeval = Extension('pubeval',
|
||||
sources = ['pubeval.c'])
|
||||
|
||||
setup (name = 'pubeval',
|
||||
version = '0.1',
|
||||
description = 'Pubeval for Python',
|
||||
ext_modules = [pubeval])
|
Loading…
Reference in New Issue
Block a user