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