1 /* $OpenBSD: pubeval.c,v 1.3 2015/11/30 08:19:25 tb Exp $ */
2 /* Public domain, Gerry Tesauro. */
3
4 /* Backgammon move-selection evaluation function for benchmark comparisons.
5 * Computes a linear evaluation function: Score = W * X, where X is an
6 * input vector encoding the board state (using a raw encoding of the number
7 * of men at each location), and W is a weight vector. Separate weight
8 * vectors are used for racing positions and contact positions. Makes lots
9 * of obvious mistakes, but provides a decent level of play for benchmarking
10 * purposes.
11 */
12
13 /* Provided as a public service to the backgammon programming community by
14 * Gerry Tesauro, IBM Research. (e-mail: tesauro@watson.ibm.com)
15 */
16
17 /* The following inputs are needed for this routine:
18 *
19 * race is an integer variable which should be set based on the INITIAL
20 * position BEFORE the move. Set race=1 if the position is a race (i.e. no
21 * contact) and 0 if the position is a contact position.
22 *
23 * pos[] is an integer array of dimension 28 which should represent a legal
24 * final board state after the move. Elements 1-24 correspond to board
25 * locations 1-24 from computer's point of view, i.e. computer's men move in
26 * the negative direction from 24 to 1, and opponent's men move in the
27 * positive direction from 1 to 24. Computer's men are represented by
28 * positive integers, and opponent's men are represented by negative
29 * integers. Element 25 represents computer's men on the bar (positive
30 * integer), and element 0 represents opponent's men on the bar (negative
31 * integer). Element 26 represents computer's men off the board (positive
32 * integer), and element 27 represents opponent's men off the board
33 * (negative integer).
34 */
35
36 #include "back.h"
37 #include "backlocal.h"
38
39 static float x[122];
40 static int pos[28];
41
42 static const float wc[122] = {
43 0.25696, -0.66937, -1.66135, -2.02487, -2.53398, -0.16092, -1.11725, -1.06654,
44 -0.92830, -1.99558, -1.10388, -0.80802, 0.09856, -0.62086, -1.27999, -0.59220,
45 -0.73667, 0.89032, -0.38933, -1.59847, -1.50197, -0.60966, 1.56166, -0.47389,
46 -1.80390, -0.83425, -0.97741, -1.41371, 0.24500, 0.10970, -1.36476, -1.05572,
47 1.15420, 0.11069, -0.38319, -0.74816, -0.59244, 0.81116, -0.39511, 0.11424,
48 -0.73169, -0.56074, 1.09792, 0.15977, 0.13786, -1.18435, -0.43363, 1.06169,
49 -0.21329, 0.04798, -0.94373, -0.22982, 1.22737, -0.13099, -0.06295, -0.75882,
50 -0.13658, 1.78389, 0.30416, 0.36797, -0.69851, 0.13003, 1.23070, 0.40868,
51 -0.21081, -0.64073, 0.31061, 1.59554, 0.65718, 0.25429, -0.80789, 0.08240,
52 1.78964, 0.54304, 0.41174, -1.06161, 0.07851, 2.01451, 0.49786, 0.91936,
53 -0.90750, 0.05941, 1.83120, 0.58722, 1.28777, -0.83711, -0.33248, 2.64983,
54 0.52698, 0.82132, -0.58897, -1.18223, 3.35809, 0.62017, 0.57353, -0.07276,
55 -0.36214, 4.37655, 0.45481, 0.21746, 0.10504, -0.61977, 3.54001, 0.04612,
56 -0.18108, 0.63211, -0.87046, 2.47673, -0.48016, -1.27157, 0.86505, -1.11342,
57 1.24612, -0.82385, -2.77082, 1.23606, -1.59529, 0.10438, -1.30206, -4.11520,
58 5.62596, -2.75800
59 };
60
61 static const float wr[122] = {
62 0.00000, -0.17160, 0.27010, 0.29906, -0.08471, 0.00000, -1.40375, -1.05121,
63 0.07217, -0.01351, 0.00000, -1.29506, -2.16183, 0.13246, -1.03508, 0.00000,
64 -2.29847, -2.34631, 0.17253, 0.08302, 0.00000, -1.27266, -2.87401, -0.07456,
65 -0.34240, 0.00000, -1.34640, -2.46556, -0.13022, -0.01591, 0.00000, 0.27448,
66 0.60015, 0.48302, 0.25236, 0.00000, 0.39521, 0.68178, 0.05281, 0.09266,
67 0.00000, 0.24855, -0.06844, -0.37646, 0.05685, 0.00000, 0.17405, 0.00430,
68 0.74427, 0.00576, 0.00000, 0.12392, 0.31202, -0.91035, -0.16270, 0.00000,
69 0.01418, -0.10839, -0.02781, -0.88035, 0.00000, 1.07274, 2.00366, 1.16242,
70 0.22520, 0.00000, 0.85631, 1.06349, 1.49549, 0.18966, 0.00000, 0.37183,
71 -0.50352, -0.14818, 0.12039, 0.00000, 0.13681, 0.13978, 1.11245, -0.12707,
72 0.00000, -0.22082, 0.20178, -0.06285, -0.52728, 0.00000, -0.13597, -0.19412,
73 -0.09308, -1.26062, 0.00000, 3.05454, 5.16874, 1.50680, 5.35000, 0.00000,
74 2.19605, 3.85390, 0.88296, 2.30052, 0.00000, 0.92321, 1.08744, -0.11696,
75 -0.78560, 0.00000, -0.09795, -0.83050, -1.09167, -4.94251, 0.00000, -1.00316,
76 -3.66465, -2.56906, -9.67677, 0.00000, -2.77982, -7.26713, -3.40177,-12.32252,
77 0.00000, 3.42040
78 };
79
80
81 float
pubeval(int race)82 pubeval(int race)
83 {
84 int i;
85 float score;
86
87 if (pos[26] == 15)
88 return (99999999.);
89 /* all men off, best possible move */
90
91 setx(); /* sets input array x[] */
92 score = 0.0;
93 if (race) { /* use race weights */
94 for (i = 0; i < 122; ++i)
95 score += wr[i] * x[i];
96 } else { /* use contact weights */
97 for (i = 0; i < 122; ++i)
98 score += wc[i] * x[i];
99 }
100 return (score);
101 }
102
103 /* sets input vector x[] given board position pos[] */
104 void
setx(void)105 setx(void)
106 {
107 int i, j, jm1, n;
108
109 /* initialize */
110 for (j = 0; j < 122; ++j)
111 x[j] = 0.0;
112 if (cturn > 0) { /* we are red, going from 1->24 */
113 for (i = 0; i < 26; i++)
114 pos[25 - i] = board[i];
115 } else { /* we are white, going from 24 -> 1 */
116 for (i = 0; i < 26; i++)
117 pos[i] = -board[i];
118 }
119 pos[26] = *offptr;
120 pos[27] = -(*offopp);
121
122 /* first encode board locations 24-1 */
123 for (j = 1; j <= 24; ++j) {
124 jm1 = j - 1;
125 n = pos[25 - j];
126 if (n != 0) {
127 if (n == -1)
128 x[5 * jm1 + 0] = 1.0;
129 else if (n == 1)
130 x[5 * jm1 + 1] = 1.0;
131 else if (n == 3)
132 x[5 * jm1 + 3] = 1.0;
133 if (n >= 4)
134 x[5 * jm1 + 4] = (float) (n - 3) / 2.0;
135 if (n >= 2)
136 x[5 * jm1 + 2] = 1.0;
137 }
138 }
139 /* encode opponent barmen */
140 x[120] = -(float) (pos[0]) / 2.0;
141 /* encode computer's menoff */
142 x[121] = (float) (pos[26]) / 15.0;
143 }
144