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