xref: /openbsd-src/games/backgammon/backgammon/pubeval.c (revision 87f25a4abf762f43d1a2045a585c035489c33d7d)
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