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
29int Material;
30int std_material[] = { 0, 100, -100, 310, -310, 4000, -4000, 500, -500, 900, -900, 325, -325, 0 };
31
32int zh_material[] = { 0, 100, -100, 210, -210, 4000, -4000, 250, -250, 450, -450, 230, -230, 0 };
33
34int suicide_material[] = { 0, 15, -15, 150, -150, 500, -500, 150, -150, 50, -50, 0, 0, 0 };
35
36int losers_material[] = { 0, 80, -80, 320, -320, 1000, -1000, 350, -350, 400, -400, 270, -270, 0 };
37
38int material[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
39
40const 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
56const 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
72const 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
88const 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
104const 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
122const int bishop[144] = {
1230,0,0,0,0,0,0,0,0,0,0,0,
1240,0,0,0,0,0,0,0,0,0,0,0,
1250,0,-5,-5,-10,-5,-5,-10,-5,-5,0,0,
1260,0,-5,10,5,10,10,5,10,-5,0,0,
1270,0,-5,5,6,15,15,6,5,-5,0,0,
1280,0,-5,3,15,10,10,15,3,-5,0,0,
1290,0,-5,3,15,10,10,15,3,-5,0,0,
1300,0,-5,5,6,15,15,6,5,-5,0,0,
1310,0,-5,10,5,10,10,5,10,-5,0,0,
1320,0,-5,-5,-10,-5,-5,-10,-5,-5,0,0,
1330,0,0,0,0,0,0,0,0,0,0,0,
1340,0,0,0,0,0,0,0,0,0,0,0};
135
136const int black_knight[144] = {
1370,0,0,0,0,0,0,0,0,0,0,0,
1380,0,0,0,0,0,0,0,0,0,0,0,
1390,0,-20,-10,-10,-10,-10, -10,-10,-20,0,0,
1400,0,-10, 15, 25, 25, 25,  25, 15,-10,0,0,
1410,0,-10, 15, 25, 35, 35 , 35, 15,-10,0,0,
1420,0,-10, 10, 25, 20, 25,  25, 10,-10,0,0,
1430,0,-10, 0,  20, 20, 20,  20,  0,-10,0,0,
1440,0,-10, 0,  15, 15, 15,  15,  0,-10,0,0,
1450,0,-10, 0,   0,  3,  3,   0,  0,-10,0,0,
1460,0,-20,-35,-10,-10,-10, -10,-35,-20,0,0,
1470,0,0,0,0,0,0,0,0,0,0,0,
1480,0,0,0,0,0,0,0,0,0,0,0};
149
150const int white_knight[144] = {
1510,0,0,0,0,0,0,0,0,0,0,0,
1520,0,0,0,0,0,0,0,0,0,0,0,
1530,0,-20, -35,-10, -10, -10,-10, -35, -20,0,0,
1540,0,-10,   0,  0,   3,   3,  0,   0, -10,0,0,
1550,0,-10,   0, 15,  15,  15, 15,   0, -10,0,0,
1560,0,-10,   0, 20,  20,  20, 20,   0, -10,0,0,
1570,0,-10,  10, 25,  20,  25, 25,  10, -10,0,0,
1580,0,-10,  15, 25,  35,  35, 35,  15, -10,0,0,
1590,0,-10,  15, 25,  25,  25, 25,  15, -10,0,0,
1600,0,-20, -10,-10, -10, -10,-10, -10, -20,0,0,
1610,0,0,0,0,0,0,0,0,0,0,0,
1620,0,0,0,0,0,0,0,0,0,0,0};
163
164const 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
180const 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: */
197const int white_king[144] = {
1980,0,0,0,0,0,0,0,0,0,0,0,
1990,0,0,0,0,0,0,0,0,0,0,0,
2000,0,-100,   7,   4,  0,  10  , 4,   7,-100,0,0,
2010,0,-250,-200,-150,-100,-100,-150,-200,-250,0,0,
2020,0,-350,-300,-300,-250,-250,-300,-300,-350,0,0,
2030,0,-400,-400,-400,-350,-350,-400,-400,-400,0,0,
2040,0,-450,-450,-450,-450,-450,-450,-450,-450,0,0,
2050,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
2060,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
2070,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
2080,0,0,0,0,0,0,0,0,0,0,0,
2090,0,0,0,0,0,0,0,0,0,0,0};
210
211/* to be used during opening and middlegame for black king positioning: */
212const int black_king[144] = {
2130,0,0,0,0,0,0,0,0,0,0,0,
2140,0,0,0,0,0,0,0,0,0,0,0,
2150,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
2160,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
2170,0,-500,-500,-500,-500,-500,-500,-500,-500,0,0,
2180,0,-450,-450,-450,-450,-450,-450,-450,-450,0,0,
2190,0,-400,-400,-400,-350,-350,-400,-400,-400,0,0,
2200,0,-350,-300,-300,-250,-250,-300,-300,-350,0,0,
2210,0,-250,-200,-150,-100,-100,-150,-200,-250,0,0,
2220,0,-100,   7,   4,   0,  10  , 4,   7,-100,0,0,
2230,0,0,0,0,0,0,0,0,0,0,0,
2240,0,0,0,0,0,0,0,0,0,0,0};
225
226const int black_queen[144] = {
2270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2290, 0, 5, 5, 5,10,10, 5, 5, 5, 0, 0,
2300, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0,
2310, 0,-30,-30,-30,-30,-30,-30,-30,-30,0, 0,
2320,0,-60,-40,-40,-60,-60,-40,-40,-60,0,0,
2330,0,-40,-40,-40,-40,-40,-40,-40,-40,0,0,
2340,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0,
2350,0,0,0,0,7,10,5,0,0,0,0,
2360,0,0,0,0, 5,0,0,0,0,0,0,
2370,0,0,0,0,0,0,0,0,0,0,0,
2380,0,0,0,0,0,0,0,0,0,0,0};
239
240
241const int white_queen[144] = {
2420,0,0,0,0,0,0,0,0,0,0,0,
2430,0,0,0,0,0,0,0,0,0,0,0,
2440,0,0,0,0,5,0,0,0,0,0,0,
2450,0,0,0,0,7,10,5,0,0,0,0,
2460,0,-15,-15,-15,-10,-10,-15,-15,-15,0,0,
2470,0,-40,-40,-40,-40,-40,-40,-40,-40,0,0,
2480,0,-60,-40,-40,-60,-60,-40,-40,-60,0,0,
2490, 0,-30,-30,-30,-30,-30,-30,-30,-30,0, 0,
2500, 0, 0, 0, 3, 3, 3,3,3, 0, 0, 0,
2510, 0, 5, 5, 5,10,10,5,5,5, 0, 0,
2520,0,0,0,0,0,0,0,0,0,0,0,
2530,0,0,0,0,0,0,0,0,0,0,0};
254
255const 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
271const 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
290int pre_p_tropism[9] =
291{ 9999, 40, 20, 10, 3, 1, 1, 0, 9999};
292
293int pre_r_tropism[9] =
294{ 9999, 50, 40, 15, 5, 1, 1, 0, 9999};
295
296int pre_n_tropism[9] =
297{ 9999, 50, 70, 35, 10, 2, 1, 0, 9999};
298
299int pre_q_tropism[9] =
300{ 9999, 100, 60, 20, 5, 2, 0, 0, 9999};
301
302int pre_b_tropism[9] =
303{ 9999, 50, 25, 15, 5, 2, 2, 2, 9999};
304
305unsigned char p_tropism[144][144];
306unsigned char q_tropism[144][144];
307unsigned char n_tropism[144][144];
308unsigned char r_tropism[144][144];
309unsigned char b_tropism[144][144];
310
311int 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
330void 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
371int32_t eval (void) {
372
373  /* return a score for the current middlegame position: */
374
375  int i, a, j;
376  int32_t 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