1 /*
2     Sjeng - a chess variants playing program
3     Copyright (C) 2000 Gian-Carlo Pascutto
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19     File: eval.c
20     Purpose: evaluate crazyhouse/bughouse positions
21 
22 */
23 
24 #include "sjeng.h"
25 #include "extvars.h"
26 #include "protos.h"
27 #include "squares.h"
28 
29 int Material;
30 int std_material[] = { 0, 100, -100, 310, -310, 4000, -4000, 500, -500, 900, -900, 325, -325, 0 };
31 
32 int zh_material[] = { 0, 100, -100, 210, -210, 4000, -4000, 250, -250, 450, -450, 230, -230, 0 };
33 
34 int suicide_material[] = { 0, 15, -15, 150, -150, 500, -500, 150, -150, 50, -50, 0, 0, 0 };
35 
36 int losers_material[] = { 0, 80, -80, 320, -320, 1000, -1000, 350, -350, 400, -400, 270, -270, 0 };
37 
38 int material[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
39 
40 const int file[144] =
41 {
42   0,0,0,0,0,0,0,0,0,0,0,0,
43   0,0,0,0,0,0,0,0,0,0,0,0,
44   0,0,1,2,3,4,5,6,7,8,0,0,
45   0,0,1,2,3,4,5,6,7,8,0,0,
46   0,0,1,2,3,4,5,6,7,8,0,0,
47   0,0,1,2,3,4,5,6,7,8,0,0,
48   0,0,1,2,3,4,5,6,7,8,0,0,
49   0,0,1,2,3,4,5,6,7,8,0,0,
50   0,0,1,2,3,4,5,6,7,8,0,0,
51   0,0,1,2,3,4,5,6,7,8,0,0,
52   0,0,0,0,0,0,0,0,0,0,0,0,
53   0,0,0,0,0,0,0,0,0,0,0,0
54 };
55 
56 const int rank[144] =
57 {
58   0,0,0,0,0,0,0,0,0,0,0,0,
59   0,0,0,0,0,0,0,0,0,0,0,0,
60   0,0,1,1,1,1,1,1,1,1,0,0,
61   0,0,2,2,2,2,2,2,2,2,0,0,
62   0,0,3,3,3,3,3,3,3,3,0,0,
63   0,0,4,4,4,4,4,4,4,4,0,0,
64   0,0,5,5,5,5,5,5,5,5,0,0,
65   0,0,6,6,6,6,6,6,6,6,0,0,
66   0,0,7,7,7,7,7,7,7,7,0,0,
67   0,0,8,8,8,8,8,8,8,8,0,0,
68   0,0,0,0,0,0,0,0,0,0,0,0,
69   0,0,0,0,0,0,0,0,0,0,0,0
70 };
71 
72 const int diagl[144] =
73 {
74   0,0,0,0,0,0,0,0,0,0,0,0,
75   0,0,0,0,0,0,0,0,0,0,0,0,
76   0,0, 1, 2, 3, 4, 5, 6, 7, 8,0,0,
77   0,0, 9, 1, 2, 3, 4, 5, 6, 7,0,0,
78   0,0,10, 9, 1, 2, 3, 4, 5, 6,0,0,
79   0,0,11,10, 9, 1, 2, 3, 4, 5,0,0,
80   0,0,12,11,10, 9, 1, 2, 3, 4,0,0,
81   0,0,13,12,11,10, 9, 1, 2, 3,0,0,
82   0,0,14,13,12,11,10, 9, 1, 2,0,0,
83   0,0,15,14,13,12,11,10, 9, 1,0,0,
84   0,0,0,0,0,0,0,0,0,0,0,0,
85   0,0,0,0,0,0,0,0,0,0,0,0
86 };
87 
88 const int diagr[144] =
89 {
90   0,0,0,0,0,0,0,0,0,0,0,0,
91   0,0,0,0,0,0,0,0,0,0,0,0,
92   0,0,15,14,13,12,11,10,9,1,0,0,
93   0,0,14,13,12,11,10,9,1,2,0,0,
94   0,0,13,12,11,10,9,1,2,3,0,0,
95   0,0,12,11,10,9,1,2,3,4,0,0,
96   0,0,11,10,9,1,2,3,4,5,0,0,
97   0,0,10,9,1,2,3,4,5,6,0,0,
98   0,0,9,1,2,3,4,5,6,7,0,0,
99   0,0,1,2,3,4,5,6,7,8,0,0,
100   0,0,0,0,0,0,0,0,0,0,0,0,
101   0,0,0,0,0,0,0,0,0,0,0,0
102 };
103 
104 const int sqcolor[144] =
105 {
106   0,0,0,0,0,0,0,0,0,0,0,0,
107   0,0,0,0,0,0,0,0,0,0,0,0,
108   0,0,1,0,1,0,1,0,1,0,0,0,
109   0,0,0,1,0,1,0,1,0,1,0,0,
110   0,0,1,0,1,0,1,0,1,0,0,0,
111   0,0,0,1,0,1,0,1,0,1,0,0,
112   0,0,1,0,1,0,1,0,1,0,0,0,
113   0,0,0,1,0,1,0,1,0,1,0,0,
114   0,0,1,0,1,0,1,0,1,0,0,0,
115   0,0,0,1,0,1,0,1,0,1,0,0,
116   0,0,0,0,0,0,0,0,0,0,0,0,
117   0,0,0,0,0,0,0,0,0,0,0,0
118 };
119 
120 /* these tables will be used for positional bonuses: */
121 
122 const int bishop[144] = {
123 0,0,0,0,0,0,0,0,0,0,0,0,
124 0,0,0,0,0,0,0,0,0,0,0,0,
125 0,0,-5,-5,-10,-5,-5,-10,-5,-5,0,0,
126 0,0,-5,10,5,10,10,5,10,-5,0,0,
127 0,0,-5,5,6,15,15,6,5,-5,0,0,
128 0,0,-5,3,15,10,10,15,3,-5,0,0,
129 0,0,-5,3,15,10,10,15,3,-5,0,0,
130 0,0,-5,5,6,15,15,6,5,-5,0,0,
131 0,0,-5,10,5,10,10,5,10,-5,0,0,
132 0,0,-5,-5,-10,-5,-5,-10,-5,-5,0,0,
133 0,0,0,0,0,0,0,0,0,0,0,0,
134 0,0,0,0,0,0,0,0,0,0,0,0};
135 
136 const int black_knight[144] = {
137 0,0,0,0,0,0,0,0,0,0,0,0,
138 0,0,0,0,0,0,0,0,0,0,0,0,
139 0,0,-20,-10,-10,-10,-10, -10,-10,-20,0,0,
140 0,0,-10, 15, 25, 25, 25,  25, 15,-10,0,0,
141 0,0,-10, 15, 25, 35, 35 , 35, 15,-10,0,0,
142 0,0,-10, 10, 25, 20, 25,  25, 10,-10,0,0,
143 0,0,-10, 0,  20, 20, 20,  20,  0,-10,0,0,
144 0,0,-10, 0,  15, 15, 15,  15,  0,-10,0,0,
145 0,0,-10, 0,   0,  3,  3,   0,  0,-10,0,0,
146 0,0,-20,-35,-10,-10,-10, -10,-35,-20,0,0,
147 0,0,0,0,0,0,0,0,0,0,0,0,
148 0,0,0,0,0,0,0,0,0,0,0,0};
149 
150 const int white_knight[144] = {
151 0,0,0,0,0,0,0,0,0,0,0,0,
152 0,0,0,0,0,0,0,0,0,0,0,0,
153 0,0,-20, -35,-10, -10, -10,-10, -35, -20,0,0,
154 0,0,-10,   0,  0,   3,   3,  0,   0, -10,0,0,
155 0,0,-10,   0, 15,  15,  15, 15,   0, -10,0,0,
156 0,0,-10,   0, 20,  20,  20, 20,   0, -10,0,0,
157 0,0,-10,  10, 25,  20,  25, 25,  10, -10,0,0,
158 0,0,-10,  15, 25,  35,  35, 35,  15, -10,0,0,
159 0,0,-10,  15, 25,  25,  25, 25,  15, -10,0,0,
160 0,0,-20, -10,-10, -10, -10,-10, -10, -20,0,0,
161 0,0,0,0,0,0,0,0,0,0,0,0,
162 0,0,0,0,0,0,0,0,0,0,0,0};
163 
164 const int white_pawn[144] =
165 {
166   0,0,0,0,0,0,0,0,0,0,0,0,
167   0,0,0,0,0,0,0,0,0,0,0,0,
168   0,0,0,0,0,0,0,0,0,0,0,0,
169   0,0,25, 25, 35,  5,  5, 50, 45, 30,0,0,
170   0,0, 0,  0,  0,  7,  7,  5,  5,  0,0,0,
171   0,0, 0,  0,  0, 14, 14,  0,  0,  0,0,0,
172   0,0, 0,  0, 10, 20, 20, 10,  5,  5,0,0,
173   0,0,12, 18, 18, 27, 27, 18, 18, 18,0,0,
174   0,0,25, 30, 30, 35, 35, 35, 30, 25,0,0,
175   0,0,0,0,0,0,0,0,0,0,0,0,
176   0,0,0,0,0,0,0,0,0,0,0,0,
177   0,0,0,0,0,0,0,0,0,0,0,0
178 };
179 
180 const int black_pawn[144] =
181 {
182   0,0,0,0,0,0,0,0,0,0,0,0,
183   0,0,0,0,0,0,0,0,0,0,0,0,
184   0,0,0,0,0,0,0,0,0,0,0,0,
185   0,0,30, 30, 30, 35, 35, 35, 30, 25,0,0,
186   0,0,12, 18, 18, 27, 27, 18, 18, 18,0,0,
187   0,0, 0,  0, 10, 20, 20, 10,  5,  5,0,0,
188   0,0, 0,  0,  0, 14, 14,  0,  0,  0,0,0,
189   0,0, 0,  0,  0,  7,  7,  5,  5,  0,0,0,
190   0,0,25, 25, 35,  5,  5, 50, 45, 30,0,0,
191   0,0,0,0,0,0,0,0,0,0,0,0,
192   0,0,0,0,0,0,0,0,0,0,0,0,
193   0,0,0,0,0,0,0,0,0,0,0,0
194 };
195 
196 /* to be used during opening and middlegame for white king positioning: */
197 const int white_king[144] = {
198 0,0,0,0,0,0,0,0,0,0,0,0,
199 0,0,0,0,0,0,0,0,0,0,0,0,
200 0,0,-100,   7,   4,  0,  10  , 4,   7,-100,0,0,
201 0,0,-250,-200,-150,-100,-100,-150,-200,-250,0,0,
202 0,0,-350,-300,-300,-250,-250,-300,-300,-350,0,0,
203 0,0,-400,-400,-400,-350,-350,-400,-400,-400,0,0,
204 0,0,-450,-450,-450,-450,-450,-450,-450,-450,0,0,
205 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
206 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
207 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
208 0,0,0,0,0,0,0,0,0,0,0,0,
209 0,0,0,0,0,0,0,0,0,0,0,0};
210 
211 /* to be used during opening and middlegame for black king positioning: */
212 const int black_king[144] = {
213 0,0,0,0,0,0,0,0,0,0,0,0,
214 0,0,0,0,0,0,0,0,0,0,0,0,
215 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
216 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
217 0,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
218 0,0,-450,-450,-450,-450,-450,-450,-450,-450,0,0,
219 0,0,-400,-400,-400,-350,-350,-400,-400,-400,0,0,
220 0,0,-350,-300,-300,-250,-250,-300,-300,-350,0,0,
221 0,0,-250,-200,-150,-100,-100,-150,-200,-250,0,0,
222 0,0,-100,   7,   4,   0,  10  , 4,   7,-100,0,0,
223 0,0,0,0,0,0,0,0,0,0,0,0,
224 0,0,0,0,0,0,0,0,0,0,0,0};
225 
226 const int black_queen[144] = {
227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 0, 0, 5, 5, 5,10,10, 5, 5, 5, 0, 0,
230 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0,
231 0, 0,-30,-30,-30,-30,-30,-30,-30,-30,0, 0,
232 0,0,-60,-40,-40,-60,-60,-40,-40,-60,0,0,
233 0,0,-40,-40,-40,-40,-40,-40,-40,-40,0,0,
234 0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0,
235 0,0,0,0,0,7,10,5,0,0,0,0,
236 0,0,0,0,0, 5,0,0,0,0,0,0,
237 0,0,0,0,0,0,0,0,0,0,0,0,
238 0,0,0,0,0,0,0,0,0,0,0,0};
239 
240 
241 const int white_queen[144] = {
242 0,0,0,0,0,0,0,0,0,0,0,0,
243 0,0,0,0,0,0,0,0,0,0,0,0,
244 0,0,0,0,0,5,0,0,0,0,0,0,
245 0,0,0,0,0,7,10,5,0,0,0,0,
246 0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0,
247 0,0,-40,-40,-40,-40,-40,-40,-40,-40,0,0,
248 0,0,-60,-40,-40,-60,-60,-40,-40,-60,0,0,
249 0, 0,-30,-30,-30,-30,-30,-30,-30,-30,0, 0,
250 0, 0, 0, 0, 3, 3, 3,3,3, 0, 0, 0,
251 0, 0, 5, 5, 5,10,10,5,5,5, 0, 0,
252 0,0,0,0,0,0,0,0,0,0,0,0,
253 0,0,0,0,0,0,0,0,0,0,0,0};
254 
255 const int black_rook[144] =
256 {
257   0,0,  0,  0,  0,  0,  0,  0,  0,  0,0,0,
258   0,0,  0,  0,  0,  0,  0,  0,  0,  0,0,0,
259   0,0, 10, 15, 20, 25, 25, 20, 15, 10,0,0,
260   0,0,  0, 10, 15, 20, 20, 15, 10,  0,0,0,
261   0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0,
262   0,0,-20,-20,-20,-30,-30,-20,-20,-20,0,0,
263   0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0,
264   0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0,
265   0,0,  0,  0,  0,  7, 10,  0,  0,  0,0,0,
266   0,0,  2,  2,  2,  2,  2,  2,  2,  2,0,0,
267   0,0,0,0,0,0,0,0,0,0,0,0,
268   0,0,0,0,0,0,0,0,0,0,0,0
269 };
270 
271 const int white_rook[144] =
272 {
273     0,0,0,0,0,0,0,0,0,0,0,0,
274     0,0,0,0,0,0,0,0,0,0,0,0,
275     0,0,  2,  2,  2,  2,  2,  2,  2,  2,0,0,
276     0,0,  0,  0,  0,  7, 10,  0,  0,  0,0,0,
277     0,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0,
278     0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0,
279     0,0,-20,-20,-20,-30,-30,-20,-20,-20,0,0,
280     0,0,-20,-20,-20,-20,-20,-20,-20,-20,0,0,
281     0,0,  0, 10, 15, 20, 20, 15, 10,  0,0,0,
282     0,0, 10, 15, 20, 25, 25, 20, 15, 10,0,0,
283     0,0,0,0,0,0,0,0,0,0,0,0,
284     0,0,0,0,0,0,0,0,0,0,0,0
285 };
286 
287 /* tropism values of 0 and 8 are bogus,
288    and should never happen in the actual eval */
289 
290 int pre_p_tropism[9] =
291 { 9999, 40, 20, 10, 3, 1, 1, 0, 9999};
292 
293 int pre_r_tropism[9] =
294 { 9999, 50, 40, 15, 5, 1, 1, 0, 9999};
295 
296 int pre_n_tropism[9] =
297 { 9999, 50, 70, 35, 10, 2, 1, 0, 9999};
298 
299 int pre_q_tropism[9] =
300 { 9999, 100, 60, 20, 5, 2, 0, 0, 9999};
301 
302 int pre_b_tropism[9] =
303 { 9999, 50, 25, 15, 5, 2, 2, 2, 9999};
304 
305 unsigned char p_tropism[144][144];
306 unsigned char q_tropism[144][144];
307 unsigned char n_tropism[144][144];
308 unsigned char r_tropism[144][144];
309 unsigned char b_tropism[144][144];
310 
311 int ksafety_scaled[15][9] =
312 {
313   {  -5,   5,  10,  15,  50,  80, 150, 150, 150 },   /* nothing */
314   {  -5,  15,  20,  25,  70, 150, 200, 200, 200 },   /* 1 pawns */
315   {  -5,  15,  30,  30, 100, 200, 300, 300, 300 },   /* 2 pawns */
316   { -10,  20,  40,  40, 100, 200, 300, 300, 400 },   /* 1 minor piece */
317   { -10,  30,  50,  80, 150, 300, 400, 400, 500 },   /* 1 minor piece + pawn */
318   { -10,  35,  60, 100, 200, 250, 400, 400, 500 },   /* queen */
319   { -10,  40,  70, 110, 210, 300, 500, 500, 600 },   /* queen + pawn */
320   { -10,  45,  75, 125, 215, 300, 500, 600, 700 },   /* queen + 2 pawn */
321   { -10,  60,  90, 130, 240, 350, 500, 600, 700 },   /* queen + piece */
322   { -15,  60,  95, 145, 260, 350, 500, 600, 700 },   /* queen + piece + pawn */
323   { -15,  60, 100, 150, 270, 350, 500, 600, 700 },   /* 2 queen */
324   { -15,  60, 110, 160, 280, 400, 600, 700, 800 },
325   { -20,  70, 115, 165, 290, 400, 600, 700, 800 },
326   { -20,  80, 120, 170, 300, 450, 700, 800, 900 },
327   { -20,  80, 125, 175, 310, 450, 700, 800, 900 }
328 };
329 
initialize_eval(void)330 void initialize_eval(void)
331 {
332   int i, j;
333 
334   if (havercfile)
335   {
336    for (i = 0; i < 15; i++)
337    {
338      for(j = 0; j < 9; j++)
339      {
340        ksafety_scaled[i][j] = (int)((float)cfg_ksafety[i][j] * (float)cfg_scalefac);
341      }
342    }
343    for(i = 1; i < 8; i++)
344    {
345      pre_p_tropism[i] = (int)((float)cfg_tropism[0][i-1] * (float)cfg_scalefac);
346      pre_b_tropism[i] = (int)((float)cfg_tropism[1][i-1] * (float)cfg_scalefac);
347      pre_n_tropism[i] = (int)((float)cfg_tropism[2][i-1] * (float)cfg_scalefac);
348      pre_r_tropism[i] = (int)((float)cfg_tropism[3][i-1] * (float)cfg_scalefac);
349      pre_q_tropism[i] = (int)((float)cfg_tropism[4][i-1] * (float)cfg_scalefac);
350    }
351   }
352 
353   for(i = 0; i < 144; i++)
354     {
355       for(j = 0; j < 144; j++)
356 	{
357 	  p_tropism[i][j] =
358 	    pre_p_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))];
359 	  b_tropism[i][j] =
360 	    pre_b_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))];
361 	  n_tropism[i][j] =
362 	    pre_n_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))];
363 	  r_tropism[i][j] =
364 	    pre_r_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))];
365 	  q_tropism[i][j] =
366 	    pre_q_tropism[max(abs(rank(i) - rank(j)), abs(file(i) - file(j)))];
367 	}
368     }
369 }
370 
eval(void)371 long int eval (void) {
372 
373   /* return a score for the current middlegame position: */
374 
375   int i, a, j;
376   long int score = 0;
377   int in_cache;
378   int safety, badsquares;
379   int norm_white_hand_eval, norm_black_hand_eval;
380   int wdev_dscale, bdev_dscale;
381 
382   if (Variant == Normal)
383     {
384       return std_eval();
385     }
386   else if (Variant == Suicide)
387     {
388       return suicide_eval();
389     }
390   else if (Variant == Losers)
391     {
392       return losers_eval();
393     }
394 
395   in_cache = 0;
396 
397   checkECache(&score, &in_cache);
398 
399   if(in_cache)
400     {
401       if (white_to_move == 1) return score;
402       return -score;
403     }
404 
405   /* set up development scalefactor depending on material
406    * in hand */
407   if (cfg_devscale)
408     {
409       /* computer plays black -> no white downscaling */
410       if (white_to_move != comp_color)
411 	{
412 	  if (white_hand_eval <= 200 && (Variant != Bughouse))
413 	    {
414 	      /* 2 pawns or less */
415 	      wdev_dscale = 2;
416 	    }
417 	  else if (white_hand_eval >= 700)
418 	    {
419 	      /* queen + minor, three minors or more */
420 	      wdev_dscale = 0;
421 	    }
422 	  else
423 	    {
424 	      wdev_dscale = 1;
425 	    }
426 	}
427       else
428 	wdev_dscale = 0;
429 
430       if (white_to_move == comp_color)
431 	{
432 	  if ((-black_hand_eval) <= 200 && (Variant != Bughouse))
433 	    {
434 	      /* 2 pawns or less */
435 	      bdev_dscale = 2;
436 	}
437 	  else if ((-black_hand_eval) >= 700)
438 	    {
439 	      /* queen + pawn, two minors + pawn */
440 	      bdev_dscale = 0;
441 	    }
442 	  else
443 	    {
444 	      bdev_dscale = 1;
445 	    }
446 	}
447       else
448 	bdev_dscale = 0;
449     }
450   else
451     {
452       wdev_dscale = bdev_dscale = 0;
453     }
454 
455   /* loop through the board, adding material value, as well as positional
456      bonuses for all pieces encountered: */
457   for (a = 1, j = 1;(a <= piece_count); j++) {
458     i = pieces[j];
459 
460     if (!i)
461       continue;
462     else
463       a++;
464 
465     switch (board[i]) {
466       case (wpawn):
467 	score += 100;
468 	score += white_pawn[i] >> wdev_dscale;
469 	score += p_tropism[i][bking_loc];
470 	break;
471 
472       case (bpawn):
473 	score -= 100;
474 	score -= black_pawn[i] >> bdev_dscale;
475 	score -= p_tropism[i][wking_loc];
476 	break;
477 
478       case (wrook):
479 	score += 250;
480 	score += white_rook[i] >> wdev_dscale;
481 	score += r_tropism[i][bking_loc];
482 	break;
483 
484       case (brook):
485 	score -= 250;
486 	score -= black_rook[i] >> bdev_dscale;
487 	score -= r_tropism[i][wking_loc];
488 	break;
489 
490       case (wbishop):
491 	score += 230;
492 	score += bishop[i] >> wdev_dscale;
493 	score += b_tropism[i][bking_loc];
494 	break;
495 
496       case (bbishop):
497 	score -= 230;
498 	score -= bishop[i] >> bdev_dscale;
499 	score -= b_tropism[i][wking_loc];
500 	break;
501 
502       case (wknight):
503 	score += 210;
504 	score += white_knight[i] >> wdev_dscale;
505 	score += n_tropism[i][bking_loc];
506 	break;
507 
508       case (bknight):
509 	score -= 210;
510 	score -= black_knight[i] >> bdev_dscale;
511 	score -= n_tropism[i][wking_loc];
512 	break;
513 
514       case (wqueen):
515 	score += 450;
516 	score += white_queen[i] >> wdev_dscale;
517 	score += q_tropism[i][bking_loc];
518 	break;
519 
520       case (bqueen):
521 	score -= 450;
522 	score -= black_queen[i] >> bdev_dscale;
523 	score -= q_tropism[i][wking_loc];
524 	break;
525 
526     }
527   }
528 
529   /* we scale our kings position depending on how
530      much material the _other_ side has in hand */
531 
532   score += white_king[wking_loc] >> bdev_dscale;
533   score -= black_king[bking_loc] >> wdev_dscale;
534 
535   /* we do not give a bonus for castling, but it is important
536      to keep our options open */
537 
538   if (!white_castled && moved[30])
539   {
540       score -= 30;
541   }
542   if (!black_castled && moved[114])
543   {
544       score += 30;
545   }
546 
547   /* give penalties for blocking the e/d pawns: */
548   if (!moved[41] && board[53] != npiece)
549     score -= 15;
550   if (!moved[42] && board[54] != npiece)
551     score -= 15;
552   if (!moved[101] && board[89] != npiece)
553     score += 15;
554   if (!moved[102] && board[90] != npiece)
555     score += 15;
556 
557 
558   if (cfg_smarteval)
559   {
560   /* Pawn cover for the King please... */
561   /* White */
562 
563   if (wking_loc != E1 && wking_loc != D1)
564   {
565   	if (board[wking_loc+11] != wpawn) score -= 24;
566   	if (board[wking_loc+12] != wpawn) score -= 35;
567   	if (board[wking_loc+13] != wpawn) score -= 24;
568 
569 	/* When castled, building a fortress wont hurt */
570 	if (white_castled)
571 	  {
572 	    if (board[bking_loc-25] == bpawn) score += 11;
573 	    if (board[bking_loc-24] == bpawn) score += 15;
574 	    if (board[bking_loc-23] == bpawn) score += 11;
575 	  }
576   }
577   /* Black */
578   if (bking_loc != E8 && bking_loc != D8)
579   {
580   	if (board[bking_loc-13] != bpawn) score += 24;
581   	if (board[bking_loc-12] != bpawn) score += 35;
582   	if (board[bking_loc-11] != bpawn) score += 24;
583 
584 	/* When castled, building a fortress wont hurt */
585 	if (black_castled)
586 	  {
587 	    if (board[bking_loc-25] == bpawn) score -= 11;
588 	    if (board[bking_loc-24] == bpawn) score -= 15;
589 	    if (board[bking_loc-23] == bpawn) score -= 11;
590 	  }
591   }
592   /* Develop stuff */
593   if (moved[E2])
594     {
595       score += 30;
596       if (moved[D2]) score += 25;
597       if (moved[G1]) score += 20;
598       if (moved[B1]) score += 15;
599       if (moved[C1]) score += 10;
600     }
601   if (moved[E7])
602     {
603       score -= 30;
604       if (moved[D7]) score -= 25;
605       if (moved[G8]) score -= 20;
606       if (moved[B8]) score -= 15;
607       if (moved[C8]) score -= 10;
608 
609     }
610 
611   /* Bad holes in the kingside (g2/e2) or (g7/e7) allow attacks */
612 
613   if ((board[G2] != wpawn) && (board[F3] == bpawn || board[E4] == bpawn))
614       score -= 30;
615   if ((board[G7] != bpawn) && (board[F6] == wpawn || board[E5] == wpawn))
616       score += 30;
617 
618 #define Fis_attacked(x,y) (board[(x)] == frame ? 0 : is_attacked((x),(y)))
619 #define Gis_attacked(x,y) (board[(x)] == frame ? 0 : nk_attacked((x),(y)))
620 
621   /* An enemy pawn in front of the king can be deadly.*/
622   /* especially if it is protected                    */
623 
624   if (board[wking_loc + 12] == bpawn || board[wking_loc + 12] == bbishop)
625     {
626       score -= 35;
627       if (Fis_attacked(wking_loc + 12, 0))
628 	score -= 150 >> bdev_dscale;
629     }
630   if (board[bking_loc - 12] == wpawn || board[bking_loc - 12] == wbishop)
631     {
632       score += 35;
633       if (Fis_attacked(bking_loc - 12,1))
634 	score += 150 >> wdev_dscale;
635     }
636 
637   /* If e6 is attacked but there is no pawn there (just P-f7) */
638 
639   /* I rely on CSE to remove the extra square checks and avoid the
640    * is_attacked call */
641 
642   if (((board[F2] == wpawn) || (board[E3] == wpawn) || board[E3] == bpawn) && Fis_attacked(E3,0))
643     {
644       if (board[F2] == wpawn) score += 10;
645       if (board[E3] == wpawn) score += 20;
646       else if (board[E3] == bpawn) score -= 15;
647     }
648   if (((board[F7] == bpawn) || (board[E6] == bpawn) || board[E6] == wpawn) && Fis_attacked(E6,1))
649     {
650       if (board[F7] == bpawn) score -= 10;
651       if (board[E6] == bpawn) score -= 20;
652       else if (board[E6] == wpawn) score += 15;
653     }
654 
655   /* Bonus if in check */
656 
657   if (Fis_attacked(bking_loc,1))
658     score += 50 >> wdev_dscale;
659   else if (Fis_attacked(wking_loc,0))
660     score -= 50 >> bdev_dscale;
661 
662   /* Give big pentalty for knight or pawn at g2/g7 especially if supported */
663   /* Also  protect  with  Rook  and  Bishop                                */
664 
665   if (board[G2] == bknight)
666     {
667       score -= 20;
668       if (Fis_attacked(G2,0)) score -= 40;
669       if (board[G1] == wrook) score += 10;
670       if (board[F1] == wbishop) score += 10;
671     }
672   if (board[G7] == wknight)
673     {
674       score += 20;
675       if (Fis_attacked(G7,1)) score += 40;
676       if (board[G8] == brook) score -= 10;
677       if (board[F8] == bbishop)score -= 10;
678     }
679 
680   /* Bishop at h3/h6 often leads to crushing attacks */
681   /* Especially when the king is trapped behind a N  */
682 
683   if ((board[H3] == bbishop) && (board[G2] != wpawn))
684     {
685       score -= 20;
686       if (board[G2] == bknight)
687 	{
688 	  score -= 40;
689 	  if (board[F1] == wking || board[G1] == wking || board[H1] == wking)
690 	      score -= 80;
691 	}
692     }
693   if ((board[H6] == wbishop) && (board[G7] != bpawn))
694     {
695       score += 20;
696       if (board[G7] == wknight)
697 	{
698 	  score += 40;
699 	  if (board[F8] == bking || board[G8] == bking || board[H8] == bking)
700 	    score += 80;
701 	}
702     }
703   }
704 
705   if (cfg_attackeval)
706   {
707     badsquares = 0;
708     safety = 0;
709 
710     badsquares += Gis_attacked(wking_loc - 13, 0);
711     badsquares += Gis_attacked(wking_loc - 12, 0);
712     badsquares += Gis_attacked(wking_loc - 11, 0);
713     badsquares += Gis_attacked(wking_loc -  1, 0);
714     badsquares += Gis_attacked(wking_loc +  1, 0);
715     badsquares += Gis_attacked(wking_loc + 11, 0);
716     badsquares += Gis_attacked(wking_loc + 12, 0);
717     badsquares += Gis_attacked(wking_loc + 13, 0);
718 
719     norm_black_hand_eval = ((-black_hand_eval) / 100);
720     if (norm_black_hand_eval > 14) norm_black_hand_eval = 14;
721     else if (norm_black_hand_eval < 0) norm_black_hand_eval = 0;
722 
723     safety -= ksafety_scaled[norm_black_hand_eval][badsquares];
724 
725     badsquares = 0;
726 
727     badsquares += Gis_attacked(bking_loc - 13, 1);
728     badsquares += Gis_attacked(bking_loc - 12, 1);
729     badsquares += Gis_attacked(bking_loc - 11, 1);
730     badsquares += Gis_attacked(bking_loc -  1, 1);
731     badsquares += Gis_attacked(bking_loc +  1, 1);
732     badsquares += Gis_attacked(bking_loc + 11, 1);
733     badsquares += Gis_attacked(bking_loc + 12, 1);
734     badsquares += Gis_attacked(bking_loc + 13, 1);
735 
736     norm_white_hand_eval = (white_hand_eval / 100);
737     if (norm_white_hand_eval > 14) norm_white_hand_eval = 14;
738     else if (norm_white_hand_eval < 0) norm_white_hand_eval = 0;
739 
740     safety += ksafety_scaled[norm_white_hand_eval][badsquares];
741 
742     score += safety;
743   }
744 
745   score += (white_hand_eval + black_hand_eval);
746 
747   storeECache(score);
748 
749   /* adjust for color: */
750   if (white_to_move == 1) {
751     return score;
752   }
753   else {
754     return -score;
755   }
756 
757 }
758 
759