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: neval.c 20 Purpose: functions for evaluating positions (standard chess) 21 22*/ 23 24#include "sjeng.h" 25#include "extvars.h" 26#include "protos.h" 27#include "squares.h" 28 29/* these tables will be used for positional bonuses: */ 30 31static int sbishop[144] = { 320,0,0,0,0,0,0,0,0,0,0,0, 330,0,0,0,0,0,0,0,0,0,0,0, 340,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0, 350,0,-2,8,5,5,5,5,8,-2,0,0, 360,0,-2,3,3,5,5,3,3,-2,0,0, 370,0,-2,2,5,4,4,5,2,-2,0,0, 380,0,-2,2,5,4,4,5,2,-2,0,0, 390,0,-2,3,3,5,5,3,3,-2,0,0, 400,0,-2,8,5,5,5,5,8,-2,0,0, 410,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0, 420,0,0,0,0,0,0,0,0,0,0,0, 430,0,0,0,0,0,0,0,0,0,0,0}; 44 45static int sknight[144] = { 460,0,0,0,0,0,0,0,0,0,0,0, 470,0,0,0,0,0,0,0,0,0,0,0, 480,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0, 490,0,-10,0,0,3,3,0,0,-10,0,0, 500,0,-10,0,5,5,5,5,0,-10,0,0, 510,0,-10,0,5,10,10,5,0,-10,0,0, 520,0,-10,0,5,10,10,5,0,-10,0,0, 530,0,-10,0,5,5,5,5,0,-10,0,0, 540,0,-10,0,0,3,3,0,0,-10,0,0, 550,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0, 560,0,0,0,0,0,0,0,0,0,0,0, 570,0,0,0,0,0,0,0,0,0,0,0}; 58 59static int32_t swhite_pawn[144] = { 600,0,0,0,0,0,0,0,0,0,0,0, 610,0,0,0,0,0,0,0,0,0,0,0, 620,0,0,0,0,0,0,0,0,0,0,0, 630,0,0,0,0,0,0,0,0,0,0,0, 640,0,1,2,3,10,10,3,2,1,0,0, 650,0,2,4,6,12,12,6,4,2,0,0, 660,0,3,6,9,14,14,9,6,3,0,0, 670,0,4,8,12,16,16,12,8,4,0,0, 680,0,5,10,15,20,20,15,10,5,0,0, 690,0,0,0,0,0,0,0,0,0,0,0, 700,0,0,0,0,0,0,0,0,0,0,0, 710,0,0,0,0,0,0,0,0,0,0,0}; 72 73static int sblack_pawn[144] = { 740,0,0,0,0,0,0,0,0,0,0,0, 750,0,0,0,0,0,0,0,0,0,0,0, 760,0,0,0,0,0,0,0,0,0,0,0, 770,0,5,10,15,20,20,15,10,5,0,0, 780,0,4,8,12,16,16,12,8,4,0,0, 790,0,3,6,9,14,14,9,6,3,0,0, 800,0,2,4,6,12,12,6,4,2,0,0, 810,0,1,2,3,10,10,3,2,1,0,0, 820,0,0,0,0,0,0,0,0,0,0,0, 830,0,0,0,0,0,0,0,0,0,0,0, 840,0,0,0,0,0,0,0,0,0,0,0, 850,0,0,0,0,0,0,0,0,0,0,0}; 86 87/* to be used during opening and middlegame for white king positioning: */ 88static int swhite_king[144] = { 890,0,0,0,0,0,0,0,0,0,0,0, 900,0,0,0,0,0,0,0,0,0,0,0, 910,0,2,14,0,0,0,9,14,2,0,0, 920,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0, 930,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0, 940,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0, 950,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0, 960,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0, 970,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0, 980,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0, 990,0,0,0,0,0,0,0,0,0,0,0, 1000,0,0,0,0,0,0,0,0,0,0,0}; 101 102/* to be used during opening and middlegame for black king positioning: */ 103static int sblack_king[144] = { 1040,0,0,0,0,0,0,0,0,0,0,0, 1050,0,0,0,0,0,0,0,0,0,0,0, 1060,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0, 1070,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0, 1080,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0, 1090,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0, 1100,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0, 1110,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0, 1120,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0, 1130,0,2,14,0,0,0,9,14,2,0,0, 1140,0,0,0,0,0,0,0,0,0,0,0, 1150,0,0,0,0,0,0,0,0,0,0,0}; 116 117/* to be used for positioning of both kings during the endgame: */ 118static int send_king[144] = { 1190,0,0,0,0,0,0,0,0,0,0,0, 1200,0,0,0,0,0,0,0,0,0,0,0, 1210,0,-5,-3,-1,0,0,-1,-3,-5,0,0, 1220,0,-3,10,10,10,10,10,10,-3,0,0, 1230,0,-1,10,25,25,25,25,10,-1,0,0, 1240,0,0,10,25,30,30,25,10,0,0,0, 1250,0,0,10,25,30,30,25,10,0,0,0, 1260,0,-1,10,25,25,25,25,10,-1,0,0, 1270,0,-3,10,10,10,10,10,10,-3,0,0, 1280,0,-5,-3,-1,0,0,-1,-3,-5,0,0, 1290,0,0,0,0,0,0,0,0,0,0,0, 1300,0,0,0,0,0,0,0,0,0,0,0}; 131 132/* utility array to reverse rank: */ 133static int srev_rank[9] = { 1340,8,7,6,5,4,3,2,1}; 135 136const int std_p_tropism[9] = 137{ 9999, 15, 10, 7, 2, 0, 0, 0, 9999}; 138 139const int std_r_tropism[9] = 140{ 9999, 10, 6, 4, 2, 0, 0, 0, 9999}; 141 142const int std_n_tropism[9] = 143{ 9999, 14, 9, 6, 1, 0, 0, 0, 9999}; 144 145const int std_q_tropism[9] = 146{ 9999, 16, 12, 7, 2, 0, 0, 0, 9999}; 147 148const int std_b_tropism[9] = 149{ 9999, 12, 7, 5, 0, 0, 0, 0, 9999}; 150 151 152static int bishop_mobility(int square) 153{ 154 register int l; 155 register int m = 0; 156 157 for (l = square-13; board[l] == npiece; l-=13) 158 m++; 159 for (l = square-11; board[l] == npiece; l-=11) 160 m++; 161 for (l = square+11; board[l] == npiece; l+=11) 162 m++; 163 for (l = square+13; board[l] == npiece; l+=13) 164 m++; 165 166 return m; 167} 168 169int32_t end_eval (void) { 170 171 /* return a score for the current endgame position: */ 172 173 int i, a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11], 174 srank, j; 175 int32_t score = 0; 176 bool isolated, backwards; 177 int in_cache; 178 int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0, 179 wq = 0, bq = 0, wr = 0, br = 0; 180 int fwrook, fbrook, rwrook, rbrook; 181 int wpotential = 0, bpotential = 0, tmp; 182 183 in_cache = 0; 184 185 checkECache(&score, &in_cache); 186 187 if(in_cache) 188 { 189 if (white_to_move == 1) return score; 190 return -score; 191 } 192 193 194 /* initialize the pawns array, (files offset by one to use dummy files in 195 order to easier determine isolated status) and also initialize the 196 arrays keeping track of the rank of the most backward pawn: */ 197 memset (pawns, 0, sizeof (pawns)); 198 for (i = 0; i < 11; i++) { 199 white_back_pawn[i] = 7; 200 black_back_pawn[i] = 2; 201 } 202 for (j = 1, a = 1; (a <= piece_count); j++) { 203 i = pieces[j]; 204 205 if (!i) 206 continue; 207 else 208 a++; 209 210 assert((i > 0) && (i < 145)); 211 212 pawn_file = file (i)+1; 213 srank = rank (i); 214 if (board[i] == wpawn) { 215 pawns[1][pawn_file]++; 216 if (srank < white_back_pawn[pawn_file]) { 217 white_back_pawn[pawn_file] = srank; 218 } 219 } 220 else if (board[i] == bpawn) { 221 pawns[0][pawn_file]++; 222 if (srank > black_back_pawn[pawn_file]) { 223 black_back_pawn[pawn_file] = srank; 224 } 225 } 226 } 227 228 /* loop through the board, adding material value, as well as positional 229 bonuses for all pieces encountered: */ 230 for (j = 1, a = 1; (a <= piece_count); j++) { 231 i = pieces[j]; 232 233 if (!i) 234 continue; 235 else 236 a++; 237 238 pawn_file = file (i)+1; 239 srank = rank (i); 240 switch (board[i]) { 241 case (wpawn): 242 isolated = FALSE; 243 backwards = FALSE; 244 score += 100; 245 score += swhite_pawn[i]; 246 wp++; 247 248 /* in general, bonuses/penalties in the endgame evaluation will be 249 higher, since pawn structure becomes more important for the 250 creation of passed pawns */ 251 252 /* check for backwards pawns: */ 253 if (white_back_pawn[pawn_file+1] > srank 254 && white_back_pawn[pawn_file-1] > srank) { 255 score -= 8; 256 backwards = TRUE; 257 /* check to see if it is furthermore isolated: */ 258 if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { 259 score -= 5; 260 isolated = TRUE; 261 } 262 } 263 264 /* give weak, exposed pawns a penalty (not as much as in the midgame, 265 since there may be no pieces to take advantage of it): */ 266 if (!pawns[0][pawn_file]) { 267 if (backwards) score -= 3; 268 if (isolated) score -= 5; 269 } 270 271 /* give doubled, trippled, etc.. pawns a penalty (bigger in the 272 endgame, since they will become big targets): */ 273 if (pawns[1][pawn_file] > 1) 274 score -= 3*(pawns[1][pawn_file]-1); 275 276 /* give bonuses for passed pawns (bigger in the endgame since passed 277 pawns are what wins the endgame): */ 278 if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && 279 srank >= black_back_pawn[pawn_file+1]) { 280 score += 30 + 3*swhite_pawn[i]; 281 282 if (white_to_move) 283 { 284 /* check queening race */ 285 /* tmp = queening square */ 286 tmp = A8 + file(i) - 1; 287 /* king is away how much ?*/ 288 if (max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp))) 289 > (abs(rank(tmp) - rank(i)))) 290 { 291 wpotential += 800; 292 } 293 } 294 else 295 { 296 /* check queening race */ 297 /* tmp = queening square */ 298 tmp = A8 + file(i) - 1; 299 /* king is away how much ?*/ 300 if ((max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp)))-1) 301 > (abs(rank(tmp) - rank(i)))) 302 { 303 wpotential += 800; 304 } 305 } 306 307 /* outside passer ? */ 308 if (file(i) == 1 || file(i) == 8) 309 score += 12 + 2*swhite_pawn[i]; 310 311 /* give an extra bonus if a connected, passed pawn: */ 312 if (!isolated) 313 { 314 score += 12; 315 316 /* check whether supporter is passed */ 317 if (pawns[1][pawn_file+1]) 318 { 319 if (!pawns[0][pawn_file+1] 320 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2]) 321 { 322 score += 7*rank(i); 323 324 /* connected on seventh ? */ 325 if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6) 326 { 327 score += 50; 328 } 329 } 330 } 331 if (pawns[1][pawn_file-1]) 332 { 333 if (!pawns[0][pawn_file-1] 334 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2]) 335 { 336 score += 7*rank(i); 337 338 /* connected on seventh ? */ 339 if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6) 340 { 341 score += 50; 342 } 343 } 344 } 345 } 346 } 347 348 if (!pawns[1][pawn_file-1]) 349 score -= 7; 350 351 break; 352 353 case (bpawn): 354 isolated = FALSE; 355 backwards = FALSE; 356 score -= 100; 357 score -= sblack_pawn[i]; 358 bp++; 359 360 /* in general, bonuses/penalties in the endgame evaluation will be 361 higher, since pawn structure becomes more important for the 362 creation of passed pawns */ 363 364 /* check for backwards pawns: */ 365 if (black_back_pawn[pawn_file+1] < srank 366 && black_back_pawn[pawn_file-1] < srank) { 367 score += 8; 368 backwards = TRUE; 369 /* check to see if it is furthermore isolated: */ 370 if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { 371 score += 5; 372 isolated = TRUE; 373 } 374 } 375 376 /* give weak, exposed pawns a penalty (not as much as in the midgame, 377 since there may be no pieces to take advantage of it): */ 378 if (!pawns[1][pawn_file]) { 379 if (backwards) score += 3; 380 if (isolated) score += 5; 381 } 382 383 /* give doubled, trippled, etc.. pawns a penalty (bigger in the 384 endgame, since they will become big targets): */ 385 if (pawns[0][pawn_file] > 1) 386 score += 3*(pawns[0][pawn_file]-1); 387 388 /* give bonuses for passed pawns (bigger in the endgame since passed 389 pawns are what wins the endgame): */ 390 if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && 391 srank <= white_back_pawn[pawn_file+1]) { 392 score -= 30 + 3*sblack_pawn[i]; 393 394 if (!white_to_move) 395 { 396 /* check queening race */ 397 /* tmp = queening square */ 398 tmp = A1 + file(i) - 1; 399 /* king is away how much ?*/ 400 if (max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp))) 401 > (abs(rank(tmp) - (rank(i))))) 402 { 403 bpotential -= 800; 404 } 405 } 406 else 407 { 408 /* check queening race */ 409 /* tmp = queening square */ 410 tmp = A1 + file(i) - 1; 411 /* king is away how much ?*/ 412 if ((max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp)))-1) 413 > abs((rank(tmp) - rank(i)))) 414 { 415 bpotential -= 800; 416 } 417 } 418 419 /* outside passer ? */ 420 if (file(i) == 1 || file(i) == 8) 421 score -= 12 + 2*sblack_pawn[i]; 422 423 /* give an extra bonus if a connected, passed pawn: */ 424 if (!isolated) 425 { 426 score -= 12; 427 428 /* check whether supporter is passed */ 429 if (pawns[0][pawn_file+1]) 430 { 431 if (!pawns[1][pawn_file+1] 432 && black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2]) 433 { 434 score -= 7*(9-rank(i)); 435 436 /* on seventh and supported ? */ 437 if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3) 438 { 439 score -= 50; 440 } 441 } 442 } 443 if (pawns[0][pawn_file-1]) 444 { 445 if (!pawns[1][pawn_file-1] 446 && black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2]) 447 { 448 score -= 7*(9-rank(i)); 449 450 /* connected on seventh ? */ 451 if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3) 452 { 453 score -= 50; 454 } 455 456 } 457 } 458 } 459 } 460 461 if (!pawns[0][pawn_file-1]) 462 score += 7; 463 464 break; 465 466 case (wrook): 467 score += 500; 468 wr++; 469 470 if (wr == 1) 471 { 472 fwrook = file(i); 473 rwrook = rank(i); 474 } 475 476 /* bonus for being on the 7th (a bit bigger bonus in the endgame, b/c 477 a rook on the 7th can be a killer in the endgame): */ 478 if (srank == 7) 479 { 480 score += 12; 481 482 if (wr == 2 && 7 == rwrook) 483 { 484 score += 10; 485 } 486 } 487 488 /* give bonuses depending on how open the rook's file is: */ 489 if (!pawns[1][pawn_file]) { 490 /* half open file */ 491 score += 5; 492 493 if (wr == 2 && file(i) == fwrook) 494 { 495 /* connected on file */ 496 score += 10; 497 } 498 499 if (!pawns[0][pawn_file]) { 500 /* open file */ 501 score += 3; 502 } 503 } 504 505 break; 506 507 case (brook): 508 score -= 500; 509 br++; 510 511 if (br == 1) 512 { 513 fbrook = file(i); 514 rbrook = rank(i); 515 } 516 517 518 /* bonus for being on the 7th (a bit bigger bonus in the endgame, b/c 519 a rook on the 7th can be a killer in the endgame): */ 520 if (srank == 2) 521 { 522 score -= 12; 523 524 if (br == 2 && 2 == rbrook) 525 { 526 score -= 10; 527 } 528 } 529 530 /* give bonuses depending on how open the rook's file is: */ 531 if (!pawns[0][pawn_file]) 532 { 533 /* half open file */ 534 score -= 5; 535 536 if (br == 2 && file(i) == fbrook) 537 { 538 /* connected on file */ 539 score -= 10; 540 } 541 542 if (!pawns[1][pawn_file]) 543 { 544 /* open file */ 545 score -= 3; 546 } 547 } 548 break; 549 550 case (wbishop): 551 score += 325; 552 score += sbishop[i]; 553 score += (bishop_mobility(i) << 1) - 15; 554 wb++; 555 break; 556 557 case (bbishop): 558 score -= 325; 559 score -= sbishop[i]; 560 score -= (bishop_mobility(i) << 1) - 15; 561 bb++; 562 break; 563 564 case (wknight): 565 score += 310; 566 score += sknight[i]; 567 wn++; 568 break; 569 570 case (bknight): 571 score -= 310; 572 score -= sknight[i]; 573 bn++; 574 break; 575 576 case (wqueen): 577 score += 900; 578 wq++; 579 break; 580 581 case (bqueen): 582 score -= 900; 583 bq++; 584 break; 585 } 586 } 587 588 /* some static knowledge about drawn endgames */ 589 590 /* pawn ending detection */ 591 if (!wr && !wq && !wb && !wn) 592 { 593 score += bpotential; 594 } 595 596 if (!br && !bq && !bb && !bn) 597 { 598 score += wpotential; 599 } 600 601 /* no more pawns */ 602 if (!wp && !bp) 603 { 604 /* nor heavies */ 605 if (!wr && !br && !wq && !bq) 606 { 607 if (!bb && !wb) 608 { 609 /* only knights */ 610 /* it pretty safe to say this is a draw */ 611 if (wn < 3 && bn < 3) 612 { 613 score = 0; 614 } 615 } 616 else if (!wn && !bn) 617 { 618 /* only bishops */ 619 /* not a draw if one side two other side zero 620 else its always a draw */ 621 if (abs(wb - bb) < 2) 622 { 623 score = 0; 624 } 625 } 626 else if ((wn < 3 && !wb) || (wb == 1 && !wn)) 627 { 628 /* we cant win, but can black? */ 629 if ((bn < 3 && !bb) || (bb == 1 && !bn)) 630 { 631 /* guess not */ 632 score = 0; 633 } 634 } 635 } 636 else if (!wq && !bq) 637 { 638 if (wr == 1 && br == 1) 639 { 640 /* rooks equal */ 641 if ((wn + wb) < 2 && (bn + bb) < 2) 642 { 643 /* one minor difference max */ 644 /* a draw too usually */ 645 score = 0; 646 } 647 } 648 else if (wr == 1 && !br) 649 { 650 /* one rook */ 651 /* draw if no minors to support AND 652 minors to defend */ 653 if ((wn + wb == 0) && (((bn + bb) == 1) || ((bn + bb) == 2))) 654 { 655 score = 0; 656 } 657 } 658 else if (br == 1 && !wr) 659 { 660 /* one rook */ 661 /* draw if no minors to support AND 662 minors to defend */ 663 if ((bn + bb == 0) && (((wn + wb) == 1) || ((wn + wb) == 2))) 664 { 665 score = 0; 666 } 667 } 668 } 669 } 670 else 671 { 672 /* bad trade code, largely based on Crafty's */ 673 /* minors are not equal */ 674 if ((wn + wb) != (bn + bb)) 675 { 676 /* majors are equal */ 677 if ((wq + wr) == (bq + br)) 678 { 679 if ((wn + wb) > (bn + bb)) 680 { 681 /* white is a piece up */ 682 score += 120; 683 } 684 else 685 { 686 /* black is a piece up */ 687 score -= 120; 688 } 689 } 690 else if (abs((wr + wq) - (br + bq)) == 1) 691 { 692 /* one major difference */ 693 694 if ((wb + wn) > (bb + bn + 1)) 695 { 696 /* two minors for one major */ 697 score += 120; 698 } 699 else if ((bb + bn) > (wb + wn + 1)) 700 { 701 score -= 120; 702 } 703 } 704 else if (abs((wr + wq) - (br + bq)) == 2) 705 { 706 /* two majors difference */ 707 708 if ((wb + wn) > (bb + bn + 2)) 709 { 710 /* three minors for two majors */ 711 score += 120; 712 } 713 else if ((bb + bn) > (wb + wn + 2)) 714 { 715 score -= 120; 716 } 717 718 } 719 } 720 else if ((wq + wr) == (bq + br)) 721 { 722 if (wq && !bq) 723 { 724 score += 120; 725 } 726 else if (!wq && bq) 727 { 728 score -= 120; 729 } 730 } 731 } 732 733 /* the king is safe to come out in the endgame, so we don't check for 734 king safety anymore, and encourage centralization of the king */ 735 score += send_king[wking_loc]; 736 737 /* the king is safe to come out in the endgame, so we don't check for 738 king safety anymore, and encourage centralization of the king */ 739 score -= send_king[bking_loc]; 740 741 /* the e/d pawn blockage is not relevant in the endgame, and we don't need 742 to check for king safety due to pawn storms / heavy piece infiltration */ 743 744 storeECache(score); 745 746 /* adjust for color: */ 747 if (white_to_move == 1) { 748 return score; 749 } 750 else { 751 return -score; 752 } 753 754} 755 756void check_phase(void) 757{ 758 int num_pieces = 0; 759 int j, a, i; 760 761 for (j = 1, a = 1; (a <= piece_count); j++) 762 { 763 i = pieces[j]; 764 765 if (!i) 766 continue; 767 else 768 a++; 769 770 if (board[i] != wpawn && board[i] != bpawn && 771 board[i] != npiece && board[i] != frame) 772 { 773 num_pieces++; 774 } 775 }; 776 if ((num_pieces >= 12) 777 /* not both have castled */ 778 && (!white_castled || !black_castled) 779 /* no both lost castling priveledges */ 780 && (board[30] == wking || board[114] == bking)) 781 { 782 phase = Opening; 783 } 784 else if (num_pieces <= 6) 785 { 786 phase = Endgame; 787 } 788 else 789 phase = Middlegame; 790 791} 792 793int32_t std_eval (void) { 794 795 /* select the appropriate eval() routine: */ 796 797 if (phase == Opening) { 798 return (opn_eval ()); 799 } 800 else if (phase == Endgame) { 801 return (end_eval ()); 802 } 803 else { 804 return (mid_eval ()); 805 } 806 807} 808 809 810int32_t mid_eval (void) { 811 812 /* return a score for the current middlegame position: */ 813 814 int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11], 815 srank, wking_pawn_file, bking_pawn_file, j; 816 int32_t score = 0; 817 bool isolated, backwards; 818 int in_cache; 819 int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0, 820 wq = 0, bq = 0, wr = 0, br = 0; 821 int rbrook, fbrook, rwrook,fwrook; 822 823 in_cache = 0; 824 825 checkECache(&score, &in_cache); 826 827 if(in_cache) 828 { 829 if (white_to_move == 1) return score; 830 return -score; 831 } 832 833 /* initialize the pawns array, (files offset by one to use dummy files in 834 order to easier determine isolated status) and also initialize the 835 arrays keeping track of the rank of the most backward pawn: */ 836 memset (pawns, 0, sizeof (pawns)); 837 for (i = 0; i < 11; i++) { 838 white_back_pawn[i] = 7; 839 black_back_pawn[i] = 2; 840 } 841 for (j = 1, a = 1; (a <= piece_count); j++) { 842 i = pieces[j]; 843 844 if (!i) 845 continue; 846 else 847 a++; 848 849 assert((i > 0) && (i < 145)); 850 851 if (board[i] == wpawn) { 852 pawn_file = file (i)+1; 853 srank = rank (i); 854 855 pawns[1][pawn_file]++; 856 if (srank < white_back_pawn[pawn_file]) { 857 white_back_pawn[pawn_file] = srank; 858 } 859 } 860 else if (board[i] == bpawn) { 861 pawn_file = file (i)+1; 862 srank = rank (i); 863 864 pawns[0][pawn_file]++; 865 if (srank > black_back_pawn[pawn_file]) { 866 black_back_pawn[pawn_file] = srank; 867 } 868 } 869 } 870 871 /* loop through the board, adding material value, as well as positional 872 bonuses for all pieces encountered: */ 873 for (j = 1, a = 1; (a <= piece_count); j++) { 874 i = pieces[j]; 875 876 if (!i) 877 continue; 878 else 879 a++; 880 881 pawn_file = file (i)+1; 882 srank = rank (i); 883 switch (board[i]) { 884 case (wpawn): 885 isolated = FALSE; 886 backwards = FALSE; 887 score += 100; 888 score += swhite_pawn[i]; 889 wp++; 890 891 /* check for backwards pawns: */ 892 if (white_back_pawn[pawn_file+1] > srank 893 && white_back_pawn[pawn_file-1] > srank) { 894 score -= 5; 895 backwards = TRUE; 896 /* check to see if it is furthermore isolated: */ 897 if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { 898 score -= 3; 899 isolated = TRUE; 900 } 901 } 902 903 score += std_p_tropism[max(abs(rank(i) - rank(bking_loc)), 904 abs(file(i) - file(bking_loc)))]; 905 /* give weak, exposed pawns a penalty: */ 906 if (!pawns[0][pawn_file]) { 907 if (backwards) score -= 4; 908 if (isolated) score -= 8; 909 } 910 911 /* give doubled, trippled, etc.. pawns a penalty: */ 912 if (pawns[1][pawn_file] > 1) 913 score -= 2*(pawns[1][pawn_file]-1); 914 915 /* give bonuses for passed pawns: */ 916 if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && 917 srank >= black_back_pawn[pawn_file+1]) { 918 score += 20 + 2*swhite_pawn[i]; 919 /* give an extra bonus if a connected, passed pawn: */ 920 if (!isolated) 921 { 922 score += 10; 923 924 /* check whether supporter is passed */ 925 if (pawns[1][pawn_file+1]) 926 { 927 if (!pawns[0][pawn_file+1] 928 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2]) 929 { 930 score += 7*rank(i); 931 932 /* connected on seventh ? */ 933 if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6) 934 { 935 score += 50; 936 } 937 } 938 } 939 if (pawns[1][pawn_file-1]) 940 { 941 if (!pawns[0][pawn_file-1] 942 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2]) 943 { 944 score += 7*rank(i); 945 946 /* connected on seventh ? */ 947 if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6) 948 { 949 score += 50; 950 } 951 } 952 } 953 954 } 955 } 956 957 if (!pawns[1][pawn_file-1]) 958 score -= 5; 959 960 break; 961 962 case (bpawn): 963 isolated = FALSE; 964 backwards = FALSE; 965 score -= 100; 966 score -= sblack_pawn[i]; 967 bp++; 968 969 /* check for backwards pawns: */ 970 if (black_back_pawn[pawn_file+1] < srank 971 && black_back_pawn[pawn_file-1] < srank) { 972 score += 5; 973 backwards = TRUE; 974 /* check to see if it is furthermore isolated: */ 975 if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { 976 score += 3; 977 isolated = TRUE; 978 } 979 } 980 981 score -= std_p_tropism[max(abs(rank(i) - rank(wking_loc)), 982 abs(file(i) - file(wking_loc)))]; 983 984 /* give weak, exposed pawns a penalty: */ 985 if (!pawns[1][pawn_file]) { 986 if (backwards) score += 4; 987 if (isolated) score += 8; 988 } 989 990 /* give doubled, trippled, etc.. pawns a penalty: */ 991 if (pawns[0][pawn_file] > 1) 992 score += 2*(pawns[0][pawn_file]-1); 993 994 /* give bonuses for passed pawns: */ 995 if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && 996 srank <= white_back_pawn[pawn_file+1]) { 997 score -= 20 + 2*sblack_pawn[i]; 998 /* give an extra bonus if a connected, passed pawn: */ 999 if (!isolated) 1000 { 1001 score -= 10; 1002 1003 /* check whether supporter is passed */ 1004 if (pawns[0][pawn_file+1]) 1005 { 1006 if (!pawns[1][pawn_file+1] 1007 && black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2]) 1008 { 1009 score -= 7*(9-rank(i)); 1010 1011 /* connected on seventh ? */ 1012 if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3) 1013 { 1014 score -= 50; 1015 } 1016 1017 } 1018 } 1019 if (pawns[0][pawn_file-1]) 1020 { 1021 if (!pawns[1][pawn_file-1] 1022 && black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2]) 1023 { 1024 score -= 7*(9-rank(i)); 1025 1026 /* connected on seventh ? */ 1027 if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3) 1028 { 1029 score -= 50; 1030 } 1031 } 1032 } 1033 } 1034 } 1035 1036 if (!pawns[0][pawn_file-1]) 1037 score += 5; 1038 1039 break; 1040 1041 case (wrook): 1042 score += 500; 1043 wr++; 1044 1045 if (wr == 1) 1046 { 1047 fwrook = file(i); 1048 rwrook = rank(i); 1049 } 1050 1051 score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)), 1052 abs(file(i) - file(bking_loc)))]; 1053 1054 /* bonus for being on the 7th: */ 1055 if (srank == 7) 1056 { 1057 score += 8; 1058 if (wr == 2 && rwrook == 7) 1059 { 1060 score += 10; 1061 } 1062 1063 } 1064 1065 /* give bonuses depending on how open the rook's file is: */ 1066 if (!pawns[1][pawn_file]) { 1067 /* half open file */ 1068 score += 5; 1069 1070 if (wr == 2 && file(i) == fwrook) 1071 { 1072 score += 12; 1073 } 1074 1075 if (!pawns[0][pawn_file]) { 1076 /* open file */ 1077 score += 3; 1078 } 1079 } 1080 1081 break; 1082 1083 case (brook): 1084 score -= 500; 1085 br++; 1086 if (br == 1) 1087 { 1088 fbrook = file(i); 1089 rbrook = rank(i); 1090 } 1091 1092 score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)), 1093 abs(file(i) - file(wking_loc)))]; 1094 1095 /* bonus for being on the 7th: */ 1096 if (srank == 2) 1097 { 1098 score -= 8; 1099 if (wr == 2 && rbrook == 2) 1100 { 1101 score -= 10; 1102 } 1103 } 1104 1105 /* give bonuses depending on how open the rook's file is: */ 1106 if (!pawns[0][pawn_file]) { 1107 /* half open file */ 1108 score -= 5; 1109 1110 if (br == 2 && file(i) == fbrook) 1111 { 1112 score -= 12; 1113 } 1114 1115 if (!pawns[1][pawn_file]) { 1116 /* open file */ 1117 score -= 3; 1118 } 1119 } 1120 1121 break; 1122 1123 case (wbishop): 1124 score += 325; 1125 score += sbishop[i]; 1126 wb++; 1127 score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)), 1128 abs(file(i) - file(bking_loc)))]; 1129 score += bishop_mobility(i); 1130 break; 1131 1132 case (bbishop): 1133 score -= 325; 1134 score -= sbishop[i]; 1135 bb++; 1136 score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)), 1137 abs(file(i) - file(wking_loc)))]; 1138 score -= bishop_mobility(i); 1139 break; 1140 1141 case (wknight): 1142 score += 310; 1143 score += sknight[i]; 1144 wn++; 1145 score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)), 1146 abs(file(i) - file(bking_loc)))]; 1147 break; 1148 1149 case (bknight): 1150 score -= 310; 1151 score -= sknight[i]; 1152 bn++; 1153 score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)), 1154 abs(file(i) - file(wking_loc)))]; 1155 break; 1156 1157 case (wqueen): 1158 score += 900; 1159 wq++; 1160 score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)), 1161 abs(file(i) - file(bking_loc)))]; 1162 break; 1163 1164 case (bqueen): 1165 score -= 900; 1166 bq++; 1167 score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)), 1168 abs(file(i) - file(wking_loc)))]; 1169 break; 1170 1171 case (wking): 1172 score += swhite_king[i]; 1173 1174 /* encourage castling, and give a penalty for moving the king without 1175 castling */ 1176 if (white_castled == wcq) 1177 score += 15; 1178 else if (white_castled == wck) 1179 score += 25; 1180 else if (moved[30]) { 1181 score -= 10; 1182 /* make the penalty bigger if the king is open, leaving the other 1183 side a chance to gain tempo with files along the file, as well 1184 as building an attack: */ 1185 if (!pawns[1][pawn_file]) 1186 score -= 15; 1187 } 1188 1189 /* if the king is behind some pawn cover, give penalties for the pawn 1190 cover being far from the king, else give a penalty for the king 1191 not having any pawn cover: */ 1192 if (file(wking_loc) != 4 && file(wking_loc) != 5) 1193 { 1194 if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file]) 1195 score -= 9*(white_back_pawn[pawn_file]-srank-1); 1196 else 1197 score -= 22; 1198 if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1]) 1199 score -= 8*(white_back_pawn[pawn_file+1]-srank-1); 1200 else 1201 score -= 16; 1202 if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1]) 1203 score -= 8*(white_back_pawn[pawn_file-1]-srank-1); 1204 else 1205 score -= 16; 1206 } 1207 else 1208 { 1209 /* being in center isnt great either, so correct */ 1210 score -= 10; 1211 } 1212 break; 1213 1214 case (bking): 1215 score -= sblack_king[i]; 1216 1217 /* encourage castling, and give a penalty for moving the king without 1218 castling */ 1219 if (black_castled == bcq) 1220 score -= 15; 1221 else if (black_castled == bck) 1222 score -= 25; 1223 else if (moved[114]) { 1224 score += 10; 1225 /* make the penalty bigger if the king is open, leaving the other 1226 side a chance to gain tempo with files along the file, as well 1227 as building an attack: */ 1228 if (!pawns[0][pawn_file]) 1229 score += 15; 1230 } 1231 1232 /* if the king is behind some pawn cover, give penalties for the pawn 1233 cover being far from the king, else give a penalty for the king 1234 not having any pawn cover: */ 1235 if (file(bking_loc) != 4 && file(bking_loc) != 5) 1236 { 1237 if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file]) 1238 score += 9*(srev_rank[srank-black_back_pawn[pawn_file]-1]); 1239 else 1240 score += 22; 1241 if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1]) 1242 score += 8*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]); 1243 else 1244 score += 16; 1245 if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1]) 1246 score += 8*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]); 1247 else 1248 score += 16; 1249 } 1250 else 1251 { 1252 score += 10; 1253 } 1254 break; 1255 } 1256 } 1257 1258 /* give penalties for blocking the e/d pawns: */ 1259 if (!moved[41] && board[53] != npiece) 1260 score -= 5; 1261 if (!moved[42] && board[54] != npiece) 1262 score -= 5; 1263 if (!moved[101] && board[89] != npiece) 1264 score += 5; 1265 if (!moved[102] && board[90] != npiece) 1266 score += 5; 1267 1268 /* to be used for pawn storm code: */ 1269 wking_pawn_file = file (wking_loc)+1; 1270 bking_pawn_file = file (bking_loc)+1; 1271 1272 /* if the kings are on opposite wings, or far apart, check for pawn 1273 storms, and open lines for heavy pieces: */ 1274 if (abs(wking_pawn_file-bking_pawn_file) > 2) { 1275 /* black pawn storms: */ 1276 score -= 3*(srev_rank[black_back_pawn[wking_pawn_file]]-2); 1277 score -= 3*(srev_rank[black_back_pawn[wking_pawn_file+1]]-2); 1278 score -= 3*(srev_rank[black_back_pawn[wking_pawn_file-1]]-2); 1279 1280 /* white pawn storms: */ 1281 /* this has side effects on no pawns, but I guess 1282 it wont hurt - GCP */ 1283 score += 3*(white_back_pawn[bking_pawn_file]-2); 1284 score += 3*(white_back_pawn[bking_pawn_file+1]-2); 1285 score += 3*(white_back_pawn[bking_pawn_file-1]-2); 1286 1287 /* black opening up lines: */ 1288 if (!pawns[0][wking_pawn_file]) 1289 score -= 8; 1290 if (!pawns[0][wking_pawn_file+1]) 1291 score -= 6; 1292 if (!pawns[0][wking_pawn_file-1]) 1293 score -= 6; 1294 1295 /* white opening up lines: */ 1296 if (!pawns[1][bking_pawn_file]) 1297 score += 8; 1298 if (!pawns[1][bking_pawn_file+1]) 1299 score += 6; 1300 if (!pawns[1][bking_pawn_file-1]) 1301 score += 6; 1302 1303 } 1304 1305 /* bad trade code, largely based on Crafty's */ 1306 1307 /* minors are not equal */ 1308 if ((wn + wb) != (bn + bb)) 1309 { 1310 /* majors are equal */ 1311 if ((wq + wr) == (bq + br)) 1312 { 1313 if ((wn + wb) > (bn + bb)) 1314 { 1315 /* white is a piece up */ 1316 score += 120; 1317 } 1318 else 1319 { 1320 /* black is a piece up */ 1321 score -= 120; 1322 } 1323 } 1324 else if (abs((wr + wq) - (br + bq)) == 1) 1325 { 1326 /* one major difference */ 1327 1328 if ((wb + wn) > (bb + bn + 1)) 1329 { 1330 /* two minors for one major */ 1331 score += 120; 1332 } 1333 else if ((bb + bn) > (wb + wn + 1)) 1334 { 1335 score -= 120; 1336 } 1337 } 1338 else if (abs((wr + wq) - (br + bq)) == 2) 1339 { 1340 /* two majors difference */ 1341 1342 if ((wb + wn) > (bb + bn + 2)) 1343 { 1344 /* three minors for two majors */ 1345 score += 120; 1346 } 1347 else if ((bb + bn) > (wb + wn + 2)) 1348 { 1349 score -= 120; 1350 } 1351 1352 } 1353 } 1354 else if ((wq + wr) == (bq + br)) 1355 { 1356 if (wq && !bq) 1357 { 1358 score += 120; 1359 } 1360 else if (!wq && bq) 1361 { 1362 score -= 120; 1363 } 1364 } 1365 1366 storeECache(score); 1367 1368 /* adjust for color: */ 1369 if (white_to_move == 1) { 1370 return score; 1371 } 1372 else { 1373 return -score; 1374 } 1375 1376} 1377 1378int32_t opn_eval (void) { 1379 1380 /* return a score for the current opening position: */ 1381 1382 int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11], 1383 srank, wking_pawn_file, bking_pawn_file, j; 1384 int32_t score = 0; 1385 bool isolated, backwards; 1386 int in_cache; 1387 int fwrook = 0, fbrook = 0; 1388 1389 in_cache = 0; 1390 1391 checkECache(&score, &in_cache); 1392 1393 if(in_cache) 1394 { 1395 if (white_to_move == 1) return score; 1396 return -score; 1397 } 1398 1399 /* initialize the pawns array, (files offset by one to use dummy files in 1400 order to easier determine isolated status) and also initialize the 1401 arrays keeping track of the rank of the most backward pawn: */ 1402 memset (pawns, 0, sizeof (pawns)); 1403 for (i = 0; i < 11; i++) { 1404 white_back_pawn[i] = 7; 1405 black_back_pawn[i] = 2; 1406 } 1407 for (j = 1, a = 1; (a <= piece_count); j++) { 1408 i = pieces[j]; 1409 1410 if (!i) 1411 continue; 1412 else 1413 a++; 1414 1415 if (board[i] == wpawn) { 1416 pawn_file = file (i)+1; 1417 srank = rank (i); 1418 1419 pawns[1][pawn_file]++; 1420 if (srank < white_back_pawn[pawn_file]) { 1421 white_back_pawn[pawn_file] = srank; 1422 } 1423 } 1424 else if (board[i] == bpawn) { 1425 pawn_file = file (i)+1; 1426 srank = rank (i); 1427 1428 pawns[0][pawn_file]++; 1429 if (srank > black_back_pawn[pawn_file]) { 1430 black_back_pawn[pawn_file] = srank; 1431 } 1432 } 1433 } 1434 1435 /* loop through the board, adding material value, as well as positional 1436 bonuses for all pieces encountered: */ 1437 for (j = 1, a = 1; (a <= piece_count); j++) { 1438 i = pieces[j]; 1439 1440 if (!i) 1441 continue; 1442 else 1443 a++; 1444 1445 assert((i > 0) && (i < 145)); 1446 1447 pawn_file = file (i)+1; 1448 srank = rank (i); 1449 switch (board[i]) { 1450 case (wpawn): 1451 isolated = FALSE; 1452 backwards = FALSE; 1453 score += 100; 1454 score += swhite_pawn[i]; 1455 1456 /* penalties / bonuses will be in general smaller in the opening, 1457 in order to put an emphasis on piece development */ 1458 1459 /* check for backwards pawns: */ 1460 if (white_back_pawn[pawn_file+1] > srank 1461 && white_back_pawn[pawn_file-1] > srank) { 1462 /* no penalty in the opening for having a backwards pawn that hasn't 1463 moved yet! */ 1464 if (srank != 2) 1465 score -= 3; 1466 backwards = TRUE; 1467 /* check to see if it is furthermore isolated: */ 1468 if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) { 1469 score -= 2; 1470 isolated = TRUE; 1471 } 1472 } 1473 1474 /* give weak, exposed pawns a penalty: */ 1475 if (!pawns[0][pawn_file]) { 1476 if (backwards) score -= 3; 1477 if (isolated) score -= 5; 1478 } 1479 1480 /* give doubled, trippled, etc.. pawns a penalty: */ 1481 if (pawns[1][pawn_file] > 1) 1482 score -= 2*(pawns[1][pawn_file]-1); 1483 1484 /* give bonuses for passed pawns: */ 1485 if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] && 1486 srank >= black_back_pawn[pawn_file+1]) { 1487 score += 5 + 2*swhite_pawn[i]; 1488 /* give an extra bonus if a connected, passed pawn: */ 1489 if (!isolated) 1490 score += 10; 1491 } 1492 1493 break; 1494 1495 case (bpawn): 1496 isolated = FALSE; 1497 backwards = FALSE; 1498 score -= 100; 1499 score -= sblack_pawn[i]; 1500 1501 /* penalties / bonuses will be in general smaller in the opening, 1502 in order to put an emphasis on piece development */ 1503 1504 /* check for backwards pawns: */ 1505 if (black_back_pawn[pawn_file+1] < srank 1506 && black_back_pawn[pawn_file-1] < srank) { 1507 /* no penalty in the opening for having a backwards pawn that hasn't 1508 moved yet! */ 1509 if (srank != 2) 1510 score += 3; 1511 backwards = TRUE; 1512 /* check to see if it is furthermore isolated: */ 1513 if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) { 1514 score += 2; 1515 isolated = TRUE; 1516 } 1517 } 1518 1519 /* give weak, exposed pawns a penalty: */ 1520 if (!pawns[1][pawn_file]) { 1521 if (backwards) score += 3; 1522 if (isolated) score += 5; 1523 } 1524 1525 /* give doubled, trippled, etc.. pawns a penalty: */ 1526 if (pawns[0][pawn_file] > 1) 1527 score += 2*(pawns[0][pawn_file]-1); 1528 1529 /* give bonuses for passed pawns: */ 1530 if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] && 1531 srank <= white_back_pawn[pawn_file+1]) { 1532 score -= 5 + 2*sblack_pawn[i]; 1533 /* give an extra bonus if a connected, passed pawn: */ 1534 if (!isolated) 1535 score -= 10; 1536 } 1537 1538 break; 1539 1540 case (wrook): 1541 score += 500; 1542 1543 if (!fwrook) fwrook = file(i); 1544 else if (file(i) == fwrook) 1545 { 1546 /* two rooks, file at least halfopen */ 1547 if (!pawns[1][pawn_file]) 1548 score += 10; 1549 } 1550 1551 /* bonus for being on the 7th: */ 1552 if (srank == 7) 1553 score += 8; 1554 1555 /* give bonuses depending on how open the rook's file is: */ 1556 if (!pawns[1][pawn_file]) { 1557 /* half open file */ 1558 score += 5; 1559 if (!pawns[0][pawn_file]) { 1560 /* open file */ 1561 score += 3; 1562 } 1563 } 1564 1565 break; 1566 1567 case (brook): 1568 score -= 500; 1569 1570 if (!fbrook) fbrook = file(i); 1571 else if (file(i) == fbrook) 1572 { 1573 /* two rooks, file at least halfopen */ 1574 if (!pawns[0][pawn_file]) 1575 score -= 10; 1576 } 1577 1578 /* bonus for being on the 7th: */ 1579 if (srank == 2) 1580 score -= 8; 1581 1582 /* give bonuses depending on how open the rook's file is: */ 1583 if (!pawns[0][pawn_file]) { 1584 /* half open file */ 1585 score -= 5; 1586 if (!pawns[1][pawn_file]) { 1587 /* open file */ 1588 score -= 3; 1589 } 1590 } 1591 1592 break; 1593 1594 case (wbishop): 1595 score += 325; 1596 score += sbishop[i]; 1597 score += std_b_tropism[max(abs(rank(i) - rank(bking_loc)), 1598 abs(file(i) - file(bking_loc)))]; 1599 score += bishop_mobility(i); 1600 break; 1601 1602 case (bbishop): 1603 score -= 325; 1604 score -= sbishop[i]; 1605 score -= std_b_tropism[max(abs(rank(i) - rank(wking_loc)), 1606 abs(file(i) - file(wking_loc)))]; 1607 score -= bishop_mobility(i); 1608 break; 1609 1610 case (wknight): 1611 score += 310; 1612 score += sknight[i]; 1613 score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)), 1614 abs(file(i) - file(bking_loc)))]; 1615 break; 1616 1617 case (bknight): 1618 score -= 310; 1619 score -= sknight[i]; 1620 score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)), 1621 abs(file(i) - file(wking_loc)))]; 1622 break; 1623 1624 case (wqueen): 1625 score += 900; 1626 1627 score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)), 1628 abs(file(i) - file(bking_loc)))]; 1629 1630 /* a small penalty to discourage moving the queen in the opening 1631 before the other minors: */ 1632 if (i != 29) 1633 if (!moved[28] || !moved[27] || !moved[31] || !moved[32]) 1634 score -= 10; 1635 1636 break; 1637 1638 case (bqueen): 1639 score -= 900; 1640 1641 score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)), 1642 abs(file(i) - file(wking_loc)))]; 1643 1644 /* a small penalty to discourage moving the queen in the opening 1645 before the other minors: */ 1646 if (i != 113) 1647 if (!moved[112] || !moved[111] || !moved[115] || !moved[116]) 1648 score += 10; 1649 1650 break; 1651 1652 case (wking): 1653 score += swhite_king[i]; 1654 1655 /* encourage castling, and give a penalty for moving the king without 1656 castling */ 1657 if (white_castled == wcq) 1658 score += 12; 1659 else if (white_castled == wck) 1660 score += 20; 1661 else if (moved[30]) { 1662 score -= 15; 1663 /* make the penalty bigger if the king is open, leaving the other 1664 side a chance to gain tempo with files along the file, as well 1665 as building an attack: */ 1666 if (!pawns[1][pawn_file]) 1667 score -= 10; 1668 } 1669 1670 /* in general, in the opening, don't worry quite so much about pawn 1671 cover, because sometimes it isn't good for the king to castle */ 1672 1673 /* if the king is behind some pawn cover, give penalties for the pawn 1674 cover being far from the king, else give a penalty for the king 1675 not having any pawn cover: */ 1676 /* only worry about cover when castled */ 1677 if (file(wking_loc) != 4 && file(wking_loc) != 5) 1678 { 1679 if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file]) 1680 score -= 7*(white_back_pawn[pawn_file]-srank-1); 1681 else 1682 score -= 14; 1683 if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1]) 1684 score -= 4*(white_back_pawn[pawn_file+1]-srank-1); 1685 else 1686 score -= 8; 1687 if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1]) 1688 score -= 4*(white_back_pawn[pawn_file-1]-srank-1); 1689 else 1690 score -= 8; 1691 } 1692 else 1693 { 1694 score -= 7; 1695 } 1696 1697 break; 1698 1699 case (bking): 1700 score -= sblack_king[i]; 1701 1702 /* encourage castling, and give a penalty for moving the king without 1703 castling */ 1704 if (black_castled == bcq) 1705 score -= 12; 1706 else if (black_castled == bck) 1707 score -= 20; 1708 else if (moved[114]) { 1709 score += 15; 1710 /* make the penalty bigger if the king is open, leaving the other 1711 side a chance to gain tempo with files along the file, as well 1712 as building an attack: */ 1713 if (!pawns[0][pawn_file]) 1714 score += 10; 1715 } 1716 1717 /* in general, in the opening, don't worry quite so much about pawn 1718 cover, because sometimes it isn't good for the king to castle */ 1719 1720 /* if the king is behind some pawn cover, give penalties for the pawn 1721 cover being far from the king, else give a penalty for the king 1722 not having any pawn cover: */ 1723 if (file(bking_loc) != 4 && file(bking_loc) != 5) 1724 { 1725 if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file]) 1726 score += 7*(srev_rank[srank-black_back_pawn[pawn_file]-1]); 1727 else 1728 score += 14; 1729 if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1]) 1730 score += 4*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]); 1731 else 1732 score += 8; 1733 if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1]) 1734 score += 4*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]); 1735 else 1736 score += 8; 1737 } 1738 else 1739 { 1740 score += 7; 1741 } 1742 1743 break; 1744 } 1745 } 1746 1747 /* give bigger penalties for blocking the e/d pawns in the opening, as 1748 we want to develop quickly: */ 1749 if (!moved[41] && board[53] != npiece) 1750 score -= 7; 1751 if (!moved[42] && board[54] != npiece) 1752 score -= 7; 1753 if (!moved[101] && board[89] != npiece) 1754 score += 7; 1755 if (!moved[102] && board[90] != npiece) 1756 score += 7; 1757 1758 /* to be used for pawn storm code: */ 1759 wking_pawn_file = file[wking_loc]+1; 1760 bking_pawn_file = file[bking_loc]+1; 1761 1762 /* if the kings are on opposite wings, or far apart, check for pawn 1763 storms, and open lines for heavy pieces (bonuses/penalties brought 1764 down a bit in the opening, as it isn't a good idea to start pawn 1765 storming when the position is still fluid): */ 1766 if (abs(bking_pawn_file-wking_pawn_file) > 2) { 1767 /* black pawn storms: */ 1768 score -= srev_rank[black_back_pawn[wking_pawn_file]] - 2; 1769 score -= srev_rank[black_back_pawn[wking_pawn_file+1]] - 2; 1770 score -= srev_rank[black_back_pawn[wking_pawn_file-1]] - 2; 1771 1772 /* white pawn storms: */ 1773 score += white_back_pawn[bking_pawn_file] - 2; 1774 score += white_back_pawn[bking_pawn_file+1] - 2; 1775 score += white_back_pawn[bking_pawn_file-1] - 2; 1776 1777 /* black opening up lines: */ 1778 if (!pawns[0][wking_pawn_file]) 1779 score -= 6; 1780 if (!pawns[0][wking_pawn_file+1]) 1781 score -= 4; 1782 if (!pawns[0][wking_pawn_file-1]) 1783 score -= 4; 1784 1785 /* white opening up lines: */ 1786 if (!pawns[1][bking_pawn_file]) 1787 score += 6; 1788 if (!pawns[1][bking_pawn_file+1]) 1789 score += 4; 1790 if (!pawns[1][bking_pawn_file-1]) 1791 score += 4; 1792 1793 } 1794 1795 storeECache(score); 1796 1797 /* adjust for color: */ 1798 if (white_to_move == 1) { 1799 return score; 1800 } 1801 else { 1802 return -score; 1803 } 1804 1805} 1806