home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Jeux / Reflexion / Crafty-15.19.lha / crafty-15.19 / src / evaluate.c < prev    next >
C/C++ Source or Header  |  1998-09-13  |  121KB  |  2,899 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "chess.h"
  4. #include "evaluate.h"
  5. #include "data.h"
  6.  
  7. /* last modified 09/06/98 */
  8. /*
  9. ********************************************************************************
  10. *                                                                              *
  11. *   Evaluate() is used to evaluate the chess board.  broadly, it addresses     *
  12. *   four (4) distinct areas:  (1) material score which is simply a summing of  *
  13. *   piece types multiplied by piece values;  (2) pawn scoring which considers  *
  14. *   placement of pawns and also evaluates passed pawns, particularly in end-   *
  15. *   game situations;  (3) piece scoring which evaluates the placement of each  *
  16. *   piece as well as things like piece mobility;  (4) king safety which        *
  17. *   considers the pawn shelter around the king along with material present to  *
  18. *   facilitate an attack.                                                      *
  19. *                                                                              *
  20. ********************************************************************************
  21. */
  22.  
  23. int Evaluate(TREE *tree, int ply, int wtm, int alpha, int beta) {
  24.   register BITBOARD temp;
  25.   register int square, file, score, tscore;
  26.   register int drawn_ending=0;
  27. #if defined(DEBUGEV)
  28.   int lastsc=Material;
  29. #endif
  30. /*
  31.  ----------------------------------------------------------
  32. |                                                          |
  33. |   check for draws due to insufficient material and       |
  34. |   adjust the score as necessary.                         |
  35. |                                                          |
  36.  ----------------------------------------------------------
  37. */
  38.   if (TotalWhitePieces<5 && TotalBlackPieces<5)
  39.     drawn_ending=EvaluateDraws(tree);
  40.   if (drawn_ending > 0) return(DrawScore(root_wtm==wtm));
  41.   score=Material;
  42. #ifdef DEBUGEV
  43.   printf("score[material]=                  %4d\n",score);
  44. #endif
  45. /*
  46.  ----------------------------------------------------------
  47. |                                                          |
  48. |   check for bad trades, which includes a queen for 3     |
  49. |   minor pieces and a rook for two minor pieces.          |
  50. |                                                          |
  51.  ----------------------------------------------------------
  52. */
  53.   if (WhiteMinors != BlackMinors) {
  54.     if (WhiteMajors == BlackMajors) {
  55.       if (WhiteMinors > BlackMinors) score+=BAD_TRADE;
  56.       else  score-=BAD_TRADE;
  57.     }
  58.     else {
  59.       if (WhiteMinors > BlackMinors+1) score+=BAD_TRADE;
  60.       else if (BlackMinors > WhiteMinors+1) score-=BAD_TRADE;
  61.     }
  62.   }
  63. #ifdef DEBUGEV
  64.   if (score != lastsc)
  65.   printf("score[bad trade]=                 %4d\n",score);
  66.   lastsc=score;
  67. #endif
  68. /*
  69. **********************************************************************
  70. *                                                                    *
  71. *   determine if this is position should be evaluated to force mate  *
  72. *   (neither side has pawns) or if it should be evaluated normally.  *
  73. *   call EvaluatePawns() to evaluate the current pawn position.      *
  74. *   this routine modifies the "passed" pawn bit-vector which         *
  75. *   indicates whether a pawn on each file is passed or not.          *
  76. *                                                                    *
  77. **********************************************************************
  78. */
  79.   tree->all_pawns=Or(BlackPawns,WhitePawns);
  80.   if ((TotalWhitePawns+TotalBlackPawns) == 0) {
  81.     score+=EvaluateMate(tree);
  82. #ifdef DEBUGEV
  83.     printf("score[mater]=                     %4d\n",score);
  84. #endif
  85.     tree->pawn_score.p_score=0;
  86.     tree->pawn_score.passed_w=0;
  87.     tree->pawn_score.passed_b=0;
  88.     tree->pawn_score.weak_w=0;
  89.     tree->pawn_score.weak_b=0;
  90.     tree->pawn_score.white_pof=0;
  91.     tree->pawn_score.black_pof=0;
  92.     tree->pawn_score.black_protected=0;
  93.     tree->pawn_score.white_protected=0;
  94.     tree->pawn_score.white_defects_k=0;
  95.     tree->pawn_score.white_defects_q=0;
  96.     tree->pawn_score.black_defects_k=0;
  97.     tree->pawn_score.black_defects_q=0;
  98.     tree->pawn_score.outside=0;
  99.   }
  100.   else {
  101. #if !defined(FAST)
  102.     tree->pawn_probes++;
  103. #endif
  104.     if (PawnHashKey == tree->pawn_score.key) {
  105. #if !defined(FAST)
  106.       tree->pawn_hits++;
  107. #endif
  108.       score+=tree->pawn_score.p_score;
  109.     }
  110.     else score+=EvaluatePawns(tree);
  111. #ifdef DEBUGEV
  112.     if (score != lastsc)
  113.       printf("score[pawns]=                     %4d\n",score);
  114.     lastsc=score;
  115. #endif
  116.   }
  117. /*
  118. **********************************************************************
  119. *                                                                    *
  120. *   if there are any passed pawns, first call EvaluatePassedPawns()  *
  121. *   to evaluate them.  then, if one side has a passed pawn and the   *
  122. *   other side has no pieces, call EvaluatePassedPawnRaces() to see  *
  123. *   if the passed pawn can be stopped from promoting.  finally, we   *
  124. *   use tree->pawn_score.outside to see if one side has an outside   *
  125. *   passed pawn that represents a nearly won endgame advantage.      *
  126. *                                                                    *
  127. **********************************************************************
  128. */
  129.   if (tree->pawn_score.passed_b || tree->pawn_score.passed_w) {
  130.     score+=EvaluatePassedPawns(tree);
  131.     if (tree->pawn_score.outside&1)
  132.       score+=outside_passed[(int) TotalBlackPieces];
  133.     if (tree->pawn_score.outside&2)
  134.       score-=outside_passed[(int) TotalWhitePieces];
  135.     if ((TotalWhitePieces==0 && tree->pawn_score.passed_b) ||
  136.         (TotalBlackPieces==0 && tree->pawn_score.passed_w))
  137.       score+=EvaluatePassedPawnRaces(tree,wtm);
  138. #ifdef DEBUGEV
  139.     if (score != lastsc)
  140.       printf("score[passed pawns]=              %4d\n",score);
  141.     lastsc=score;
  142. #endif
  143.   }
  144. /*
  145. **********************************************************************
  146. *                                                                    *
  147. *   trade bonus.  this follows the classic rule, if ahead in         *
  148. *   material, trade pieces but not pawns.  if behind in material,    *
  149. *   trade pawns but not pieces.  this is handled carefully, however, *
  150. *   in that trading down to a single rook or minor piece is not con- *
  151. *   sidered a good idea as the positions are more drawish, while     *
  152. *   eliminating all pieces is generally a good idea for the side     *
  153. *   that is ahead...                                                 *
  154. *                                                                    *
  155. **********************************************************************
  156. */
  157.   if (Material >= PAWN_VALUE) {
  158.     if (TotalBlackPieces < 20) {
  159.       if (!root_wtm || Material >= PAWN_VALUE*2)
  160.         score+=(20-TotalBlackPieces)*TRADE_PIECES;
  161.     }
  162.   }
  163.   else if (Material <= -PAWN_VALUE) {
  164.     if (TotalWhitePieces < 20) {
  165.       if (root_wtm || Material <= -PAWN_VALUE*2)
  166.         score-=(20-TotalWhitePieces)*TRADE_PIECES;
  167.     }
  168.   }
  169. #ifdef DEBUGEV
  170.   if (score != lastsc)
  171.   printf("score[trades]=                    %4d\n",score);
  172.   lastsc=score;
  173. #endif
  174. /*
  175.  ----------------------------------------------------------
  176. |                                                          |
  177. |   check to see if the bishop is trapped at a2 or h2 with |
  178. |   a pawn at b2 or g2 that can advance one square and     |
  179. |   trap the bishop, or a pawn at b3 or g3 that has        |
  180. |   trapped the bishop already.  also make sure that this  |
  181. |   pawn is defended to close the trap.                    |
  182. |                                                          |
  183.  ----------------------------------------------------------
  184. */
  185.   if (WhiteBishops) {
  186.     temp=And(WhiteBishops,mask_A7H7);
  187.     while(temp) {
  188.       square=FirstOne(temp);
  189.       if (square==A7 && And(mask_B6B7,BlackPawns)) {
  190.         if (And(set_mask[B6],BlackPawns) || Swap(tree,B7,B6,0)>=0)
  191.           score-=BISHOP_TRAPPED;
  192.       }
  193.       else if (square==H7 &&And(mask_G6G7,BlackPawns)) {
  194.         if (And(set_mask[G6],BlackPawns) || Swap(tree,G7,G6,0)>=0)
  195.           score-=BISHOP_TRAPPED;
  196.       }
  197.       Clear(square,temp);
  198.     }
  199.   }
  200.   if (BlackBishops) {
  201.     temp=And(BlackBishops,mask_A2H2);
  202.     while(temp) {
  203.       square=FirstOne(temp);
  204.       if (square==A2 &&And(mask_B2B3,WhitePawns)) {
  205.         if (And(set_mask[B3],WhitePawns) || Swap(tree,B2,B3,1)>=0)
  206.           score+=BISHOP_TRAPPED;
  207.       }
  208.       else if (square==H2 && And(mask_G2G3,WhitePawns)) {
  209.         if (And(set_mask[G3],WhitePawns) || Swap(tree,G2,G3,1)>=0)
  210.           score+=BISHOP_TRAPPED;
  211.       }
  212.       Clear(square,temp);
  213.     }
  214.   }
  215. /*
  216. **********************************************************************
  217. *                                                                    *
  218. *   call EvaluateDevelopment() to evaluate development.  if the      *
  219. *   flag "opening" is zero, skip the call.                           *
  220. *                                                                    *
  221. **********************************************************************
  222. */
  223.   if (opening) score+=EvaluateDevelopment(tree,ply);
  224. #ifdef DEBUGEV
  225.   if (score != lastsc)
  226.   printf("score[development]=               %4d\n",score);
  227.   lastsc=score;
  228. #endif
  229. /*
  230. **********************************************************************
  231. *                                                                    *
  232. *   now evaluate king safety by analyzing the pawn shelter in front  *
  233. *   of the king to determine if there are holes, open files or other *
  234. *   weaknesses that will make an attack difficult to repel.  one     *
  235. *   special case is to detect the presence of a bishop that protects *
  236. *   squares left after the b/g pawn has been advanced, leaving holes *
  237. *   around the king, and pawns/bishops and queen threatening on g2   *
  238. *   and related squares.                                             *
  239. *                                                                    *
  240. **********************************************************************
  241. */
  242.   score+=EvaluateKingSafety(tree,ply);
  243. #ifdef DEBUGEV
  244.   if (score != lastsc)
  245.   printf("score[king safety]=               %4d\n",score);
  246.   lastsc=score;
  247. #endif
  248. /*
  249. **********************************************************************
  250. *                                                                    *
  251. *  check to see if we can take a lazy exit and avoid the time-       *
  252. *  consuming part of the evaluation code.                            *
  253. *                                                                    *
  254. **********************************************************************
  255. */
  256.   if (drawn_ending == 0) {
  257.     register int tscore=(wtm)?score:-score;
  258.     if (tscore-largest_positional_score>= beta) return(beta);
  259.     if (tscore+largest_positional_score<= alpha) return(alpha);
  260.   }
  261.   tscore=score;
  262.   tree->evaluations++;
  263. /*
  264. **********************************************************************
  265. *                                                                    *
  266. *  now evaluate the kings.  these tests are done dynamically, since  *
  267. *  they depend on various pieces that can't be hashed in the king    *
  268. *  safety defect counts kept in the pawn hash table.                 *
  269. *                                                                    *
  270. **********************************************************************
  271. */
  272. /*
  273.  ----------------------------------------------------------
  274. |                                                          |
  275. |   white king.                                            |
  276. |                                                          |
  277. |   first, check for a weak back rank.                     |
  278. |                                                          |
  279.  ----------------------------------------------------------
  280. */
  281.   if (TotalBlackPieces < 14) score+=king_value_w[WhiteKingSQ];
  282.   if (WhiteKingSQ < A2) {
  283.     if (!And(And(king_attacks[WhiteKingSQ],rank_mask[RANK2]),
  284.              Compl(WhitePawns))) score-=KING_BACK_RANK;
  285. /*
  286.  ----------------------------------------------------------
  287. |                                                          |
  288. |   check to see if the king has been forced to move and   |
  289. |   has trapped a rook at a1/a2/b1/g1/h1/h2, if so, then   |
  290. |   penalize the trapped rook to help extricate it.        |
  291. |                                                          |
  292.  ----------------------------------------------------------
  293. */
  294.     if (WhiteKingSQ>FILEE) {
  295.       if (And(WhiteRooks,mask_kr_trapped_w[FILEH-WhiteKingSQ])) 
  296.         score-=ROOK_TRAPPED;
  297.     }
  298.     else if (WhiteKingSQ<FILED) {
  299.       if (And(WhiteRooks,mask_qr_trapped_w[WhiteKingSQ]))
  300.         score-=ROOK_TRAPPED;
  301.     }
  302.   }
  303. #ifdef DEBUGEV
  304.   if (score != lastsc)
  305.   printf("score[kings(white)]=              %4d\n",score);
  306.   lastsc=score;
  307. #endif
  308.  
  309. /*
  310.  ----------------------------------------------------------
  311. |                                                          |
  312. |   black king.                                            |
  313. |                                                          |
  314. |   first, check for a weak back rank.                     |
  315. |                                                          |
  316.  ----------------------------------------------------------
  317. */
  318.   if (TotalWhitePieces < 14) score-=king_value_b[BlackKingSQ];
  319.   if (BlackKingSQ > H7) {
  320.     if (!And(And(king_attacks[BlackKingSQ],rank_mask[RANK7]),
  321.              Compl(BlackPawns))) score+=KING_BACK_RANK;
  322. /*
  323.  ----------------------------------------------------------
  324. |                                                          |
  325. |   check to see if the king has been forced to move and   |
  326. |   has trapped a rook at a1/a2/b1/g1/h1/h2, if so, then   |
  327. |   penalize the trapped rook to help extricate it.        |
  328. |                                                          |
  329.  ----------------------------------------------------------
  330. */
  331.     if (File(BlackKingSQ) > FILEE) {
  332.       if (And(BlackRooks,mask_kr_trapped_b[FILEH-File(BlackKingSQ)]))
  333.         score+=ROOK_TRAPPED;
  334.     }
  335.     else if (File(BlackKingSQ) < FILED) {
  336.       if (And(BlackRooks,mask_qr_trapped_b[File(BlackKingSQ)]))
  337.         score+=ROOK_TRAPPED;
  338.     }
  339.   }
  340. #ifdef DEBUGEV
  341.   if (score != lastsc)
  342.   printf("score[kings(black)]=              %4d\n",score);
  343.   lastsc=score;
  344. #endif
  345.  
  346. /*
  347. **********************************************************************
  348. *                                                                    *
  349. *   knight evaluation includes centralization and "outposts".        *
  350. *                                                                    *
  351. **********************************************************************
  352. */
  353. /*
  354.  ----------------------------------------------------------
  355. |                                                          |
  356. |   white knights.                                         |
  357. |                                                          |
  358. |   first, evaluate for "outposts" which is a knight that  |
  359. |   can't be driven off by an enemy pawn, and which is     |
  360. |   supported by a friendly pawn.                          |
  361. |                                                          |
  362.  ----------------------------------------------------------
  363. */
  364.   temp=WhiteKnights;
  365.   while(temp) {
  366.     square=FirstOne(temp);
  367.     if (white_outpost[square] &&
  368.         !And(mask_no_pawn_attacks_b[square],BlackPawns)) {
  369.       score+=KNIGHT_OUTPOST*white_outpost[square];
  370.       if(And(b_pawn_attacks[square],WhitePawns)) score+=KNIGHT_OUTPOST;
  371.     }
  372. /*
  373.  ----------------------------------------------------------
  374. |                                                          |
  375. |   now fold in centralization score from the piece/square |
  376. |   table "knight_value_*" and king tropism.               |
  377. |                                                          |
  378.  ----------------------------------------------------------
  379. */
  380.     score+=knight_value_w[square];
  381.     if (knight_value_w[square] >= 0)
  382.       score+=(4-Distance(square,tree->b_kingsq))*KNIGHT_KING_TROPISM;
  383.     Clear(square,temp);
  384.   }
  385. #ifdef DEBUGEV
  386.   if (score != lastsc)
  387.   lastsc=score;
  388. #endif
  389.  
  390. /*
  391.  ----------------------------------------------------------
  392. |                                                          |
  393. |   black knights.                                         |
  394. |                                                          |
  395. |   first, evaluate for "outposts" which is a knight that  |
  396. |   can't be driven off by an enemy pawn, and which is     |
  397. |   supported by a friendly pawn.                          |
  398. |                                                          |
  399.  ----------------------------------------------------------
  400. */
  401.   temp=BlackKnights;
  402.   while(temp) {
  403.     square=FirstOne(temp);
  404.     if (black_outpost[square] &&
  405.         !And(mask_no_pawn_attacks_w[square],WhitePawns)) {
  406.       score-=KNIGHT_OUTPOST*black_outpost[square];
  407.       if (And(w_pawn_attacks[square],BlackPawns)) score-=KNIGHT_OUTPOST;
  408.     }
  409. /*
  410.  ----------------------------------------------------------
  411. |                                                          |
  412. |   now fold in centralization score from the piece/square |
  413. |   table "knight_value_*" and king tropism.               |
  414. |                                                          |
  415.  ----------------------------------------------------------
  416. */
  417.     score-=knight_value_b[square];
  418.     if (knight_value_b[square] >= 0)
  419.       score-=(4-Distance(square,tree->w_kingsq))*KNIGHT_KING_TROPISM;
  420.     if (knight_value_b[square] >= 0)
  421.     Clear(square,temp);
  422.   }
  423. #ifdef DEBUGEV
  424.   if (score != lastsc)
  425.   printf("score[knights(black)]=            %4d\n",score);
  426.   lastsc=score;
  427. #endif
  428. /*
  429. **********************************************************************
  430. *                                                                    *
  431. *   bishop evaluation includes mobility, centralization as well as   *
  432. *   a bonus for having the bishop pair.  a special case is a bishop  *
  433. *   that is fianchettoed in front of a castled king.  this bishop is *
  434. *   defending very weak squares and is therefore more valuable and   *
  435. *   should not be traded.                                            *
  436. *                                                                    *
  437. **********************************************************************
  438. */
  439. /*
  440.  ----------------------------------------------------------
  441. |                                                          |
  442. |   white bishops                                          |
  443. |                                                          |
  444. |   first, locate each bishop and add in its static score  |
  445. |   from the bishop piece/square table.                    |
  446. |                                                          |
  447.  ----------------------------------------------------------
  448. */
  449.   temp=WhiteBishops;
  450.   while(temp) {
  451.     square=FirstOne(temp);
  452.     score+=bishop_value_w[square];
  453. /*
  454.  ----------------------------------------------------------
  455. |                                                          |
  456. |   then fold in the mobility score.                       |
  457. |                                                          |
  458.  ----------------------------------------------------------
  459. */
  460.     score+=BISHOP_MOBILITY*(MobilityBishop(square)-5);
  461. /*
  462.  ----------------------------------------------------------
  463. |                                                          |
  464. |   now add in a bonus for a bishop outpost, which is      |
  465. |   similar to a knight outpost although less valuable.    |
  466. |                                                          |
  467.  ----------------------------------------------------------
  468. */
  469.     if (white_outpost[square] &&
  470.         !And(mask_no_pawn_attacks_b[square],BlackPawns)) {
  471.       score+=BISHOP_OUTPOST*white_outpost[square];
  472.     }
  473. /*
  474.  ----------------------------------------------------------
  475. |                                                          |
  476. |   add in a bonus for occupying a rank or file close to   |
  477. |   the king.                                              |
  478. |                                                          |
  479.  ----------------------------------------------------------
  480. */
  481.     score+=(4-Distance(square,tree->b_kingsq))*BISHOP_KING_TROPISM;
  482.     Clear(square,temp);
  483.   }
  484. #ifdef DEBUGEV
  485.   if (score != lastsc)
  486.     printf("score[bishops(white)]=            %4d\n",score);
  487.   lastsc=score;
  488. #endif
  489. /*
  490.  ----------------------------------------------------------
  491. |                                                          |
  492. |   black bishops                                          |
  493. |                                                          |
  494. |   first, locate each bishop and add in its static score  |
  495. |   from the bishop piece/square table.                    |
  496. |                                                          |
  497.  ----------------------------------------------------------
  498. */
  499.   temp=BlackBishops;
  500.   while(temp) {
  501.     square=FirstOne(temp);
  502.     score-=bishop_value_b[square];
  503. /*
  504.  ----------------------------------------------------------
  505. |                                                          |
  506. |   then fold in the mobility score.                       |
  507. |                                                          |
  508.  ----------------------------------------------------------
  509. */
  510.     score-=BISHOP_MOBILITY*(MobilityBishop(square)-5);
  511. /*
  512.  ----------------------------------------------------------
  513. |                                                          |
  514. |   now add in a bonus for a bishop outpost, which is      |
  515. |   similar to a knight outpost although less valuable.    |
  516. |                                                          |
  517.  ----------------------------------------------------------
  518. */
  519.     if (black_outpost[square] &&
  520.         !And(mask_no_pawn_attacks_w[square],WhitePawns)) {
  521.       score-=BISHOP_OUTPOST*black_outpost[square];
  522.     }
  523. /*
  524.  ----------------------------------------------------------
  525. |                                                          |
  526. |   add in a bonus for occupying a rank or file close to   |
  527. |   the king.                                              |
  528. |                                                          |
  529.  ----------------------------------------------------------
  530. */
  531.     score-=(4-Distance(square,tree->w_kingsq))*BISHOP_KING_TROPISM;
  532.     Clear(square,temp);
  533.   }
  534. #ifdef DEBUGEV
  535.   if (score != lastsc)
  536.     printf("score[bishops(black)]=            %4d\n",score);
  537.   lastsc=score;
  538. #endif
  539. /*
  540.  ----------------------------------------------------------
  541. |                                                          |
  542. |   now, give either side a bonus for having two bishops.  |
  543. |                                                          |
  544.  ----------------------------------------------------------
  545. */
  546.   if (And(WhiteBishops,WhiteBishops-1)) score+=BISHOP_PAIR;
  547.   if (And(BlackBishops,BlackBishops-1)) score-=BISHOP_PAIR;
  548. #ifdef DEBUGEV
  549.   if (score != lastsc)
  550.   printf("score[bishop pair]=               %4d\n",score);
  551.   lastsc=score;
  552. #endif
  553. /*
  554. **********************************************************************
  555. *                                                                    *
  556. *   rook evaluation includes several simple cases, including open    *
  557. *   files, 7th rank, connected, etc.                                 *
  558. *                                                                    *
  559. **********************************************************************
  560. */
  561. /*
  562.  ----------------------------------------------------------
  563. |                                                          |
  564. |   white rooks                                            |
  565. |                                                          |
  566.  ----------------------------------------------------------
  567. */
  568.   temp=WhiteRooks;
  569.   while(temp) {
  570.     square=FirstOne(temp);
  571.     file=File(square);
  572.     score+=rook_value_w[square];
  573. /*
  574.  ----------------------------------------------------------
  575. |                                                          |
  576. |   determine if the rook is on an open file.  if it is,   |
  577. |   determine if this rook attacks another friendly rook,  |
  578. |   making it difficult to drive the rooks off the file.   |
  579. |   if the file is not open, see if it's only closed by a  |
  580. |   enemy pawn that is weak.  if so, a rook here is still  |
  581. |   strong.                                                |
  582. |                                                          |
  583. |   add in a bonus for occupying a rank or file close to   |
  584. |   the king, if there are no friendly pawns on the same   |
  585. |   file.                                                  |
  586. |                                                          |
  587.  ----------------------------------------------------------
  588. */
  589.     if (!And(file_mask[file],tree->all_pawns)) {
  590.       score+=ROOK_OPEN_FILE;
  591.       if (!end_game && FileDistance(square,tree->b_kingsq) <=1 ) score+=ROOK_OPEN_FILE;
  592.       if (And(AttacksFile(square),WhiteRooks)) score+=ROOK_CONNECTED_OPEN_FILE;
  593.     }
  594.     else if (!And(file_mask[file],WhitePawns)) {
  595.       score+=ROOK_HALF_OPEN_FILE;
  596.       if (tree->pawn_score.weak_b & (128>>file)) score+=ROOK_OPEN_FILE/2;
  597.     }
  598.     score+=(4-FileDistance(square,tree->b_kingsq))*ROOK_KING_TROPISM;
  599. /*
  600.  ----------------------------------------------------------
  601. |                                                          |
  602. |   see if the rook is behind a passed pawn.  if it is,    |
  603. |   it is counted as though the file is open.              |
  604. |                                                          |
  605.  ----------------------------------------------------------
  606. */
  607.     if (128>>file & tree->pawn_score.passed_w) {
  608.       register int pawnsq=LastOne(And(WhitePawns,file_mask[file]));
  609.       if (square<pawnsq && !And(BlackPieces,set_mask[pawnsq+8]))
  610.         score+=ROOK_BEHIND_PASSED_PAWN;
  611.       if (And(AttacksFile(square),WhiteRooks)) score-=ROOK_BEHIND_PASSED_PAWN/2;
  612.     }
  613.     if (128>>file & tree->pawn_score.passed_b) {
  614.       register int pawnsq=FirstOne(And(BlackPawns,file_mask[file]));
  615.       if (square > pawnsq) score+=ROOK_BEHIND_PASSED_PAWN;
  616.     }
  617. /*
  618.  ----------------------------------------------------------
  619. |                                                          |
  620. |   add in a bonus for weak opponent pawns that are on an  |
  621. |   open file where this rook can attack them.             |
  622. |                                                          |
  623.  ----------------------------------------------------------
  624. */
  625.     score+=tree->pawn_score.black_pof*ROOK_WEAK_PAWN;
  626. /*
  627.  ----------------------------------------------------------
  628. |                                                          |
  629. |   finally check to see if any rooks are on the 7th rank, |
  630. |   with the opponent having pawns on that rank and the    |
  631. |   opponent's king being hemmed in on the 7th/8th rank.   |
  632. |   if so, and another rook or queen is also on the 7th,   |
  633. |   then this is a *strong* positional advantage.          |
  634. |                                                          |
  635.  ----------------------------------------------------------
  636. */
  637.     if (Rank(square)==RANK7 && (BlackKingSQ>H7 ||
  638.                                 And(BlackPawns,rank_mask[RANK7]))) {
  639.       score+=ROOK_ON_7TH;
  640.       if (TotalBlackPieces <= 16) {
  641.         score+=ROOK_ON_7TH>>1;
  642.         if (tree->pawn_score.passed_w && BlackKingSQ>H7 &&
  643.             !And(BlackPieces,mask_abs7_w)) score+=ROOK_ABSOLUTE_7TH;
  644.       }
  645.       if (And(AttacksRank(square),Or(WhiteRooks,WhiteQueens)))
  646.         score+=ROOK_CONNECTED_7TH_RANK;
  647.     }
  648.     Clear(square,temp);
  649.   }
  650. #ifdef DEBUGEV
  651.   if (score != lastsc)
  652.   printf("score[rooks(white)]=              %4d\n",score);
  653.   lastsc=score;
  654. #endif
  655.  
  656. /*
  657.  ----------------------------------------------------------
  658. |                                                          |
  659. |   black rooks                                            |
  660. |                                                          |
  661.  ----------------------------------------------------------
  662. */
  663.   temp=BlackRooks;
  664.   while(temp) {
  665.     square=FirstOne(temp);
  666.     file=File(square);
  667.     score-=rook_value_b[square];
  668. /*
  669.  ----------------------------------------------------------
  670. |                                                          |
  671. |   determine if the rook is on an open file.  if it is,   |
  672. |   determine if this rook attacks another friendly rook,  |
  673. |   making it difficult to drive the rooks off the file.   |
  674. |   if the file is not open, see if it's only closed by a  |
  675. |   enemy pawn that is weak.  if so, a rook here is still  |
  676. |   strong.                                                |
  677. |                                                          |
  678. |   add in a bonus for occupying a rank or file close to   |
  679. |   the king, if there are no friendly pawns on the same   |
  680. |   file.                                                  |
  681. |                                                          |
  682.  ----------------------------------------------------------
  683. */
  684.     if (!And(file_mask[file],tree->all_pawns)) {
  685.       score-=ROOK_OPEN_FILE;
  686.       if (!end_game && FileDistance(square,tree->w_kingsq) <= 1) score-=ROOK_OPEN_FILE;
  687.       if (And(AttacksFile(square),BlackRooks)) score-=ROOK_CONNECTED_OPEN_FILE;
  688.     }
  689.     else if (!And(file_mask[file],BlackPawns)) {
  690.       score-=ROOK_HALF_OPEN_FILE;
  691.       if (tree->pawn_score.weak_w & (128>>file)) score-=ROOK_OPEN_FILE/2;
  692.     }
  693.     score-=(4-FileDistance(square,tree->w_kingsq))*ROOK_KING_TROPISM;
  694. /*
  695.  ----------------------------------------------------------
  696. |                                                          |
  697. |   if not, see if the rook is behind a passed pawn.  if   |
  698. |   it is, it is counted as though the file is open.       |
  699. |                                                          |
  700.  ----------------------------------------------------------
  701. */
  702.     if (128>>file & tree->pawn_score.passed_b) {
  703.       register int pawnsq=FirstOne(And(BlackPawns,file_mask[file]));
  704.       if (square>pawnsq && !And(WhitePieces,set_mask[pawnsq-8]))
  705.         score-=ROOK_BEHIND_PASSED_PAWN;
  706.       if (And(AttacksFile(square),BlackRooks)) score+=ROOK_BEHIND_PASSED_PAWN/2;
  707.     }
  708.     if (128>>file & tree->pawn_score.passed_w) {
  709.       register int pawnsq=LastOne(And(WhitePawns,file_mask[file]));
  710.       if (square < pawnsq) score-=ROOK_BEHIND_PASSED_PAWN;
  711.     }
  712. /*
  713.  ----------------------------------------------------------
  714. |                                                          |
  715. |   add in a bonus for weak opponent pawns that are on an  |
  716. |   open file where this rook can attack them.             |
  717. |                                                          |
  718.  ----------------------------------------------------------
  719. */
  720.     score-=tree->pawn_score.white_pof*ROOK_WEAK_PAWN;
  721. /*
  722.  ----------------------------------------------------------
  723. |                                                          |
  724. |   finally check to see if any rooks are on the 7th rank, |
  725. |   with the opponent having pawns on that rank and the    |
  726. |   opponent's king being hemmed in on the 7th/8th rank.   |
  727. |   if so, and another rook or queen is also on the 7th,   |
  728. |   then this is a *strong* positional advantage.          |
  729. |                                                          |
  730.  ----------------------------------------------------------
  731. */
  732.     if (Rank(square)==RANK2 && (WhiteKingSQ<A2 ||
  733.                                 And(WhitePawns,rank_mask[RANK2]))) {
  734.       score-=ROOK_ON_7TH;
  735.       if (TotalWhitePieces<=16) {
  736.         score-=ROOK_ON_7TH>>1;
  737.         if (tree->pawn_score.passed_b && WhiteKingSQ<A2 &&
  738.             !And(WhitePieces,mask_abs7_b)) score-=ROOK_ABSOLUTE_7TH;
  739.       }
  740.       if (And(AttacksRank(square),Or(BlackRooks,BlackQueens)))
  741.         score-=ROOK_CONNECTED_7TH_RANK;
  742.     }
  743.     Clear(square,temp);
  744.   }
  745. #ifdef DEBUGEV
  746.   if (score != lastsc)
  747.   printf("score[rooks(black)]=              %4d\n",score);
  748.   lastsc=score;
  749. #endif
  750. /*
  751. **********************************************************************
  752. *                                                                    *
  753. *   queen evaluation only includes centralization, plus a bonus if   *
  754. *   the opponent's king-side is shredded, making the queen a more    *
  755. *   dangerous piece.                                                 *
  756. *                                                                    *
  757. **********************************************************************
  758. */
  759. /*
  760.  ----------------------------------------------------------
  761. |                                                          |
  762. |   white queens                                           |
  763. |                                                          |
  764. |   first locate each queen and obtain it's centralization |
  765. |   score from the static piece/square table for queens.   |
  766. |                                                          |
  767. |   then, if the opposing side's king safety is much worse |
  768. |   than the king safety for this side, add in a bonus to  |
  769. |   keep the queen around.                                 |
  770. |                                                          |
  771.  ----------------------------------------------------------
  772. */
  773.   temp=WhiteQueens;
  774.   while(temp) {
  775.     square=FirstOne(temp);
  776.     score+=queen_value_w[square];
  777. /*
  778.  ----------------------------------------------------------
  779. |                                                          |
  780. |   check to see if the queen is in a strong positiono on  |
  781. |   the 7th rank supported by a rook on the 7th.  if so,   |
  782. |   the positional advantage is almost overwhelming.       |
  783. |                                                          |
  784.  ----------------------------------------------------------
  785. */
  786.     if ((Rank(square) == RANK7) && (And(BlackPawns,rank_mask[RANK7]) ||
  787.          (BlackKingSQ > H7))) {
  788.       if (And(AttacksRank(square),WhiteRooks)) score+=QUEEN_ROOK_ON_7TH_RANK;
  789.     }
  790. /*
  791.  ----------------------------------------------------------
  792. |                                                          |
  793. |   add in a bonus for occupying a rank or file close to   |
  794. |   the king.                                              |
  795. |                                                          |
  796.  ----------------------------------------------------------
  797. */
  798.     score+=(4-FileDistance(square,tree->b_kingsq))*QUEEN_KING_TROPISM;
  799.     score+=(4-Distance(square,tree->b_kingsq))*QUEEN_KING_TROPISM/4;
  800.     score+=tree->b_safety*2;
  801.     Clear(square,temp);
  802.   }
  803. #ifdef DEBUGEV
  804.   if (score != lastsc)
  805.   printf("score[queens(white)]=             %4d\n",score);
  806.   lastsc=score;
  807. #endif
  808. /*
  809.  ----------------------------------------------------------
  810. |                                                          |
  811. |   black queens                                           |
  812. |                                                          |
  813. |   first locate each queen and obtain it's centralization |
  814. |   score from the static piece/square table for queens.   |
  815. |                                                          |
  816. |   then, if the opposing side's king safety is much worse |
  817. |   than the king safety for this side, add in a bonus to  |
  818. |   keep the queen around.                                 |
  819. |                                                          |
  820.  ----------------------------------------------------------
  821. */
  822.   temp=BlackQueens;
  823.   while(temp) {
  824.     square=FirstOne(temp);
  825.     score-=queen_value_b[square];
  826. /*
  827.  ----------------------------------------------------------
  828. |                                                          |
  829. |   check to see if the queen is in a strong positiono on  |
  830. |   the 7th rank supported by a rook on the 7th.  if so,   |
  831. |   the positional advantage is almost overwhelming.       |
  832. |                                                          |
  833.  ----------------------------------------------------------
  834. */
  835.     if ((Rank(square) == RANK2) && (And(WhitePawns,rank_mask[RANK2]) ||
  836.          (WhiteKingSQ < A2))) {
  837.       if (And(AttacksRank(square),BlackRooks)) score-=QUEEN_ROOK_ON_7TH_RANK;
  838.     }
  839. /*
  840.  ----------------------------------------------------------
  841. |                                                          |
  842. |   add in a bonus for occupying a rank or file close to   |
  843. |   the king.                                              |
  844. |                                                          |
  845.  ----------------------------------------------------------
  846. */
  847.     score-=(4-FileDistance(square,tree->w_kingsq))*QUEEN_KING_TROPISM;
  848.     score-=(4-Distance(square,tree->w_kingsq))*QUEEN_KING_TROPISM/4;
  849.     score-=tree->w_safety*2;
  850.     Clear(square,temp);
  851.   }
  852. #ifdef DEBUGEV
  853.   if (score != lastsc)
  854.   printf("score[queens(black)]=             %4d\n",score);
  855.   lastsc=score;
  856. #endif
  857.   if (abs(score-tscore) > largest_positional_score) 
  858.     largest_positional_score=abs(score-tscore);
  859. /*
  860.  ----------------------------------------------------------
  861. |                                                          |
  862. |   if the ending has only bishops of opposite colors, the |
  863. |   score is pulled closer to a draw.  if the score says   |
  864. |   one side is winning, but that side doesn't have enough |
  865. |   material to win, the score is set to DRAW.             |
  866. |                                                          |
  867.  ----------------------------------------------------------
  868. */
  869.   if (TotalWhitePieces==bishop_v && TotalBlackPieces==bishop_v) {
  870.     if (square_color[FirstOne(BlackBishops)] != 
  871.         square_color[FirstOne(WhiteBishops)])
  872.       score=score>>1;
  873.   }
  874.   if (drawn_ending < 0) {
  875.     if (drawn_ending == -1 && score > 0) score=DrawScore(root_wtm==wtm);
  876.     else if (drawn_ending == -2 && score < 0) score=DrawScore(root_wtm==wtm);
  877.   }
  878. #ifdef DEBUGEV
  879.   if (score != lastsc)
  880.   printf("score[draws]=                     %4d\n",score);
  881.   lastsc=score;
  882. #endif
  883.   return((wtm) ? score : -score);
  884. }
  885.  
  886. /* last modified 03/11/98 */
  887. /*
  888. ********************************************************************************
  889. *                                                                              *
  890. *   EvaluateDevelopment() is used to encourage the program to develop its      *
  891. *   pieces before moving its queen.  standard developmental principles are     *
  892. *   applied.  they include:  (1) don't move the queen until minor pieces are   *
  893. *   developed;  (2) advance the center pawns as soon as possible;  (3) don't   *
  894. *   move the king unless its a castling move.                                  *
  895. *                                                                              *
  896. ********************************************************************************
  897. */
  898. int EvaluateDevelopment(TREE *tree, int ply) {
  899.   register int possible, real, score=0;
  900.   BITBOARD unmoved_pieces;
  901.  
  902. /*
  903.  ----------------------------------------------------------
  904. |                                                          |
  905. |   first, some "thematic" things, which includes don't    |
  906. |   block the c-pawn in queen-pawn openings, then also     |
  907. |   check to see if center pawns are blocked.              |
  908. |                                                          |
  909.  ----------------------------------------------------------
  910. */
  911.   if (root_wtm) {
  912.     if (!And(set_mask[E4],WhitePawns) && And(set_mask[D4],WhitePawns)) {
  913.       if (And(set_mask[C2],WhitePawns) &&
  914.           And(set_mask[C3],Or(WhiteKnights,WhiteBishops)))
  915.       score-=DEVELOPMENT_THEMATIC;
  916.     }
  917.     if (And(Occupied,And(Shiftr(And(WhitePawns,rank_mask[RANK2]),8),
  918.                               Or(file_mask[FILED],file_mask[FILEE]))))
  919.       score-=DEVELOPMENT_BLOCKED_PAWN;
  920.   }
  921.   else {
  922.     if (!And(set_mask[E4],WhitePawns) && And(set_mask[D4],WhitePawns)) {
  923.       if (And(set_mask[C7],BlackPawns) &&
  924.           And(set_mask[C6],Or(BlackKnights,BlackBishops)))
  925.       score+=DEVELOPMENT_THEMATIC;
  926.     }
  927.     if (And(Occupied,And(Shiftl(And(BlackPawns,rank_mask[RANK7]),8),
  928.                               Or(file_mask[FILED],file_mask[FILEE]))))
  929.       score+=DEVELOPMENT_BLOCKED_PAWN;
  930.   }
  931. #ifdef DEBUGDV
  932.   printf("development.1 score=%d\n", score);
  933. #endif
  934. /*
  935.  ----------------------------------------------------------
  936. |                                                          |
  937. |   if all minor pieces aren't developed, then penalize    |
  938. |   the queen if it has moved.                             |
  939. |                                                          |
  940.  ----------------------------------------------------------
  941. */
  942.   if ((unmoved_pieces=And(Or(WhiteKnights,WhiteBishops),white_minor_pieces))) {
  943.     int unmoved=PopCnt(unmoved_pieces);
  944.     score-=unmoved*DEVELOPMENT_UNMOVED;
  945.     if ((unmoved>1 || WhiteCastle(ply)>0) &&
  946.         !And(WhiteQueens,set_mask[D1])) score-=DEVELOPMENT_QUEEN_EARLY;
  947.   }
  948.   if ((unmoved_pieces=And(Or(BlackKnights,BlackBishops),black_minor_pieces))) {
  949.     int unmoved=PopCnt(unmoved_pieces);
  950.     score+=unmoved*DEVELOPMENT_UNMOVED;
  951.     if ((unmoved>1 || BlackCastle(ply)>0) &&
  952.         !And(BlackQueens,set_mask[D8])) score+=DEVELOPMENT_QUEEN_EARLY;
  953.   }
  954. #ifdef DEBUGDV
  955.   printf("development.2 score=%d\n",score);
  956. #endif
  957. /*
  958.  ----------------------------------------------------------
  959. |                                                          |
  960. |   if the king hasn't moved at the beginning of the       |
  961. |   search, but it has moved somewhere in the current      |
  962. |   search path, make *sure* it's a castle move or else    |
  963. |   penalize the loss of castling privilege.               |
  964. |                                                          |
  965. |   if it *is* a castle move, penalize the king if it is   |
  966. |   castling to one side when the other side is much safer |
  967. |   but will it will take longer to prepare to castle in   |
  968. |   that safer direction.                                  |
  969. |                                                          |
  970. |   the final test is to see if castling rights have been  |
  971. |   lost due to moving one rook.  if so, check to see if   |
  972. |   the remaining castle right would put the king in an    |
  973. |   unsafe position which is just as bad.                  |
  974. |                                                          |
  975.  ----------------------------------------------------------
  976. */
  977.   if (WhiteCastle(1) > 0) {
  978.     register int bq, mult;
  979.     possible=0;
  980.     real=0;
  981.     if (WhiteCastle(ply) == 0)
  982.         score-=(root_wtm) ? 2*DEVELOPMENT_LOSING_CASTLE :
  983.                             DEVELOPMENT_LOSING_CASTLE;
  984.     bq=(BlackQueens) ? 2 : 1;
  985.     if (WhiteCastle(ply) < 0) {
  986.       if (File(WhiteKingSQ) > FILEE) {
  987.         mult=TotalBlackPieces*bq+10;
  988.         if (root_wtm) {
  989.           real=-mult*tree->pawn_score.white_defects_k/10;
  990.           possible=-mult*tree->pawn_score.white_defects_q/10;
  991.         }
  992.         else {
  993.           real=-mult*tree->pawn_score.white_defects_k/15;
  994.           possible=-mult*tree->pawn_score.white_defects_q/15;
  995.         }
  996.       }
  997.       else if (File(WhiteKingSQ) < FILED) {
  998.         mult=TotalBlackPieces*bq+10;
  999.         if (root_wtm) {
  1000.           real=-mult*tree->pawn_score.white_defects_q/10;
  1001.           possible=-mult*tree->pawn_score.white_defects_k/10;
  1002.         }
  1003.         else {
  1004.           real=-mult*tree->pawn_score.white_defects_q/15;
  1005.           possible=-mult*tree->pawn_score.white_defects_k/15;
  1006.         }
  1007.       }
  1008.     }
  1009.     if (WhiteCastle(1)==3 && WhiteCastle(ply)>0 && WhiteCastle(ply)!=3) {
  1010.       if (WhiteCastle(ply)&1) {
  1011.         mult=TotalBlackPieces*bq+10;
  1012.         if (root_wtm) {
  1013.           real=-mult*tree->pawn_score.white_defects_k/10;
  1014.           possible=-mult*tree->pawn_score.white_defects_q/10;
  1015.         }
  1016.         else {
  1017.           real=-mult*tree->pawn_score.white_defects_k/15;
  1018.           possible=-mult*tree->pawn_score.white_defects_q/15;
  1019.         }
  1020.       }
  1021.       else if (WhiteCastle(ply)&2) {
  1022.         mult=TotalBlackPieces*bq+10;
  1023.         if (root_wtm) {
  1024.           real=-mult*tree->pawn_score.white_defects_q/10;
  1025.           possible=-mult*tree->pawn_score.white_defects_k/10;
  1026.         }
  1027.         else {
  1028.           real=-mult*tree->pawn_score.white_defects_q/15;
  1029.           possible=-mult*tree->pawn_score.white_defects_k/15;
  1030.         }
  1031.       }
  1032.     }
  1033.     if (possible > real) score-=possible-real;
  1034.     if (WhiteCastle(ply) > 0) score-=DEVELOPMENT_NOT_CASTLED;
  1035.   }
  1036.   if (BlackCastle(1) > 0) {
  1037.     register int wq, mult;
  1038.     possible=0;
  1039.     real=0;
  1040.     if (BlackCastle(ply) == 0)
  1041.       score+=(!root_wtm) ? 2*DEVELOPMENT_LOSING_CASTLE :
  1042.                              DEVELOPMENT_LOSING_CASTLE;
  1043.     wq=(WhiteQueens) ? 2 : 1;
  1044.     if (BlackCastle(ply) < 0) {
  1045.       if (File(BlackKingSQ) > FILEE) {
  1046.         mult=TotalWhitePieces*wq+10;
  1047.         if (root_wtm) {
  1048.           real=-mult*tree->pawn_score.black_defects_k/15;
  1049.           possible=-mult*tree->pawn_score.black_defects_q/15;
  1050.         }
  1051.         else {
  1052.           real=-mult*tree->pawn_score.black_defects_k/10;
  1053.           possible=-mult*tree->pawn_score.black_defects_q/10;
  1054.         }
  1055.       }
  1056.       else {
  1057.         mult=TotalWhitePieces*wq+10;
  1058.         if (root_wtm) {
  1059.           real=-mult*tree->pawn_score.black_defects_q/15;
  1060.           possible=-mult*tree->pawn_score.black_defects_k/15;
  1061.         }
  1062.         else {
  1063.           real=-mult*tree->pawn_score.black_defects_q/10;
  1064.           possible=-mult*tree->pawn_score.black_defects_k/10;
  1065.         }
  1066.       }
  1067.     }
  1068.     if (BlackCastle(1)==3 && BlackCastle(ply)>0 && BlackCastle(ply)!=3) {
  1069.       if (BlackCastle(ply)&1) {
  1070.         mult=TotalWhitePieces*wq+10;
  1071.         if (root_wtm) {
  1072.           real=-mult*tree->pawn_score.black_defects_k/15;
  1073.           possible=-mult*tree->pawn_score.black_defects_q/15;
  1074.         }
  1075.         else {
  1076.           real=-mult*tree->pawn_score.black_defects_k/10;
  1077.           possible=-mult*tree->pawn_score.black_defects_q/10;
  1078.         }
  1079.       }
  1080.       else if (BlackCastle(ply)&2) {
  1081.         mult=TotalWhitePieces*wq+10;
  1082.         if (root_wtm) {
  1083.           real=-mult*tree->pawn_score.black_defects_q/15;
  1084.           possible=-mult*tree->pawn_score.black_defects_k/15;
  1085.         }
  1086.         else {
  1087.           real=-mult*tree->pawn_score.black_defects_q/10;
  1088.           possible=-mult*tree->pawn_score.black_defects_k/10;
  1089.         }
  1090.       }
  1091.     }
  1092.     if (possible > real) score+=possible-real;
  1093.     if (BlackCastle(ply) > 0) score+=DEVELOPMENT_NOT_CASTLED;
  1094.   }
  1095. #ifdef DEBUGDV
  1096.   printf("development.3 score=%d\n",score);
  1097. #endif
  1098.   return(score);
  1099. }
  1100.  
  1101. int EvaluateDraws(TREE *tree) {
  1102.   register int square;
  1103. /*
  1104.  ----------------------------------------------------------
  1105. |                                                          |
  1106. |   if lots of material is left, it's not a draw.          |
  1107. |                                                          |
  1108.  ----------------------------------------------------------
  1109. */
  1110.   if (TotalWhitePieces >= 5 || TotalBlackPieces >=5) return(0);
  1111. /*
  1112.  ----------------------------------------------------------
  1113. |                                                          |
  1114. |   if white has a bishop and pawn(s) then the pawn had    |
  1115. |   better not be only rook pawns, or else the bishop had  |
  1116. |   better be the right color, otherwise its a DRAW if the |
  1117. |   black king can block the pawn.                         |
  1118. |                                                          |
  1119.  ----------------------------------------------------------
  1120. */
  1121.   if (TotalBlackPieces==0 && TotalWhitePawns &&
  1122.       !And(WhitePawns,not_rook_pawns)) {
  1123.     if (TotalWhitePieces==3) {
  1124.       if (And(WhiteBishops,dark_squares)) {
  1125.         if (And(file_mask[FILEH],WhitePawns)) return(0);
  1126.       }
  1127.       else if (And(file_mask[FILEA],WhitePawns)) return(0);
  1128.     }
  1129.     else if (TotalWhitePieces==0) {
  1130.       if (And(file_mask[FILEA],WhitePawns) &&
  1131.           And(file_mask[FILEH],WhitePawns)) return(0);
  1132.     }
  1133.     else return(0);
  1134.  
  1135.     if (!And(WhitePawns,file_mask[FILEA]) ||
  1136.         !And(WhitePawns,file_mask[FILEH])) {
  1137.       square=LastOne(WhitePawns);
  1138.       if (Rank(BlackKingSQ) >= Rank(square))
  1139.         if (FileDistance(BlackKingSQ,square)<=1) return(1);
  1140.       return(0);
  1141.     }
  1142.   }
  1143. /*
  1144.  ----------------------------------------------------------
  1145. |                                                          |
  1146. |   if black has a bishop and pawn(s) then the pawn had    |
  1147. |   better not be only rook pawns, or else the bishop had  |
  1148. |   better be the right color, otherwise its a DRAW if the |
  1149. |   white king can block the pawn.                         |
  1150. |                                                          |
  1151.  ----------------------------------------------------------
  1152. */
  1153.   if (TotalWhitePieces==0 && TotalBlackPawns &&
  1154.       !And(BlackPawns,not_rook_pawns)) {
  1155.     if (TotalBlackPieces==3) {
  1156.       if (And(BlackBishops,dark_squares)) {
  1157.         if (And(file_mask[FILEA],BlackPawns)) return(0);
  1158.       }
  1159.       else if (And(file_mask[FILEH],BlackPawns)) return(0);
  1160.     }
  1161.     else if (TotalBlackPieces==0) {
  1162.       if (And(file_mask[FILEA],BlackPawns) &&
  1163.           And(file_mask[FILEH],BlackPawns)) return(0);
  1164.     }
  1165.     else return(0);
  1166.  
  1167.     if (!And(BlackPawns,file_mask[FILEA]) ||
  1168.         !And(BlackPawns,file_mask[FILEH])) {
  1169.       square=FirstOne(BlackPawns);
  1170.       if (Rank(WhiteKingSQ) <= Rank(square))
  1171.         if (FileDistance(WhiteKingSQ,square)<=1) return(1);
  1172.       return(0);
  1173.     }
  1174.   }
  1175. /*
  1176.  ----------------------------------------------------------
  1177. |                                                          |
  1178. |   if both sides have pawns, the game is not a draw for   |
  1179. |   lack of material.  also, if one side has at least a    |
  1180. |   B+N, then it's not a drawn position.                   |
  1181. |                                                          |
  1182.  ----------------------------------------------------------
  1183. */
  1184.   if (!TotalWhitePawns && !TotalBlackPawns &&
  1185.       TotalWhitePieces < 5 && TotalBlackPieces < 5) return(1);
  1186.   if (TotalWhitePawns == 0 && TotalWhitePieces < 4) return(-1);
  1187.   else if (TotalBlackPawns == 0 && TotalBlackPieces < 4) return(-2);
  1188.   return(0);
  1189. }
  1190.  
  1191. /* last modified 05/27/98 */
  1192. /*
  1193. ********************************************************************************
  1194. *                                                                              *
  1195. *   EvaluateMate() is used to evaluate positions where neither side has pawns  *
  1196. *   and one side has enough material to force checkmate.  it simply trys to    *
  1197. *   force the losing king to the edge of the board, and then to the corner     *
  1198. *   where mates are easier to find.                                            *
  1199. *                                                                              *
  1200. ********************************************************************************
  1201. */
  1202. int EvaluateMate(TREE *tree) {
  1203.   register int mate_score=0;
  1204. /*
  1205.  ----------------------------------------------------------
  1206. |                                                          |
  1207. |   if one side has a bishop+knight and the other side has |
  1208. |   no pieces or pawns, then use the special bishop_knight |
  1209. |   scoring board for the losing king to force it to the   |
  1210. |   right corner for mate.                                 |
  1211. |                                                          |
  1212.  ----------------------------------------------------------
  1213. */
  1214.   if ((TotalBlackPieces==0) && (TotalWhitePieces==5) &&
  1215.       (!WhitePawns) && (!BlackPawns) && WhiteBishops) {
  1216.     if (And(dark_squares,WhiteBishops))
  1217.       mate_score=b_n_mate_dark_squares[BlackKingSQ];
  1218.     else
  1219.       mate_score=b_n_mate_light_squares[BlackKingSQ];
  1220.   }
  1221.   if ((TotalBlackPieces==5) && (TotalWhitePieces==0) &&
  1222.       (!WhitePawns) && (!BlackPawns) && BlackBishops) {
  1223.     if (And(dark_squares,BlackBishops))
  1224.       mate_score=-b_n_mate_dark_squares[WhiteKingSQ];
  1225.     else
  1226.       mate_score=-b_n_mate_light_squares[WhiteKingSQ];
  1227.   }
  1228.   if (!mate_score) {
  1229. /*
  1230.  ----------------------------------------------------------
  1231. |                                                          |
  1232. |   if white is winning, force the black king to the edge  |
  1233. |   of the board.                                          |
  1234. |                                                          |
  1235.  ----------------------------------------------------------
  1236. */
  1237.     if (Material >= 300) {
  1238.       mate_score=mate[BlackKingSQ];
  1239.       mate_score-=(Distance(WhiteKingSQ,BlackKingSQ)-3)*KING_KING_TROPISM;
  1240.     }
  1241. /*
  1242.  ----------------------------------------------------------
  1243. |                                                          |
  1244. |   if black is winning, force the white king to the edge  |
  1245. |   of the board.                                          |
  1246. |                                                          |
  1247.  ----------------------------------------------------------
  1248. */
  1249.     else if (Material <= -300) {
  1250.       mate_score=-mate[WhiteKingSQ];
  1251.       mate_score+=(Distance(WhiteKingSQ,BlackKingSQ)-3)*KING_KING_TROPISM;
  1252.     }
  1253.   }
  1254.   return(mate_score);
  1255. }
  1256.  
  1257. /* last modified 08/05/98 */
  1258. /*
  1259. ********************************************************************************
  1260. *                                                                              *
  1261. *   EvaluateKingSafety() is used to evaluate king safety for both sides, based *
  1262. *   on the pawns around the king and the material left on the board.           *
  1263. *                                                                              *
  1264. ********************************************************************************
  1265. */
  1266. int EvaluateKingSafety(TREE *tree, int ply) {
  1267.   int score=0;
  1268. /*
  1269.  ----------------------------------------------------------
  1270. |                                                          |
  1271. |   first, check for the "trojan horse" attack where the   |
  1272. |   opponent offers a piece to open the h-file with a very |
  1273. |   difficult to refute attack.                            |
  1274. |                                                          |
  1275.  ----------------------------------------------------------
  1276. */
  1277.   if (!no_tricks) {
  1278.     if (root_wtm && File(WhiteKingSQ) >= FILEE) {
  1279.       if (!And(tree->all_pawns,file_mask[FILEH])) {
  1280.         if (BlackRooks && BlackQueens) score-=KING_SAFETY_MATE_THREAT;
  1281.       }
  1282.     }
  1283.     if (!root_wtm && File(BlackKingSQ) >= FILEE) {
  1284.       if (!And(tree->all_pawns,file_mask[FILEH])) {
  1285.         if (WhiteRooks && WhiteQueens) score+=KING_SAFETY_MATE_THREAT;
  1286.       }
  1287.     }
  1288.   }
  1289. /*
  1290.  ----------------------------------------------------------
  1291. |                                                          |
  1292. |   Now do normal scoring, if the king has castled, the    |
  1293. |   pawns in front are important.  If not castled yet, the |
  1294. |   pawns on the kingside should be preserved for this.    |
  1295. |                                                          |
  1296.  ----------------------------------------------------------
  1297. */
  1298.   tree->w_kingsq=WhiteKingSQ;
  1299.   tree->b_kingsq=BlackKingSQ;
  1300.   if (TotalWhitePieces > 13 && TotalBlackPieces > 13) {
  1301.     tree->w_safety=king_defects_w[WhiteKingSQ];
  1302.     if (WhiteCastle(ply) <= 0) {
  1303.       if (File(WhiteKingSQ) >= FILEE) {
  1304.         if (File(WhiteKingSQ) == FILEH) tree->w_kingsq=(Rank(WhiteKingSQ)<<3)+FILEG;
  1305.         tree->w_safety+=tree->pawn_score.white_defects_k;
  1306.         if (!And(WhitePawns,set_mask[G2])) {
  1307.           if (And(WhitePawns,set_mask[G3]) && Distance(WhiteKingSQ,G2)==1 &&
  1308.               And(WhiteBishops,good_bishop_kw))
  1309.             tree->w_safety-=KING_SAFETY_GOOD_BISHOP;
  1310.           if ((And(set_mask[F3],BlackPawns) || And(set_mask[F3],BlackBishops)) &&
  1311.               BlackQueens) tree->w_safety+=KING_SAFETY_MATE_G2G7;
  1312.         }
  1313.         if (File(WhiteKingSQ)==FILEE) {
  1314.           if (!And(tree->all_pawns,file_mask[FILED])) tree->w_safety+=KING_SAFETY_OPEN_FILE;
  1315.           if (!And(tree->all_pawns,file_mask[FILEE])) tree->w_safety+=KING_SAFETY_OPEN_FILE;
  1316.         }
  1317.       }
  1318.       else if (File(WhiteKingSQ) <= FILED) {
  1319.         if (File(WhiteKingSQ) == FILEA) tree->w_kingsq=(Rank(WhiteKingSQ)<<3)+FILEB;
  1320.         tree->w_safety+=tree->pawn_score.white_defects_q;
  1321.         if (!And(WhitePawns,set_mask[B2])) {
  1322.           if (And(WhitePawns,set_mask[B3]) && Distance(WhiteKingSQ,B2)==1 &&
  1323.               And(WhiteBishops,good_bishop_qw))
  1324.             tree->w_safety-=KING_SAFETY_GOOD_BISHOP;
  1325.           if ((And(set_mask[C3],BlackPawns) || And(set_mask[C3],BlackBishops)) &&
  1326.               BlackQueens) tree->w_safety+=KING_SAFETY_MATE_G2G7;
  1327.         }
  1328.       }
  1329.       if (File(WhiteKingSQ)==FILED) {
  1330.         if (!And(tree->all_pawns,file_mask[FILED])) tree->w_safety+=KING_SAFETY_OPEN_FILE;
  1331.         if (!And(tree->all_pawns,file_mask[FILEE])) tree->w_safety+=KING_SAFETY_OPEN_FILE;
  1332.       }
  1333.     }
  1334.     else {
  1335.       if (WhiteCastle(ply) & 1)
  1336.         tree->w_safety+=tree->pawn_score.white_defects_k;
  1337.       else if (WhiteCastle(ply) & 2)
  1338.         tree->w_safety+=tree->pawn_score.white_defects_q;
  1339.     }
  1340.  
  1341.     tree->b_safety=king_defects_b[BlackKingSQ];
  1342.     if (BlackCastle(ply) <= 0) {
  1343.       if (File(BlackKingSQ) >= FILEE) {
  1344.         if (File(BlackKingSQ) == FILEH) tree->b_kingsq=(Rank(BlackKingSQ)<<3)+FILEG;
  1345.         tree->b_safety+=tree->pawn_score.black_defects_k;
  1346.         if (!And(BlackPawns,set_mask[G7])) {
  1347.           if (And(BlackPawns,set_mask[G6]) && Distance(BlackKingSQ,G7)==1 &&
  1348.               And(BlackBishops,good_bishop_kb))
  1349.             tree->b_safety-=KING_SAFETY_GOOD_BISHOP;
  1350.           if ((And(set_mask[F6],WhitePawns) || And(set_mask[F6],WhiteBishops)) &&
  1351.               WhiteQueens) tree->b_safety+=KING_SAFETY_MATE_G2G7;
  1352.         }
  1353.         if (File(BlackKingSQ)==FILEE) {
  1354.           if (!And(tree->all_pawns,file_mask[FILED])) tree->b_safety+=KING_SAFETY_OPEN_FILE;
  1355.           if (!And(tree->all_pawns,file_mask[FILEE])) tree->b_safety+=KING_SAFETY_OPEN_FILE;
  1356.         }
  1357.       }
  1358.       else if (File(BlackKingSQ) <= FILED) {
  1359.         tree->b_safety+=tree->pawn_score.black_defects_q;
  1360.         if (File(BlackKingSQ) == FILEA) tree->b_kingsq=(Rank(BlackKingSQ)<<3)+FILEB;
  1361.         if (!And(BlackPawns,set_mask[B7])) {
  1362.           if (And(BlackPawns,set_mask[B6]) && Distance(BlackKingSQ,B7)==1 &&
  1363.               And(BlackBishops,good_bishop_qb))
  1364.             tree->b_safety-=KING_SAFETY_GOOD_BISHOP;
  1365.           if ((And(set_mask[C6],WhitePawns) || And(set_mask[C6],WhiteBishops)) &&
  1366.               WhiteQueens) tree->b_safety+=KING_SAFETY_MATE_G2G7;
  1367.         }
  1368.         if (File(BlackKingSQ)==FILED) {
  1369.           if (!And(tree->all_pawns,file_mask[FILED])) tree->b_safety+=KING_SAFETY_OPEN_FILE;
  1370.           if (!And(tree->all_pawns,file_mask[FILEE])) tree->b_safety+=KING_SAFETY_OPEN_FILE;
  1371.         }
  1372.       }
  1373.     }
  1374.     else {
  1375.       if (BlackCastle(ply) & 1)
  1376.         tree->b_safety+=tree->pawn_score.black_defects_k;
  1377.       else if (BlackCastle(ply) & 2)
  1378.         tree->b_safety+=tree->pawn_score.black_defects_q;
  1379.     }
  1380.     tree->w_safety=Min(tree->w_safety,30);
  1381.     tree->b_safety=Min(tree->b_safety,30);
  1382.   }
  1383.   else {
  1384.     tree->w_safety=0;
  1385.     tree->b_safety=0;
  1386.   }
  1387.   score-=(tree->w_safety*TotalBlackPieces)/3;
  1388.   score+=(tree->b_safety*TotalWhitePieces)/3;
  1389.   return(score);
  1390. }
  1391.  
  1392. /* last modified 03/11/98 */
  1393. /*
  1394. ********************************************************************************
  1395. *                                                                              *
  1396. *   EvaluatePassedPawns() is used to evaluate passed pawns and the danger      *
  1397. *   they produce.  the first bonus is for a passed pawn that has reached the   *
  1398. *   6th rank and is supported by the king, making it very difficult to stop it *
  1399. *   from queening.  the second case is two connected passed pawns on the 6th   *
  1400. *   or 7th rank, with the opposing side having little material to stop them.   *
  1401. *                                                                              *
  1402. ********************************************************************************
  1403. */
  1404. int EvaluatePassedPawns(TREE *tree) {
  1405.   register int file, square, score=0;
  1406.   register int white_king_sq, black_king_sq;
  1407.   register int pawns;
  1408.  
  1409. /*
  1410.  ----------------------------------------------------------
  1411. |                                                          |
  1412. |   check to see if black has any passed pawns.  if so,    |
  1413. |   and the king supports the pawn, then the pawn is even  |
  1414. |   more valuable.  at the same time, check to see if the  |
  1415. |   is blockaded by an enemy piece.  if so then the pawn   |
  1416. |   is less valuable since it can't advance easily.  as    |
  1417. |   material is removed, passed pawns also become more     |
  1418. |   valuable.                                              |
  1419. |                                                          |
  1420.  ----------------------------------------------------------
  1421. */
  1422.   if (tree->pawn_score.passed_b) {
  1423.     black_king_sq=BlackKingSQ;
  1424.     pawns=tree->pawn_score.passed_b;
  1425.     while (pawns) {
  1426.       file=first_ones_8bit[pawns];
  1427.       pawns&=~(128>>file);
  1428.       square=FirstOne(And(BlackPawns,file_mask[file]));
  1429.       if (TotalWhitePieces < 20)
  1430.         score-=reduced_material_passer[TotalWhitePieces]*(RANK8-Rank(square));
  1431.       if (FileDistance(square,black_king_sq)==1 &&
  1432.           Rank(black_king_sq)<=Rank(square))
  1433.         score-=supported_passer[RANK8-Rank(square)];
  1434.       if (And(set_mask[square-8],WhitePieces))
  1435.         score+=passed_pawn_value[RANK8-Rank(square)]/2;
  1436.     }
  1437. #ifdef DEBUGPP
  1438.   printf("score.1 after black passers = %d\n", score);
  1439. #endif
  1440. /*
  1441.  ----------------------------------------------------------
  1442. |                                                          |
  1443. |   check to see if black has any connected passed pawns.  |
  1444. |   if so, and they have both reached the 6th/7th rank,    |
  1445. |   then they are very dangerous.                          |
  1446. |                                                          |
  1447.  ----------------------------------------------------------
  1448. */
  1449.     pawns=tree->pawn_score.passed_b;
  1450.     while ((file=connected_passed[pawns])) {
  1451.       register int square1,square2;
  1452.       pawns&=~(128>>file);
  1453.       square1=FirstOne(And(BlackPawns,file_mask[file-1]));
  1454.       if (Rank(square1) > RANK3) continue;
  1455.       square2=FirstOne(And(BlackPawns,file_mask[file]));
  1456.       if (Rank(square2) > RANK3) continue;
  1457.       score-=PAWN_CONNECTED_PASSED_6TH;
  1458.       if (TotalWhitePieces < queen_v &&
  1459.           !And(set_mask[square1-8],WhitePieces) &&
  1460.           !And(set_mask[square2-8],WhitePieces)) {
  1461.         score-=PAWN_CONNECTED_PASSED_6TH;
  1462.         if ((TotalWhitePieces <= rook_v) && 
  1463.             (!And(WhiteKing,black_pawn_race_btm[square1]) ||
  1464.              !And(WhiteKing,black_pawn_race_btm[square2])))
  1465.           score-=3*PAWN_CONNECTED_PASSED_6TH;
  1466.       }
  1467.     }
  1468.   }
  1469. #ifdef DEBUGPP
  1470.   printf("score.2 after black passers = %d\n", score);
  1471. #endif
  1472. /*
  1473.  ----------------------------------------------------------
  1474. |                                                          |
  1475. |   check to see if white has any passed pawns.  if so,    |
  1476. |   and the king supports the pawn, then the pawn is even  |
  1477. |   more valuable.  at the same time, check to see if the  |
  1478. |   is blockaded by an enemy piece.  if so then the pawn   |
  1479. |   is less valuable since it can't advance easily.  as    |
  1480. |   material is removed, passed pawns also become more     |
  1481. |   valuable.                                              |
  1482. |                                                          |
  1483.  ----------------------------------------------------------
  1484. */
  1485.   if (tree->pawn_score.passed_w) {
  1486.     white_king_sq=WhiteKingSQ;
  1487.     pawns=tree->pawn_score.passed_w;
  1488.     while (pawns) {
  1489.       file=first_ones_8bit[pawns];
  1490.       pawns&=~(128>>file);
  1491.       square=LastOne(And(WhitePawns,file_mask[file]));
  1492.       if (TotalBlackPieces < 20)
  1493.         score+=reduced_material_passer[TotalBlackPieces]*Rank(square);
  1494.       if (FileDistance(square,white_king_sq)==1 &&
  1495.           Rank(white_king_sq)>=Rank(square)) 
  1496.         score+=supported_passer[Rank(square)];
  1497.       if (And(set_mask[square+8],BlackPieces))
  1498.         score-=passed_pawn_value[Rank(square)]/2;
  1499.     }
  1500. #ifdef DEBUGPP
  1501.   printf("score.1 after white passers = %d\n", score);
  1502. #endif
  1503. /*
  1504.  ----------------------------------------------------------
  1505. |                                                          |
  1506. |   check to see if white has any connected passed pawns.  |
  1507. |   if so, and they have both reached the 6th/7th rank,    |
  1508. |   then they are very dangerous.                          |
  1509. |                                                          |
  1510.  ----------------------------------------------------------
  1511. */
  1512.     pawns=tree->pawn_score.passed_w;
  1513.     while ((file=connected_passed[pawns])) {
  1514.       register int square1,square2;
  1515.       pawns&=~(128>>file);
  1516.       square1=LastOne(And(WhitePawns,file_mask[file-1]));
  1517.       if (Rank(square1) < RANK6) continue;
  1518.       square2=LastOne(And(WhitePawns,file_mask[file]));
  1519.       if (Rank(square2) < RANK6) continue;
  1520.       score+=PAWN_CONNECTED_PASSED_6TH;
  1521.       if (TotalBlackPieces < queen_v &&
  1522.           !And(set_mask[square1+8],BlackPieces) &&
  1523.           !And(set_mask[square2+8],BlackPieces)) {
  1524.         score+=PAWN_CONNECTED_PASSED_6TH;
  1525.         if ((TotalBlackPieces <= rook_v) && 
  1526.             (!And(BlackKing,white_pawn_race_wtm[square1]) ||
  1527.              !And(BlackKing,white_pawn_race_wtm[square2])))
  1528.           score+=3*PAWN_CONNECTED_PASSED_6TH;
  1529.       }
  1530.     }
  1531.   }
  1532. #ifdef DEBUGPP
  1533.   printf("score.2 after white passers = %d\n", score);
  1534. #endif
  1535.   if (TotalBlackPawns==1 && TotalWhitePawns==0 &&
  1536.       TotalBlackPieces==5 && BlackRooks &&
  1537.       TotalWhitePieces==5 && WhiteRooks) {
  1538.     square=FirstOne(BlackPawns);
  1539.     if (FileDistance(WhiteKingSQ,square)<=1 &&
  1540.         Rank(WhiteKingSQ)<Rank(square)) return(0);
  1541.     if (Rank(BlackKingSQ)>Rank(square) ||
  1542.         FileDistance(BlackKingSQ,square) > 1) return(0);
  1543.   }
  1544.   if (TotalWhitePawns==1 && TotalBlackPawns==0 &&
  1545.       TotalWhitePieces==5 && WhiteRooks &&
  1546.       TotalBlackPieces==5 && BlackRooks) {
  1547.     square=FirstOne(WhitePawns);
  1548.     if (FileDistance(BlackKingSQ,square)<=1 &&
  1549.         Rank(BlackKingSQ)>Rank(square)) return(0);
  1550.     if (Rank(WhiteKingSQ)<Rank(square) ||
  1551.         FileDistance(WhiteKingSQ,square) > 1) return(0);
  1552.   }
  1553.   return(score);
  1554. }
  1555.  
  1556. /* last modified 03/11/98 */
  1557. /*
  1558. ********************************************************************************
  1559. *                                                                              *
  1560. *   EvaluatePassedPawnRaces() is used to evalaute passed pawns when one        *
  1561. *   side has passed pawns and the other side (or neither) has pieces.  in      *
  1562. *   such a case, the critical question is can the defending king stop the pawn *
  1563. *   from queening or is it too far away?  if only one side has pawns that can  *
  1564. *   "run" then the situation is simple.  when both sides have pawns that can   *
  1565. *   "run" it becomes more complex as it then becomes necessary to see if       *
  1566. *   pawn queens with check, or if either pawn queens and simultaneously        *
  1567. *   attacks the opposing side's queening square.  for the special case of a    *
  1568. *   single pawn, the simple evaluation rules are used:  king two squares in    *
  1569. *   front of the pawn=win, one square in front with opposition=win,  king on   *
  1570. *   6th pawn close by is a win.  rook pawns are handled separately and are     *
  1571. *   harder to queen.                                                           *
  1572. *                                                                              *
  1573. ********************************************************************************
  1574. */
  1575. int EvaluatePassedPawnRaces(TREE *tree, int wtm) {
  1576.   register int file, square;
  1577.   register int white_queener=8, white_square=0;
  1578.   register int black_queener=8, black_square=0;
  1579.   register int white_pawn=0, black_pawn=0, queen_distance;
  1580.   register int white_protected=0, black_protected=0;
  1581.   register int pawnsq;
  1582.   register BITBOARD tempw, tempb;
  1583.   register int passed;
  1584.  
  1585. /*
  1586.  ----------------------------------------------------------
  1587. |                                                          |
  1588. |   check to see if white has one pawn and neither side    |
  1589. |   has any pieces.  if so, use the simple pawn evaluation |
  1590. |   logic.                                                 |
  1591. |                                                          |
  1592.  ----------------------------------------------------------
  1593. */
  1594.   if (WhitePawns && !BlackPawns &&
  1595.       !TotalWhitePieces && !TotalBlackPieces) do {
  1596.     pawnsq=LastOne(WhitePawns);
  1597. /*
  1598.  ------------------------------------------------
  1599. |                                                |
  1600. |   king must be in front of the pawn or we      |
  1601. |   go no further.                               |
  1602. |                                                |
  1603.  ------------------------------------------------
  1604. */
  1605.     if (Rank(WhiteKingSQ) <= Rank(pawnsq)) break;
  1606. /*
  1607.  ------------------------------------------------
  1608. |                                                |
  1609. |   first a special case.  if this is a rook     |
  1610. |   pawn, then the king must be on the adjacent  |
  1611. |   file, and be closer to the queening square   |
  1612. |   than the opposing king.                      |
  1613. |                                                |
  1614.  ------------------------------------------------
  1615. */
  1616.     if (File(pawnsq) == FILEA) {
  1617.       if ((File(WhiteKingSQ) == FILEB) &&
  1618.           (Distance(WhiteKingSQ,56) < Distance(BlackKingSQ,56)))
  1619.         return(QUEEN_VALUE-BISHOP_VALUE);
  1620.       break;
  1621.     }
  1622.     else if (File(pawnsq) == FILEH) {
  1623.       if ((File(WhiteKingSQ) == FILEG) &&
  1624.           (Distance(WhiteKingSQ,63) < Distance(BlackKingSQ,63)))
  1625.         return(QUEEN_VALUE-BISHOP_VALUE);
  1626.       break;
  1627.     }
  1628. /*
  1629.  ------------------------------------------------
  1630. |                                                |
  1631. |   if king is two squares in front of the pawn  |
  1632. |   then it's a win immediately.  if the king is |
  1633. |   on the 6th rank and closer to the pawn than  |
  1634. |   the opposing king, it's also a win.          |
  1635. |                                                |
  1636.  ------------------------------------------------
  1637. */
  1638.     if (Distance(WhiteKingSQ,pawnsq)<=Distance(BlackKingSQ,pawnsq)) {
  1639.       if (Rank(WhiteKingSQ) > Rank(pawnsq)+1)
  1640.         return(QUEEN_VALUE-BISHOP_VALUE);
  1641.       if (Rank(WhiteKingSQ) == RANK6)
  1642.         return(QUEEN_VALUE-BISHOP_VALUE);
  1643.     }
  1644. /*
  1645.  ------------------------------------------------
  1646. |                                                |
  1647. |   last chance:  if the king is one square in   |
  1648. |   front of the pawn and has the opposition,    |
  1649. |   then it's still a win.                       |
  1650. |                                                |
  1651.  ------------------------------------------------
  1652. */
  1653.     if ((Rank(WhiteKingSQ) == Rank(pawnsq)+1) &&
  1654.         HasOpposition(wtm,WhiteKingSQ,BlackKingSQ))
  1655.       return(QUEEN_VALUE-BISHOP_VALUE);
  1656.   } while(0);
  1657. /*
  1658.  ----------------------------------------------------------
  1659. |                                                          |
  1660. |   check to see if black has one pawn and neither side    |
  1661. |   has any pieces.  if so, use the simple pawn evaluation |
  1662. |   logic.                                                 |
  1663. |                                                          |
  1664.  ----------------------------------------------------------
  1665. */
  1666.   if (BlackPawns && !WhitePawns &&
  1667.       !TotalWhitePieces && !TotalBlackPieces) do {
  1668.     pawnsq=FirstOne(BlackPawns);
  1669. /*
  1670.  ------------------------------------------------
  1671. |                                                |
  1672. |   king must be in front of the pawn or we      |
  1673. |   go no further.                               |
  1674. |                                                |
  1675.  ------------------------------------------------
  1676. */
  1677.     if (Rank(BlackKingSQ) >= Rank(pawnsq)) break;
  1678. /*
  1679.  ------------------------------------------------
  1680. |                                                |
  1681. |   first a special case.  if this is a rook     |
  1682. |   pawn, then the king must be on the adjacent  |
  1683. |   file, and be closer to the queening square   |
  1684. |   than the opposing king.                      |
  1685. |                                                |
  1686.  ------------------------------------------------
  1687. */
  1688.     if (File(pawnsq) == FILEA) {
  1689.       if ((File(BlackKingSQ) == FILEB) &&
  1690.           (Distance(BlackKingSQ,0) < Distance(WhiteKingSQ,0)))
  1691.         return(-(QUEEN_VALUE-BISHOP_VALUE));
  1692.       break;
  1693.     }
  1694.     else if (File(pawnsq) == FILEH) {
  1695.       if ((File(WhiteKingSQ) == FILEG) &&
  1696.           (Distance(BlackKingSQ,8) < Distance(WhiteKingSQ,8)))
  1697.         return(-(QUEEN_VALUE-BISHOP_VALUE));
  1698.       break;
  1699.     }
  1700. /*
  1701.  ------------------------------------------------
  1702. |                                                |
  1703. |   if king is two squares in front of the pawn  |
  1704. |   then it's a win immediately.  if the king is |
  1705. |   on the 6th rank and closer to the pawn than  |
  1706. |   the opposing king, it's also a win.          |
  1707. |                                                |
  1708.  ------------------------------------------------
  1709. */
  1710.     if (Distance(BlackKingSQ,pawnsq)<=Distance(WhiteKingSQ,pawnsq)) {
  1711.       if (Rank(BlackKingSQ) < Rank(pawnsq)-1)
  1712.         return(-(QUEEN_VALUE-BISHOP_VALUE));
  1713.       if (Rank(BlackKingSQ) == RANK3)
  1714.         return(-(QUEEN_VALUE-BISHOP_VALUE));
  1715.     }
  1716. /*
  1717.  ------------------------------------------------
  1718. |                                                |
  1719. |   last chance:  if the king is one square in   |
  1720. |   front of the pawn and has the opposition,    |
  1721. |   then it's still a win.                       |
  1722. |                                                |
  1723.  ------------------------------------------------
  1724. */
  1725.     if ((Rank(BlackKingSQ) == Rank(pawnsq)-1) &&
  1726.         HasOpposition(ChangeSide(wtm),BlackKingSQ,WhiteKingSQ))
  1727.       return(-(QUEEN_VALUE-BISHOP_VALUE));
  1728.   } while(0);
  1729. /*
  1730.  ----------------------------------------------------------
  1731. |                                                          |
  1732. |   check to see if white is out of pieces and black has   |
  1733. |   passed pawns.  if so, see if any of these passed pawns |
  1734. |   can outrun the defending king and promote.             |
  1735. |                                                          |
  1736.  ----------------------------------------------------------
  1737. */
  1738.   if (!TotalWhitePieces && tree->pawn_score.passed_b) {
  1739.     passed=tree->pawn_score.passed_b;
  1740.     while ((file=first_ones_8bit[passed]) != 8) {
  1741.       passed&=~(128>>file);
  1742.       square=FirstOne(And(BlackPawns,file_mask[file]));
  1743.       if ((wtm && !And(black_pawn_race_wtm[square],WhiteKing)) ||
  1744.           (ChangeSide(wtm) && !And(black_pawn_race_btm[square],WhiteKing))) {
  1745.         queen_distance=Rank(square);
  1746.         if (And(BlackKing,minus8dir[square])) {
  1747.           if (File(square)==FILEA || File(square)==FILEH) queen_distance=99;
  1748.           queen_distance++;
  1749.         }
  1750.         if (Rank(square) == RANK7) queen_distance--;
  1751.         if (queen_distance < black_queener) {
  1752.           black_queener=queen_distance;
  1753.           black_square=File(square);
  1754.           black_pawn=square;
  1755.         }
  1756.       }
  1757.     }
  1758.   }
  1759. #ifdef DEBUGPP
  1760.   printf("black pawn on %d can promote at %d in %d moves.\n",
  1761.          black_pawn,black_square,black_queener);
  1762. #endif
  1763. /*
  1764.  ----------------------------------------------------------
  1765. |                                                          |
  1766. |   check to see if black is out of pieces and white has   |
  1767. |   passed pawns.  if so, see if any of these passed pawns |
  1768. |   can outrun the defending king and promote.             |
  1769. |                                                          |
  1770.  ----------------------------------------------------------
  1771. */
  1772.   if (!TotalBlackPieces && tree->pawn_score.passed_w) {
  1773.     passed=tree->pawn_score.passed_w;
  1774.     while ((file=first_ones_8bit[passed]) != 8) {
  1775.       passed&=~(128>>file);
  1776.       square=LastOne(And(WhitePawns,file_mask[file]));
  1777.       if ((wtm && !And(white_pawn_race_wtm[square],BlackKing)) ||
  1778.           (ChangeSide(wtm) && !And(white_pawn_race_btm[square],BlackKing))) {
  1779.         queen_distance=RANK8-Rank(square);
  1780.         if (And(WhiteKing,plus8dir[square])) {
  1781.           if (File(square)==FILEA || File(square)==FILEH) queen_distance=99;
  1782.           queen_distance++;
  1783.         }
  1784.         if (Rank(square) == RANK2) queen_distance--;
  1785.         if (queen_distance < white_queener) {
  1786.           white_queener=queen_distance;
  1787.           white_square=File(square)+56;
  1788.           white_pawn=square;
  1789.         }
  1790.       }
  1791.     }
  1792.   }
  1793. #ifdef DEBUGPP
  1794.   printf("white pawn on %d can promote at %d in %d moves.\n",
  1795.          white_pawn,white_square,white_queener);
  1796. #endif
  1797.  
  1798.   do {
  1799.     if ((white_queener==8) && (black_queener==8)) break;
  1800. /*
  1801.  ----------------------------------------------------------
  1802. |                                                          |
  1803. |   now that we know which pawns can outrun the kings for  |
  1804. |   each side, we need to do the following:  if one side   |
  1805. |   queens before the other (two moves or more) then that  |
  1806. |   side wins.                                             |
  1807. |                                                          |
  1808.  ----------------------------------------------------------
  1809. */
  1810.     if ((white_queener < 8) && (black_queener == 8))
  1811.       return(QUEEN_VALUE-BISHOP_VALUE+white_queener*PAWN_VALUE/10);
  1812.     else if ((black_queener < 8) && (white_queener == 8))
  1813.       return(-(QUEEN_VALUE-BISHOP_VALUE+black_queener*PAWN_VALUE/10));
  1814.     if (ChangeSide(wtm)) black_queener--;
  1815.     if (white_queener < black_queener)
  1816.       return(QUEEN_VALUE-BISHOP_VALUE+white_queener*PAWN_VALUE/10);
  1817.     else if (black_queener < white_queener-1)
  1818.       return(-(QUEEN_VALUE-BISHOP_VALUE+black_queener*PAWN_VALUE/10));
  1819.     if ((white_queener==8) || (black_queener==8)) break;
  1820. /*
  1821.  ----------------------------------------------------------
  1822. |                                                          |
  1823. |   if the white pawn queens one move before black, then   |
  1824. |   if the new queen checks the black king, or the new     |
  1825. |   queen attacks the queening square of black, white wins |
  1826. |   unless the black king is protecting the black queening |
  1827. |   square in which case it's a draw.                      |
  1828. |                                                          |
  1829.  ----------------------------------------------------------
  1830. */
  1831.     if (white_queener == black_queener) {
  1832.       tempw=WhitePieces;
  1833.       Clear(white_pawn,WhitePieces);
  1834.       WhitePieces=Or(WhitePieces,set_mask[white_square]);
  1835.       tempb=BlackPieces;
  1836.       Clear(black_pawn,BlackPieces);
  1837.       BlackPieces=Or(BlackPieces,set_mask[black_square]);
  1838.       if (Attack(BlackKingSQ,white_square,ply)) {
  1839.         WhitePieces=tempw;
  1840.         BlackPieces=tempb;
  1841.         return(QUEEN_VALUE-BISHOP_VALUE+white_queener*PAWN_VALUE/10);
  1842.       }
  1843.       if (Attack(black_square,white_square,ply) &&
  1844.           !And(king_attacks[black_square],BlackKing)) {
  1845.         WhitePieces=tempw;
  1846.         BlackPieces=tempb;
  1847.         return(QUEEN_VALUE-BISHOP_VALUE+white_queener*PAWN_VALUE/10);
  1848.       }
  1849.       WhitePieces=tempw;
  1850.       BlackPieces=tempb;
  1851.     }
  1852. /*
  1853.  ----------------------------------------------------------
  1854. |                                                          |
  1855. |   if the black pawn queens one move before white, then   |
  1856. |   if the new queen checks the white king, or the new     |
  1857. |   queen attacks the queening square of white, black wins |
  1858. |   unless the white king is protecting the white queening |
  1859. |   square in which case it's a draw.                      |
  1860. |                                                          |
  1861.  ----------------------------------------------------------
  1862. */
  1863.     if (black_queener == white_queener-1) {
  1864.       tempw=WhitePieces;
  1865.       Clear(white_pawn,WhitePieces);
  1866.       WhitePieces=Or(WhitePieces,set_mask[white_square]);
  1867.       tempb=BlackPieces;
  1868.       Clear(black_pawn,BlackPieces);
  1869.       BlackPieces=Or(BlackPieces,set_mask[black_square]);
  1870.       if (Attack(WhiteKingSQ,black_square,ply)) {
  1871.         WhitePieces=tempw;
  1872.         BlackPieces=tempb;
  1873.         return(-(QUEEN_VALUE-BISHOP_VALUE+black_queener*PAWN_VALUE/10));
  1874.       }
  1875.       if (Attack(white_square,black_square,ply) &&
  1876.           !And(king_attacks[white_square],WhiteKing)) {
  1877.         WhitePieces=tempw;
  1878.         BlackPieces=tempb;
  1879.         return(-(QUEEN_VALUE-BISHOP_VALUE+black_queener*PAWN_VALUE/10));
  1880.       }
  1881.       WhitePieces=tempw;
  1882.       BlackPieces=tempb;
  1883.     }
  1884.   } while(0);
  1885. /*
  1886.  ----------------------------------------------------------
  1887. |                                                          |
  1888. |   if one side has a protected passed pawn, and the other |
  1889. |   side has no pieces, then the protected passer is a     |
  1890. |   *real* advantage, unless both sides have one.          |
  1891. |                                                          |
  1892.  ----------------------------------------------------------
  1893. */
  1894.   if (white_protected && !black_protected) 
  1895.     return(PAWN_PROTECTED_PASSER_WINS);
  1896.   else if (!white_protected && black_protected) 
  1897.     return(-PAWN_PROTECTED_PASSER_WINS);
  1898.   else
  1899.     return(0);
  1900. }
  1901.  
  1902. /* last modified 08/24/98 */
  1903. /*
  1904. ********************************************************************************
  1905. *                                                                              *
  1906. *   EvaluatePawns() is used to evaluate pawns.  broadly, it addresses three    *
  1907. *   distinct actions:  (1) basic pawn scoring is hashed, the first thing done  *
  1908. *   is to see if the score is in the pawn hash table;  (2) passed pawn scoring *
  1909. *   for positions with pieces left;  (3) passed pawns where one side has a     *
  1910. *   passer and the other side has no pieces, so that the pawn can potentially  *
  1911. *   outrun the opposing king and promote.                                      *
  1912. *                                                                              *
  1913. ********************************************************************************
  1914. */
  1915. int EvaluatePawns(TREE *tree) {
  1916.   register PAWN_HASH_ENTRY *ptable;
  1917.   register BITBOARD pawns;
  1918.   register BITBOARD temp;
  1919.   register BITBOARD wp_moves, bp_moves;
  1920.   register int square, file, atk_temp;
  1921.   register int w_weak, w_isolated=0, b_weak, b_isolated=0;
  1922.   register int w_unblocked=0, b_unblocked=0;
  1923.   register int w_file_l, w_file_r, b_file_l, b_file_r;
  1924.   register int defenders, attackers, weakness, blocked, sq, adv;
  1925. #if defined(DEBUGP)
  1926.   int lastsc=0;
  1927. #endif
  1928. /*
  1929.  ----------------------------------------------------------
  1930. |                                                          |
  1931. |   first check to see if this position has been handled   |
  1932. |   before.  if so, we can skip the work saved in the pawn |
  1933. |   hash table.                                            |
  1934. |                                                          |
  1935.  ----------------------------------------------------------
  1936. */
  1937.   ptable=pawn_hash_table+(PawnHashKey&pawn_hash_mask);
  1938. #if defined(SMP)
  1939.   Lock(lock_pawn_hash);
  1940. #endif
  1941.   if (ptable->key == PawnHashKey) {
  1942. #if !defined(FAST)
  1943.     tree->pawn_hits++;
  1944. #endif
  1945.     tree->pawn_score=*ptable;
  1946. #if defined(SMP)
  1947.     UnLock(lock_pawn_hash);
  1948. #endif
  1949.     return(tree->pawn_score.p_score);
  1950.   }
  1951. #if defined(SMP)
  1952.   UnLock(lock_pawn_hash);
  1953. #endif
  1954.   tree->pawn_score.key=PawnHashKey;
  1955.   tree->pawn_score.p_score=0;
  1956.   tree->pawn_score.passed_w=0;
  1957.   tree->pawn_score.passed_b=0;
  1958.   tree->pawn_score.weak_w=0;
  1959.   tree->pawn_score.weak_b=0;
  1960.   tree->pawn_score.white_pof=0;
  1961.   tree->pawn_score.black_pof=0;
  1962.   tree->pawn_score.white_protected=0;
  1963.   tree->pawn_score.black_protected=0;
  1964.   tree->pawn_score.white_defects_k=0;
  1965.   tree->pawn_score.white_defects_q=0;
  1966.   tree->pawn_score.black_defects_k=0;
  1967.   tree->pawn_score.black_defects_q=0;
  1968.   tree->pawn_score.outside=0;
  1969. /*
  1970.  ----------------------------------------------------------
  1971. |                                                          |
  1972. |   first, determine which squares pawns can reach.        |
  1973. |                                                          |
  1974.  ----------------------------------------------------------
  1975. */
  1976.   pawns=WhitePawns;
  1977.   wp_moves=0;
  1978.   while (pawns) {
  1979.     square=FirstOne(pawns);
  1980.     for (sq=square;sq<A7;sq+=8) {
  1981.       wp_moves|=set_mask[sq];
  1982.       if (And(set_mask[sq+8],tree->all_pawns)) break;
  1983.       defenders=PopCnt(And(b_pawn_attacks[sq+8],WhitePawns));
  1984.       attackers=PopCnt(And(w_pawn_attacks[sq+8],BlackPawns));
  1985.       if (attackers-defenders == 2) break;
  1986.     }
  1987.     Clear(square,pawns);
  1988.   }
  1989.   pawns=BlackPawns;
  1990.   bp_moves=0;
  1991.   while (pawns) {
  1992.     square=FirstOne(pawns);
  1993.     for (sq=square;sq>H2;sq-=8) {
  1994.       bp_moves|=set_mask[sq];
  1995.       if (And(set_mask[sq-8],tree->all_pawns)) break;
  1996.       attackers=PopCnt(And(b_pawn_attacks[sq-8],WhitePawns));
  1997.       defenders=PopCnt(And(w_pawn_attacks[sq-8],BlackPawns));
  1998.       if (attackers-defenders == 2) break;
  1999.     }
  2000.     Clear(square,pawns);
  2001.   }
  2002. /*
  2003.  ----------------------------------------------------------
  2004. |                                                          |
  2005. |   white pawns.                                           |
  2006. |                                                          |
  2007.  ----------------------------------------------------------
  2008. */
  2009.   pawns=WhitePawns;
  2010.   while (pawns) {
  2011.     w_weak=0;
  2012.     square=FirstOne(pawns);
  2013.     file=File(square);
  2014. /*
  2015.  ----------------------------------------------------------
  2016. |                                                          |
  2017. |   evaluate pawn advances.  center pawns are encouraged   |
  2018. |   to advance, while wing pawns are pretty much neutral.  |
  2019. |                                                          |
  2020.  ----------------------------------------------------------
  2021. */
  2022.     tree->pawn_score.p_score+=pawn_value_w[square];
  2023. #ifdef DEBUGP
  2024.     if (tree->pawn_score.p_score != lastsc)
  2025.       printf("white pawn[static] file=%d,   score=%d\n",
  2026.              file,tree->pawn_score.p_score);
  2027.     lastsc=tree->pawn_score.p_score;
  2028. #endif
  2029. /*
  2030.  ----------------------------------------------------------
  2031. |                                                          |
  2032. |   evaluate weak pawns.  weak pawns are evaluated by the  |
  2033. |   following rules:  (1) if a pawn is defended by a pawn, |
  2034. |   it isn't weak;  (2) if a pawn is undefended by a pawn  |
  2035. |   and advances one (or two if it hasn't moved yet) ranks |
  2036. |   and is defended fewer times than it is attacked, it is |
  2037. |   weak.  note that the penalty is greater if the pawn is |
  2038. |   on an open file.  note that an isolated pawn is just   |
  2039. |   another case of a weak pawn, since it can never be     |
  2040. |   defended by a pawn.                                    |
  2041. |                                                          |
  2042.  ----------------------------------------------------------
  2043. */
  2044.     if (!And(mask_pawn_isolated[square],WhitePawns)) {
  2045.       w_isolated++;
  2046.       w_weak=128;
  2047.     }
  2048.     else do {
  2049. /*
  2050.  ----------------------------------------------------------
  2051. |                                                          |
  2052. |  test the pawn where it is, and as it advances.  note    |
  2053. |  whether it can end up with more pawn defenders than     |
  2054. |  pawn attackers as it advances.                          |
  2055. |                                                          |
  2056.  ----------------------------------------------------------
  2057. */
  2058.       weakness=0;
  2059.       if (And(plus8dir[square],BlackPawns)) break;
  2060.       defenders=PopCnt(And(b_pawn_attacks[square],WhitePawns));
  2061.       attackers=PopCnt(And(w_pawn_attacks[square],BlackPawns));
  2062.       if (defenders > attackers) break;
  2063.       defenders=PopCnt(And(b_pawn_attacks[square+8],WhitePawns));
  2064.       attackers=PopCnt(And(w_pawn_attacks[square+8],BlackPawns));
  2065.       if (attackers && attackers >= defenders) weakness=attackers-defenders+1;
  2066.       else if (attackers || defenders) break;
  2067.       if (!weakness) break;
  2068. /*
  2069.  ----------------------------------------------------------
  2070. |                                                          |
  2071. |  if the pawn can be defended by a pawn, and that pawn    |
  2072. |  can safely advance, then this pawn is not weak.         |
  2073. |                                                          |
  2074.  ----------------------------------------------------------
  2075. */
  2076.       if ((temp=And(mask_no_pawn_attacks_w[square],WhitePawns))) {
  2077.         if (file > FILEA) {
  2078.           BITBOARD temp1=And(temp,file_mask[file-1]);
  2079.           attackers=1;
  2080.           if (temp1) {
  2081.             int defend_sq=LastOne(temp1);
  2082.             for (sq=defend_sq;sq<(Rank(square)<<3);sq+=8) {
  2083.               attackers=1;
  2084.               if (sq!=defend_sq && And(tree->all_pawns,set_mask[sq])) break;
  2085.               attackers=PopCnt(And(w_pawn_attacks[sq],BlackPawns));
  2086.               if (attackers) break;
  2087.             }
  2088.             if (!attackers) weakness=0;
  2089.           }
  2090.           if (!weakness) break;
  2091.         }
  2092.         if (file < FILEH) {
  2093.           BITBOARD temp1=And(temp,file_mask[file+1]);
  2094.           if (temp1) {
  2095.             int defend_sq=LastOne(temp1);
  2096.             for (sq=defend_sq;sq<(Rank(square)<<3);sq+=8) {
  2097.               attackers=1;
  2098.               if (sq != defend_sq && And(tree->all_pawns,set_mask[sq])) break;
  2099.               attackers=PopCnt(And(w_pawn_attacks[sq],BlackPawns));
  2100.               if (attackers) break;
  2101.             }
  2102.             if (!attackers) weakness=0;
  2103.           }
  2104.         }
  2105.       }
  2106.  
  2107.       if (weakness > 0) {
  2108.         w_weak=128;
  2109.         if (weakness == 3) tree->pawn_score.p_score-=PAWN_WEAK_P2;
  2110.         else if (weakness) tree->pawn_score.p_score-=PAWN_WEAK_P1;
  2111.       }
  2112.     } while(0);
  2113.     if (w_weak) {
  2114.       tree->pawn_score.white_pof++;
  2115.       tree->pawn_score.weak_w|=w_weak>>file;
  2116.     }
  2117. #ifdef DEBUGP
  2118.     if (w_weak) printf("weak white pawn on %s\n",DisplaySQ(square));
  2119.     if (tree->pawn_score.p_score != lastsc)
  2120.       printf("white pawn[weak] file=%d,     score=%d\n",
  2121.              file,tree->pawn_score.p_score);
  2122.     lastsc=tree->pawn_score.p_score;
  2123. #endif
  2124. /*
  2125.  ----------------------------------------------------------
  2126. |                                                          |
  2127. |   evaluate doubled pawns.  if there are other pawns on   |
  2128. |   this file, penalize this pawn.                         |
  2129. |                                                          |
  2130.  ----------------------------------------------------------
  2131. */
  2132.     if (PopCnt(And(file_mask[file],WhitePawns)) > 1) {
  2133.       tree->pawn_score.p_score-=PAWN_DOUBLED;
  2134.     }
  2135. #ifdef DEBUGP
  2136.     if (tree->pawn_score.p_score != lastsc)
  2137.       printf("white pawn[doubled] file=%d,     score=%d\n",
  2138.              file,tree->pawn_score.p_score);
  2139.     lastsc=tree->pawn_score.p_score;
  2140. #endif
  2141. /*
  2142.  ----------------------------------------------------------
  2143. |                                                          |
  2144. |   evaluate passed pawns.                                 |
  2145. |                                                          |
  2146.  ----------------------------------------------------------
  2147. */
  2148.     if (!And(mask_pawn_passed_w[square],BlackPawns) &&
  2149.         (!And(minus8dir[square],tree->all_pawns) || !w_weak)) {
  2150.       tree->pawn_score.p_score+=passed_pawn_value[Rank(square)];
  2151.       if (And(mask_pawn_protected_w[square],WhitePawns))
  2152.         tree->pawn_score.white_protected=1;
  2153.       tree->pawn_score.passed_w|=128>>file;
  2154.     }
  2155. #ifdef DEBUGP
  2156.     if (tree->pawn_score.p_score != lastsc)
  2157.       printf("white pawn[passed] file=%d,   score=%d\n",
  2158.              file,tree->pawn_score.p_score);
  2159.     lastsc=tree->pawn_score.p_score;
  2160. #endif
  2161. /*
  2162.  ----------------------------------------------------------
  2163. |                                                          |
  2164. |   evaluate "hidden" passed pawns.  simple case is a pawn |
  2165. |   chain (white) at b5, a6, with a black pawn at a7.      |
  2166. |   it appears the b-pawn is backward, with a ram at a6/a7 |
  2167. |   but this is misleading, because the pawn at a6 is      |
  2168. |   really passed when white plays b6.                     |
  2169. |                                                          |
  2170.  ----------------------------------------------------------
  2171. */
  2172.     if (Rank(square) > RANK5 && And(set_mask[square+8],BlackPawns) &&
  2173.         !And(mask_pawn_passed_w[square+8],BlackPawns) &&
  2174.         ((File(square) < FILEH && And(set_mask[square-7],WhitePawns) &&
  2175.           !And(plus8dir[square-7],BlackPawns) &&
  2176.           !And(plus8dir[square-6],BlackPawns)) ||
  2177.          (File(square) > FILEA && And(set_mask[square-9],WhitePawns) &&
  2178.           !And(plus8dir[square-9],BlackPawns) &&
  2179.           !And(plus8dir[square-10],BlackPawns)))) {
  2180.       tree->pawn_score.p_score+=passed_pawn_value[Rank(square)];
  2181.     }
  2182. #ifdef DEBUGP
  2183.     if (tree->pawn_score.p_score != lastsc)
  2184.       printf("white pawn[hidden] file=%d,   score=%d\n",
  2185.              file,tree->pawn_score.p_score);
  2186.     lastsc=tree->pawn_score.p_score;
  2187. #endif
  2188. /*
  2189.  ----------------------------------------------------------
  2190. |                                                          |
  2191. |   evaluate blocked pawns.  these are pawns that can not  |
  2192. |   advance because they are blocked, or because they will |
  2193. |   be instantly lost due to other enemy pawns preventing  |
  2194. |   them from moving at all.                               |
  2195. |                                                          |
  2196.  ----------------------------------------------------------
  2197. */
  2198.     if (!end_game) {
  2199.       blocked=1;
  2200.       do {
  2201.         for (sq=square;sq<Min(square+24,A8);sq+=8) {
  2202.           defenders=PopCnt(And(b_pawn_attacks[sq],wp_moves));
  2203.           attackers=PopCnt(And(w_pawn_attacks[sq],BlackPawns));
  2204.           if (attackers > defenders) break;
  2205.           else if (attackers) {
  2206.             blocked=0;
  2207.             break;
  2208.           }
  2209.           if (And(set_mask[sq+8],tree->all_pawns)) break;
  2210.         }
  2211.         if (sq >= Min(square+24,A8)) blocked=0;
  2212.       } while(0);
  2213.       if (!blocked) w_unblocked++;
  2214.     }
  2215.     Clear(square,pawns);
  2216.   }
  2217. /*
  2218.  ----------------------------------------------------------
  2219. |                                                          |
  2220. |   black pawns.                                           |
  2221. |                                                          |
  2222.  ----------------------------------------------------------
  2223. */
  2224.   pawns=BlackPawns;
  2225.   while(pawns) {
  2226.     b_weak=0;
  2227.     square=FirstOne(pawns);
  2228.     file=File(square);
  2229. /*
  2230.  ----------------------------------------------------------
  2231. |                                                          |
  2232. |   evaluate pawn advances.  center pawns are encouraged   |
  2233. |   to advance, while wing pawns are pretty much neutral.  |
  2234. |                                                          |
  2235.  ----------------------------------------------------------
  2236. */
  2237.     tree->pawn_score.p_score-=pawn_value_b[square];
  2238. #ifdef DEBUGP
  2239.     if (tree->pawn_score.p_score != lastsc)
  2240.       printf("black pawn[static] file=%d,   score=%d\n",
  2241.              file,tree->pawn_score.p_score);
  2242.     lastsc=tree->pawn_score.p_score;
  2243. #endif
  2244. /*
  2245.  ----------------------------------------------------------
  2246. |                                                          |
  2247. |   evaluate weak pawns.  weak pawns are evaluated by the  |
  2248. |   following rules:  (1) if a pawn is defended by a pawn, |
  2249. |   it isn't weak;  (2) if a pawn is undefended by a pawn  |
  2250. |   and advances one (or two if it hasn't moved yet) ranks |
  2251. |   and is defended fewer times than it is attacked, it is |
  2252. |   weak.  note that the penalty is greater if the pawn is |
  2253. |   on an open file.  note that an isolated pawn is just   |
  2254. |   another case of a weak pawn, since it can never be     |
  2255. |   defended by a pawn.                                    |
  2256. |                                                          |
  2257.  ----------------------------------------------------------
  2258. */
  2259.     if (!And(mask_pawn_isolated[square],BlackPawns)) {
  2260.       b_isolated++;
  2261.       b_weak=128;
  2262.     }
  2263.     else do {
  2264. /*
  2265.  ----------------------------------------------------------
  2266. |                                                          |
  2267. |  test the pawn where it is, and as it advances.  note    |
  2268. |  whether it can end up with more pawn defenders than     |
  2269. |  pawn attackers as it advances.                          |
  2270. |                                                          |
  2271.  ----------------------------------------------------------
  2272. */
  2273.       weakness=0;
  2274.       if (And(minus8dir[square],WhitePawns)) break;
  2275.       attackers=PopCnt(And(b_pawn_attacks[square],WhitePawns));
  2276.       defenders=PopCnt(And(w_pawn_attacks[square],BlackPawns));
  2277.       if (defenders > attackers) break;
  2278.       attackers=PopCnt(And(b_pawn_attacks[square-8],WhitePawns));
  2279.       defenders=PopCnt(And(w_pawn_attacks[square-8],BlackPawns));
  2280.       if (And(set_mask[square-8],tree->all_pawns)) weakness=1;
  2281.       if (attackers && attackers >= defenders) weakness=attackers-defenders+1;
  2282.       else if (attackers || defenders) break;
  2283.       if (!weakness) break;
  2284. /*
  2285.  ----------------------------------------------------------
  2286. |                                                          |
  2287. |  if the pawn can be defended by a pawn, and that pawn    |
  2288. |  can safely advance, then this pawn is not weak.         |
  2289. |                                                          |
  2290.  ----------------------------------------------------------
  2291. */
  2292.       if ((temp=And(mask_no_pawn_attacks_b[square],BlackPawns))) {
  2293.         if (file > FILEA) {
  2294.           BITBOARD temp1=And(temp,file_mask[file-1]);
  2295.           attackers=1;
  2296.           if (temp1) {
  2297.             int defend_sq=FirstOne(temp1);
  2298.             for (sq=defend_sq;sq>=((Rank(square)+1)<<3);sq-=8) {
  2299.               attackers=1;
  2300.               if (sq!=defend_sq && And(tree->all_pawns,set_mask[sq])) break;
  2301.               attackers=PopCnt(And(b_pawn_attacks[sq],WhitePawns));
  2302.               if (attackers) break;
  2303.             }
  2304.             if (!attackers) weakness=0;
  2305.           }
  2306.           if (!weakness) break;
  2307.         }
  2308.         if (file < FILEH) {
  2309.           BITBOARD temp1=And(temp,file_mask[file+1]);
  2310.           if (temp1) {
  2311.             int defend_sq=FirstOne(temp1);
  2312.             for (sq=defend_sq;sq>=((Rank(square)+1)<<3);sq-=8) {
  2313.               attackers=1;
  2314.               if (sq!=defend_sq && And(tree->all_pawns,set_mask[sq])) break;
  2315.               attackers=PopCnt(And(b_pawn_attacks[sq],WhitePawns));
  2316.               if (attackers) break;
  2317.             }
  2318.             if (!attackers) weakness=0;
  2319.           }
  2320.         }
  2321.       }
  2322.  
  2323.       if (weakness > 0) {
  2324.         b_weak=128;
  2325.         if (weakness == 3) tree->pawn_score.p_score+=PAWN_WEAK_P2;
  2326.         else if (weakness) tree->pawn_score.p_score+=PAWN_WEAK_P1;
  2327.         else tree->pawn_score.p_score+=PAWN_WEAK_P2;
  2328.       }
  2329.     } while(0);
  2330.     if (b_weak) {
  2331.       tree->pawn_score.black_pof++;
  2332.       tree->pawn_score.weak_b|=b_weak>>file;
  2333.     }
  2334. #ifdef DEBUGP
  2335.     if (b_weak) printf("weak black pawn on %s\n",DisplaySQ(square));
  2336.     if (tree->pawn_score.p_score != lastsc)
  2337.       printf("black pawn[weak] file=%d,     score=%d\n",
  2338.              file,tree->pawn_score.p_score);
  2339.     lastsc=tree->pawn_score.p_score;
  2340. #endif
  2341. /*
  2342.  ----------------------------------------------------------
  2343. |                                                          |
  2344. |   evaluate doubled pawns.  if there are other pawns on   |
  2345. |   this file, penalize this pawn.                         |
  2346. |                                                          |
  2347.  ----------------------------------------------------------
  2348. */
  2349.     if (PopCnt(And(file_mask[file],BlackPawns)) > 1) {
  2350.       tree->pawn_score.p_score+=PAWN_DOUBLED;
  2351.     }
  2352. #ifdef DEBUGP
  2353.     if (tree->pawn_score.p_score != lastsc)
  2354.       printf("black pawn[doubled] file=%d,     score=%d\n",
  2355.              file,tree->pawn_score.p_score);
  2356.     lastsc=tree->pawn_score.p_score;
  2357. #endif
  2358. /*
  2359.  ----------------------------------------------------------
  2360. |                                                          |
  2361. |   evaluate passed pawns.                                 |
  2362. |                                                          |
  2363.  ----------------------------------------------------------
  2364. */
  2365.     if (!And(mask_pawn_passed_b[square],WhitePawns) &&
  2366.         (!And(plus8dir[square],tree->all_pawns) || !b_weak)) {
  2367.       tree->pawn_score.p_score-=passed_pawn_value[(RANK8-Rank(square))];
  2368.       if (And(mask_pawn_protected_b[square],BlackPawns))
  2369.         tree->pawn_score.black_protected=1;
  2370.       tree->pawn_score.passed_b|=128>>file;
  2371.     }
  2372. #ifdef DEBUGP
  2373.     if (tree->pawn_score.p_score != lastsc)
  2374.       printf("black pawn[passed] file=%d,   score=%d\n",
  2375.              file,tree->pawn_score.p_score);
  2376.     lastsc=tree->pawn_score.p_score;
  2377. #endif
  2378. /*
  2379.  ----------------------------------------------------------
  2380. |                                                          |
  2381. |   evaluate "hidden" passed pawns.  simple case is a pawn |
  2382. |   chain (white) at b5, a6, with a black pawn at a7.      |
  2383. |   it appears the b-pawn is backward, with a ram at a6/a7 |
  2384. |   but this is misleading, because the pawn at a6 is      |
  2385. |   really passed when white plays b6.                     |
  2386. |                                                          |
  2387.  ----------------------------------------------------------
  2388. */
  2389.     if (Rank(square) < RANK4 && And(set_mask[square-8],WhitePawns) &&
  2390.         !And(mask_pawn_passed_b[square-8],WhitePawns) &&
  2391.         ((File(square) < FILEH && And(set_mask[square+9],BlackPawns) &&
  2392.           !And(minus8dir[square+9],WhitePawns) &&
  2393.           !And(minus8dir[square+10],WhitePawns)) ||
  2394.          (File(square) > FILEA && And(set_mask[square+7],BlackPawns) &&
  2395.           !And(minus8dir[square+7],WhitePawns) &&
  2396.           !And(minus8dir[square+6],WhitePawns)))) {
  2397.       tree->pawn_score.p_score-=passed_pawn_value[(RANK8-Rank(square))];
  2398.     }
  2399. #ifdef DEBUGP
  2400.     if (tree->pawn_score.p_score != lastsc)
  2401.       printf("black pawn[hidden] file=%d,   score=%d\n",
  2402.              file,tree->pawn_score.p_score);
  2403.     lastsc=tree->pawn_score.p_score;
  2404. #endif
  2405. /*
  2406.  ----------------------------------------------------------
  2407. |                                                          |
  2408. |   evaluate blocked pawns.  these are pawns that can not  |
  2409. |   advance because they are blocked, or because they will |
  2410. |   be instantly lost due to other enemy pawns preventing  |
  2411. |   them from moving at all.                               |
  2412. |                                                          |
  2413.  ----------------------------------------------------------
  2414. */
  2415.     if (!end_game) {
  2416.       blocked=1;
  2417.       do {
  2418.         for (sq=square;sq>Max(square-24,H1);sq-=8) {
  2419.           attackers=PopCnt(And(b_pawn_attacks[sq],WhitePawns));
  2420.           defenders=PopCnt(And(w_pawn_attacks[sq],bp_moves));
  2421.           if (attackers > defenders) break;
  2422.           else if (attackers) {
  2423.             blocked=0;
  2424.             break;
  2425.           }
  2426.           if (And(set_mask[sq-8],tree->all_pawns)) break;
  2427.         }
  2428.         if (sq <= Max(square-24,H1)) blocked=0;
  2429.       } while(0);
  2430.       if (!blocked) b_unblocked++;
  2431.     }
  2432.     Clear(square,pawns);
  2433.   }
  2434. /*
  2435.  ----------------------------------------------------------
  2436. |                                                          |
  2437. |   now fold in the penalty for isolated pawns, which is   |
  2438. |   non-linear to penalize more isolani more severely.     |
  2439. |   note that the penalty penalizes the side with the      |
  2440. |   most isolated pawns, in an exponential rate.           |
  2441. |                                                          |
  2442.  ----------------------------------------------------------
  2443. */
  2444.   if (w_isolated > b_isolated)
  2445.     tree->pawn_score.p_score+=isolated_pawn_value[w_isolated-b_isolated];
  2446.   else
  2447.     tree->pawn_score.p_score-=isolated_pawn_value[b_isolated-w_isolated];
  2448. #ifdef DEBUGP
  2449.   if (tree->pawn_score.p_score != lastsc)
  2450.     printf("pawn[isolated]          score=%d\n",tree->pawn_score.p_score);
  2451.   lastsc=tree->pawn_score.p_score;
  2452. #endif
  2453. /*
  2454.  ----------------------------------------------------------
  2455. |                                                          |
  2456. |   now fold in the bonus for unblocked pawns.  the real   |
  2457. |   issue is keeping "lever" possibilities for each side   |
  2458. |   available, so there is some opportunity for breaking   |
  2459. |   the position open, rather than letting it become       |
  2460. |   totally blocked.                                       |
  2461. |                                                          |
  2462.  ----------------------------------------------------------
  2463. */
  2464.   if (TotalWhitePawns>5 && TotalBlackPawns>5)
  2465.     tree->pawn_score.p_score+=unblocked_pawns[w_unblocked]-
  2466.                               unblocked_pawns[b_unblocked];
  2467. #ifdef DEBUGP
  2468.   if (tree->pawn_score.p_score != lastsc)
  2469.     printf("pawn[unblocked]         score=%d\n",tree->pawn_score.p_score);
  2470.   lastsc=tree->pawn_score.p_score;
  2471. #endif
  2472. /*
  2473.  ----------------------------------------------------------
  2474. |                                                          |
  2475. |   now fold in the penalty for "rams" which are pawns     |
  2476. |   that are blocked by a pawn on the same file.           |
  2477. |                                                          |
  2478.  ----------------------------------------------------------
  2479. */
  2480.   if (root_wtm)
  2481.     tree->pawn_score.p_score-=
  2482.       PAWN_RAM*PopCnt(And(WhitePawns,Shiftl(BlackPawns,8)));
  2483.   else
  2484.     tree->pawn_score.p_score+=
  2485.       PAWN_RAM*PopCnt(And(WhitePawns,Shiftl(BlackPawns,8)));
  2486. #ifdef DEBUGP
  2487.   if (tree->pawn_score.p_score != lastsc)
  2488.     printf("pawn[rams]              score=%d\n",tree->pawn_score.p_score);
  2489.   lastsc=tree->pawn_score.p_score;
  2490. #endif
  2491. /*
  2492.  ----------------------------------------------------------
  2493. |                                                          |
  2494. |   now evaluate king safety.  the basic idea is this:  if |
  2495. |   a pawn is on its original square, no defect is given.  |
  2496. |   if a pawn has advanced 1 rank, defects are added in.   |
  2497. |   if the pawn has advanced two files more defects are    |
  2498. |   added to the total. otherwise if the pawn is com-      |
  2499. |   pletely missing, even more defects are added in, and   |
  2500. |   in that case, if the opponent has no pawn on this file |
  2501. |   it is even worse.  this is repeated for each file.     |
  2502. |                                                          |
  2503.  ----------------------------------------------------------
  2504. */
  2505. /*
  2506.  ------------------------------------------------
  2507. |                                                |
  2508. |   rook pawn file.  (black)                     |
  2509. |                                                |
  2510.  ------------------------------------------------
  2511. */
  2512.   tree->pawn_score.black_defects_k=0;
  2513.   tree->pawn_score.black_defects_q=0;
  2514.   if (!And(BlackPawns,set_mask[A7])) {
  2515.     if (And(BlackPawns,set_mask[A6]))
  2516.      tree->pawn_score.black_defects_q+=KING_SAFETY_RP_ADV1;
  2517.    else
  2518.     tree->pawn_score.black_defects_q+=KING_SAFETY_RP_TOO_FAR;
  2519.     if (!And(BlackPawns,file_mask[FILEA]))
  2520.       tree->pawn_score.black_defects_q+=KING_SAFETY_RP_FILE_HALF_OPEN;
  2521.   }
  2522.   if (!And(WhitePawns,file_mask[FILEA]))
  2523.     tree->pawn_score.black_defects_q+=KING_SAFETY_RP_FILE_HALF_OPEN;
  2524.  
  2525.   if (!And(BlackPawns,set_mask[H7])) {
  2526.     if (And(BlackPawns,set_mask[H6]))
  2527.       tree->pawn_score.black_defects_k+=KING_SAFETY_RP_ADV1;
  2528.     else
  2529.       tree->pawn_score.black_defects_k+=KING_SAFETY_RP_TOO_FAR;
  2530.     if (!And(BlackPawns,file_mask[FILEH]))
  2531.       tree->pawn_score.black_defects_k+=KING_SAFETY_RP_FILE_HALF_OPEN;
  2532.   }
  2533.   if (!And(WhitePawns,file_mask[FILEH]))
  2534.     tree->pawn_score.black_defects_k+=KING_SAFETY_RP_FILE_OTHERHALF_OPEN;
  2535. #ifdef DEBUGK
  2536.   printf("black.RP, defects=%d(q)  %d(k)\n",
  2537.          tree->pawn_score.black_defects_q,tree->pawn_score.black_defects_k);
  2538. #endif
  2539. /*
  2540.  ------------------------------------------------
  2541. |                                                |
  2542. |   knight pawn file.  (black)                   |
  2543. |                                                |
  2544.  ------------------------------------------------
  2545. */
  2546.   if (!And(set_mask[B7],BlackPawns)) {
  2547.     if (And(BlackPawns,set_mask[B6])) 
  2548.       tree->pawn_score.black_defects_q+=KING_SAFETY_NP_ADV1;
  2549.     else
  2550.       tree->pawn_score.black_defects_q+=KING_SAFETY_NP_TOO_FAR;
  2551.     if (!And(BlackPawns,file_mask[FILEB]))
  2552.       tree->pawn_score.black_defects_q+=KING_SAFETY_NP_FILE_HALF_OPEN;
  2553.   }
  2554.   if (!And(WhitePawns,file_mask[FILEB]))
  2555.     tree->pawn_score.black_defects_q+=KING_SAFETY_NP_FILE_OTHERHALF_OPEN;
  2556.  
  2557.   if (!And(set_mask[G7],BlackPawns)) {
  2558.     if (And(BlackPawns,set_mask[G6])) 
  2559.       tree->pawn_score.black_defects_k+=KING_SAFETY_NP_ADV1;
  2560.     else
  2561.       tree->pawn_score.black_defects_k+=KING_SAFETY_NP_TOO_FAR;
  2562.     if (!And(BlackPawns,file_mask[FILEG]))
  2563.       tree->pawn_score.black_defects_k+=KING_SAFETY_NP_FILE_HALF_OPEN;
  2564.   }
  2565.   if (!And(WhitePawns,file_mask[FILEG]))
  2566.     tree->pawn_score.black_defects_k+=KING_SAFETY_NP_FILE_OTHERHALF_OPEN;
  2567. #ifdef DEBUGK
  2568.   printf("black.NP, defects=%d(q)  %d(k)\n",
  2569.          tree->pawn_score.black_defects_q,tree->pawn_score.black_defects_k);
  2570. #endif
  2571. /*
  2572.  ------------------------------------------------
  2573. |                                                |
  2574. |   bishop pawn file.  (black)                   |
  2575. |                                                |
  2576.  ------------------------------------------------
  2577. */
  2578.   if (!And(BlackPawns,set_mask[C7])) {
  2579.     if (And(BlackPawns,set_mask[C6]))
  2580.       tree->pawn_score.black_defects_q+=KING_SAFETY_BP_ADV1;
  2581.     else
  2582.       tree->pawn_score.black_defects_q+=KING_SAFETY_BP_TOO_FAR;
  2583.     if (!And(BlackPawns,file_mask[FILEC]))
  2584.       tree->pawn_score.black_defects_q+=KING_SAFETY_BP_FILE_HALF_OPEN;
  2585.   }
  2586.   if (!And(WhitePawns,file_mask[FILEC]))
  2587.     tree->pawn_score.black_defects_q+=KING_SAFETY_BP_FILE_OTHERHALF_OPEN;
  2588.  
  2589.   if (!And(BlackPawns,set_mask[F7])) {
  2590.     if (And(BlackPawns,set_mask[F6]))
  2591.       tree->pawn_score.black_defects_k+=KING_SAFETY_BP_ADV1;
  2592.     else
  2593.       tree->pawn_score.black_defects_k+=KING_SAFETY_BP_TOO_FAR;
  2594.     if (!And(BlackPawns,file_mask[FILEF]))
  2595.       tree->pawn_score.black_defects_k+=KING_SAFETY_BP_FILE_HALF_OPEN;
  2596.   }
  2597.   if (!And(WhitePawns,file_mask[FILEF]))
  2598.     tree->pawn_score.black_defects_k+=KING_SAFETY_BP_FILE_OTHERHALF_OPEN;
  2599. #ifdef DEBUGK
  2600.   printf("black.BP, defects=%d(q)  %d(k)\n",
  2601.          tree->pawn_score.black_defects_q,tree->pawn_score.black_defects_k);
  2602. #endif
  2603. /*
  2604.  ------------------------------------------------
  2605. |                                                |
  2606. |   combination tests (black)                    |
  2607. |                                                |
  2608.  ------------------------------------------------
  2609. */
  2610.   if (!And(BlackPawns,set_mask[A7]) && !And(BlackPawns,set_mask[C7]))
  2611.     tree->pawn_score.black_defects_q+=KING_SAFETY_RP_BP_ADV1;
  2612.   if (!And(BlackPawns,set_mask[F7]) && !And(BlackPawns,set_mask[H7]))
  2613.     tree->pawn_score.black_defects_k+=KING_SAFETY_RP_BP_ADV1;
  2614. #ifdef DEBUGK
  2615.   printf("black.BRP, defects=%d(q)  %d(k)\n",
  2616.          tree->pawn_score.black_defects_q,tree->pawn_score.black_defects_k);
  2617. #endif
  2618. /*
  2619.  ------------------------------------------------
  2620. |                                                |
  2621. |   attack test (black).  determine if white has |
  2622. |   has pawns on black's 4th rank, in a pawn-    |
  2623. |   storm.                                       |
  2624. |                                                |
  2625.  ------------------------------------------------
  2626. */
  2627.   adv=PopCnt(And(mask_bk_4th,WhitePawns));
  2628.   atk_temp=adv*KING_SAFETY_PAWN_ATTACK_4TH;
  2629.   tree->pawn_score.black_defects_k+=atk_temp;
  2630.   adv=PopCnt(And(mask_bq_4th,WhitePawns));
  2631.   atk_temp=adv*KING_SAFETY_PAWN_ATTACK_4TH;
  2632.   adv=PopCnt(And(mask_bq_5th,WhitePawns));
  2633. #ifdef DEBUGK
  2634.   printf("black.AT, defects=%d(q)  %d(k)\n",
  2635.          tree->pawn_score.black_defects_q,tree->pawn_score.black_defects_k);
  2636. #endif
  2637. /*
  2638.  ----------------------------------------------------------
  2639. |                                                          |
  2640. |   now look for the "stonewall" formation in the white    |
  2641. |   pawns and penalize the kingside safety if this type of |
  2642. |   pawn position is found.                                |
  2643. |                                                          |
  2644.  ----------------------------------------------------------
  2645. */
  2646.   if (!root_wtm) {
  2647.     if (PopCnt(And(WhitePawns,stonewall_white)) == 3)
  2648.       tree->pawn_score.black_defects_k+=KING_SAFETY_STONEWALL;
  2649.   }
  2650. #ifdef DEBUGK
  2651.   printf("black.SW, defects=%d(q)  %d(k)\n",
  2652.          tree->pawn_score.black_defects_q,tree->pawn_score.black_defects_k);
  2653. #endif
  2654.  
  2655. /*
  2656.  ------------------------------------------------
  2657. |                                                |
  2658. |   rook pawn file.  (white)                     |
  2659. |                                                |
  2660.  ------------------------------------------------
  2661. */
  2662.   tree->pawn_score.white_defects_k=0;
  2663.   tree->pawn_score.white_defects_q=0;
  2664.   if (!And(WhitePawns,set_mask[A2])) {
  2665.     if (And(WhitePawns,set_mask[A3]))
  2666.       tree->pawn_score.white_defects_q+=KING_SAFETY_RP_ADV1;
  2667.     else
  2668.       tree->pawn_score.white_defects_q+=KING_SAFETY_RP_TOO_FAR;
  2669.     if (!And(WhitePawns,file_mask[FILEA]))
  2670.       tree->pawn_score.white_defects_q+=KING_SAFETY_RP_FILE_HALF_OPEN;
  2671.   }
  2672.   if (!And(BlackPawns,file_mask[FILEA]))
  2673.     tree->pawn_score.white_defects_q+=KING_SAFETY_RP_FILE_OTHERHALF_OPEN;
  2674.  
  2675.   if (!And(WhitePawns,set_mask[H2])) {
  2676.     if (And(WhitePawns,set_mask[H3]))
  2677.       tree->pawn_score.white_defects_k+=KING_SAFETY_RP_ADV1;
  2678.     else
  2679.       tree->pawn_score.white_defects_k+=KING_SAFETY_RP_TOO_FAR;
  2680.     if (!And(WhitePawns,file_mask[FILEH]))
  2681.       tree->pawn_score.white_defects_k+=KING_SAFETY_RP_FILE_HALF_OPEN;
  2682.   }
  2683.   if (!And(BlackPawns,file_mask[FILEH]))
  2684.     tree->pawn_score.white_defects_k+=KING_SAFETY_RP_FILE_OTHERHALF_OPEN;
  2685. #ifdef DEBUGK
  2686.   printf("white.RP, defects=%d(q)  %d(k)\n",
  2687.          tree->pawn_score.white_defects_q,tree->pawn_score.white_defects_k);
  2688. #endif
  2689. /*
  2690.  ------------------------------------------------
  2691. |                                                |
  2692. |   knight pawn file.  (white)                   |
  2693. |                                                |
  2694.  ------------------------------------------------
  2695. */
  2696.   if (!And(set_mask[B2],WhitePawns)) {
  2697.     if (And(WhitePawns,set_mask[B3])) 
  2698.       tree->pawn_score.white_defects_q+=KING_SAFETY_NP_ADV1;
  2699.     else
  2700.       tree->pawn_score.white_defects_q+=KING_SAFETY_NP_TOO_FAR;
  2701.     if (!And(WhitePawns,file_mask[FILEB]))
  2702.       tree->pawn_score.white_defects_q+=KING_SAFETY_NP_FILE_HALF_OPEN;
  2703.   }
  2704.   if (!And(BlackPawns,file_mask[FILEB]))
  2705.     tree->pawn_score.white_defects_q+=KING_SAFETY_NP_FILE_OTHERHALF_OPEN;
  2706.  
  2707.   if (!And(set_mask[G2],WhitePawns)) {
  2708.     if (And(WhitePawns,set_mask[G3])) 
  2709.       tree->pawn_score.white_defects_k+=KING_SAFETY_NP_ADV1;
  2710.     else
  2711.       tree->pawn_score.white_defects_k+=KING_SAFETY_NP_TOO_FAR;
  2712.     if (!And(WhitePawns,file_mask[FILEG]))
  2713.       tree->pawn_score.white_defects_k+=KING_SAFETY_NP_FILE_HALF_OPEN;
  2714.   }
  2715.   if (!And(BlackPawns,file_mask[FILEG]))
  2716.     tree->pawn_score.white_defects_k+=KING_SAFETY_NP_FILE_OTHERHALF_OPEN;
  2717. #ifdef DEBUGK
  2718.   printf("white.NP, defects=%d(q)  %d(k)\n",
  2719.          tree->pawn_score.white_defects_q,tree->pawn_score.white_defects_k);
  2720. #endif
  2721. /*
  2722.  ------------------------------------------------
  2723. |                                                |
  2724. |   bishop pawn file.  (white)                   |
  2725. |                                                |
  2726.  ------------------------------------------------
  2727. */
  2728.   if (!And(WhitePawns,set_mask[C2])) {
  2729.     if (And(WhitePawns,set_mask[C3]))
  2730.       tree->pawn_score.white_defects_q+=KING_SAFETY_BP_ADV1;
  2731.     else
  2732.       tree->pawn_score.white_defects_q+=KING_SAFETY_BP_TOO_FAR;
  2733.     if (!And(WhitePawns,file_mask[FILEC]))
  2734.       tree->pawn_score.white_defects_q+=KING_SAFETY_BP_FILE_HALF_OPEN;
  2735.   }
  2736.   if (!And(BlackPawns,file_mask[FILEC]))
  2737.     tree->pawn_score.white_defects_q+=KING_SAFETY_BP_FILE_OTHERHALF_OPEN;
  2738.  
  2739.   if (!And(WhitePawns,set_mask[F2])) {
  2740.     if (And(WhitePawns,set_mask[F3]))
  2741.       tree->pawn_score.white_defects_k+=KING_SAFETY_BP_ADV1;
  2742.     else
  2743.       tree->pawn_score.white_defects_k+=KING_SAFETY_BP_TOO_FAR;
  2744.     if (!And(WhitePawns,file_mask[FILEF]))
  2745.       tree->pawn_score.white_defects_k+=KING_SAFETY_BP_FILE_HALF_OPEN;
  2746.   }
  2747.   if (!And(BlackPawns,file_mask[FILEF]))
  2748.     tree->pawn_score.white_defects_k+=KING_SAFETY_BP_FILE_OTHERHALF_OPEN;
  2749. #ifdef DEBUGK
  2750.   printf("white.BP, defects=%d(q)  %d(k)\n",
  2751.          tree->pawn_score.white_defects_q,tree->pawn_score.white_defects_k);
  2752. #endif
  2753. /*
  2754.  ------------------------------------------------
  2755. |                                                |
  2756. |   combination tests (white)                    |
  2757. |                                                |
  2758.  ------------------------------------------------
  2759. */
  2760.   if (!And(WhitePawns,set_mask[A2]) && !And(WhitePawns,set_mask[C2]))
  2761.     tree->pawn_score.white_defects_q+=KING_SAFETY_RP_BP_ADV1;
  2762.   if (!And(WhitePawns,set_mask[F2]) && !And(WhitePawns,set_mask[H2]))
  2763.     tree->pawn_score.white_defects_k+=KING_SAFETY_RP_BP_ADV1;
  2764. #ifdef DEBUGK
  2765.   printf("white.BRP, defects=%d(q)  %d(k)\n",
  2766.          tree->pawn_score.white_defects_q,tree->pawn_score.white_defects_k);
  2767. #endif
  2768. /*
  2769.  ------------------------------------------------
  2770. |                                                |
  2771. |   attack test (white).  determine if black has |
  2772. |   has pawns on white's 4th rank, in a pawn-    |
  2773. |   storm.                                       |
  2774. |                                                |
  2775.  ------------------------------------------------
  2776. */
  2777.   adv=PopCnt(And(mask_wk_4th,BlackPawns));
  2778.   atk_temp=adv*KING_SAFETY_PAWN_ATTACK_4TH;
  2779.   tree->pawn_score.white_defects_k+=atk_temp;
  2780.   adv=PopCnt(And(mask_wq_4th,BlackPawns));
  2781.   atk_temp=adv*KING_SAFETY_PAWN_ATTACK_4TH;
  2782.   tree->pawn_score.white_defects_q+=atk_temp;
  2783. #ifdef DEBUGK
  2784.   printf("white.AT, defects=%d(q)  %d(k)\n",
  2785.          tree->pawn_score.white_defects_q,tree->pawn_score.white_defects_k);
  2786. #endif
  2787. /*
  2788.  ----------------------------------------------------------
  2789. |                                                          |
  2790. |   now look for the "stonewall" formation in the black    |
  2791. |   pawns and penalize the kingside safety if this type of |
  2792. |   pawn position is found.                                |
  2793. |                                                          |
  2794.  ----------------------------------------------------------
  2795. */
  2796.   if (root_wtm) {
  2797.     if (PopCnt(And(BlackPawns,stonewall_black)) == 3)
  2798.       tree->pawn_score.white_defects_k+=KING_SAFETY_STONEWALL;
  2799.   }
  2800. #ifdef DEBUGK
  2801.   printf("white.SW, defects=%d(q)  %d(k)\n",
  2802.          tree->pawn_score.white_defects_q,tree->pawn_score.white_defects_k);
  2803. #endif
  2804. /*
  2805.  ----------------------------------------------------------
  2806. |                                                          |
  2807. |  evaluate outside passed pawns by analyzing the passed   |
  2808. |  pawns for both sides. this returns a bonus if one side  |
  2809. |  has a passed pawn on the opposite side of the board     |
  2810. |  from the rest of the pawns.  the side with the most     |
  2811. |  remote (outside) pawn gets a bonus that dynamically     |
  2812. |  varies proportionally to the number of pieces on the    |
  2813. |  board so that it encourages the side with the outside   |
  2814. |  passer to trade down to a simple king and pawn ending   |
  2815. |  which the outside passer wins.                          |
  2816. |                                                          |
  2817.  ----------------------------------------------------------
  2818. */
  2819.   tree->pawn_score.outside=0;
  2820.   w_file_l=first_ones_8bit[tree->pawn_score.passed_w];
  2821.   if (w_file_l == 8) w_file_l=9;
  2822.   b_file_l=first_ones_8bit[tree->pawn_score.passed_b];
  2823.   if (b_file_l == 8) b_file_l=9;
  2824.   w_file_r=last_ones_8bit[tree->pawn_score.passed_w];
  2825.   if (w_file_r == 8) w_file_r=-9;
  2826.   b_file_r=last_ones_8bit[tree->pawn_score.passed_b];
  2827.   if (b_file_r == 8) b_file_r=-9;
  2828. /*
  2829.  ------------------------------------------------
  2830. |                                                |
  2831. |  if one side has a passed pawn that is closer  |
  2832. |  to the side of the board than any other pawn, |
  2833. |  then this pawn is "outside" and valuable.     |
  2834. |                                                |
  2835.  ------------------------------------------------
  2836. */
  2837.   if (w_file_l != 9) {
  2838.     if ((w_file_l < b_file_l-1) || (w_file_r > b_file_r+1)) do {
  2839.       if (w_file_l < 4) {
  2840.         if(And(tree->all_pawns,right_side_mask[w_file_l]) &&
  2841.            !And(BlackPawns,left_side_empty_mask[w_file_l])) {
  2842.           if (!tree->pawn_score.black_protected ||
  2843.               tree->pawn_score.white_protected) tree->pawn_score.outside|=1;
  2844.           break;
  2845.         }
  2846.       }
  2847.       if (w_file_r > 3) {
  2848.         if (And(tree->all_pawns,left_side_mask[w_file_r]) &&
  2849.             !And(BlackPawns,right_side_empty_mask[w_file_r])) {
  2850.           if (!tree->pawn_score.black_protected ||
  2851.               tree->pawn_score.white_protected) tree->pawn_score.outside|=1;
  2852.         }
  2853.       }
  2854.     } while(0);
  2855.   }
  2856.   if (b_file_l != 9) {
  2857.     if ((b_file_l < w_file_l-1) || (b_file_r > w_file_r+1)) do {
  2858.       if (b_file_l < 4) {
  2859.         if(And(tree->all_pawns,right_side_mask[b_file_l]) &&
  2860.            !And(WhitePawns,left_side_empty_mask[b_file_l])) {
  2861.           if (!tree->pawn_score.white_protected ||
  2862.               tree->pawn_score.black_protected) tree->pawn_score.outside|=2;
  2863.           break;
  2864.         }
  2865.       }
  2866.       if (b_file_r > 3) {
  2867.         if (And(tree->all_pawns,left_side_mask[b_file_r]) &&
  2868.             !And(WhitePawns,right_side_empty_mask[b_file_r])) {
  2869.           if (!tree->pawn_score.white_protected ||
  2870.               tree->pawn_score.black_protected) tree->pawn_score.outside|=2;
  2871.         }
  2872.       }
  2873.     } while(0);
  2874.   }
  2875.   if (!tree->pawn_score.outside) {
  2876.     if (tree->pawn_score.white_protected && !tree->pawn_score.black_protected)
  2877.       tree->pawn_score.outside|=1;
  2878.     if (tree->pawn_score.black_protected && !tree->pawn_score.white_protected)
  2879.       tree->pawn_score.outside|=2;
  2880.   }
  2881.  
  2882. /*
  2883.  ----------------------------------------------------------
  2884. |                                                          |
  2885. |   store the results in the pawn hash table for reuse at  |
  2886. |   a later time as needed.                                |
  2887. |                                                          |
  2888.  ----------------------------------------------------------
  2889. */
  2890. #if defined(SMP)
  2891.   Lock(lock_pawn_hash);
  2892. #endif
  2893.   *ptable=tree->pawn_score;
  2894. #if defined(SMP)
  2895.   UnLock(lock_pawn_hash);
  2896. #endif
  2897.   return(tree->pawn_score.p_score);
  2898. }
  2899.