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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "chess.h"
  4. #include "data.h"
  5.  
  6. /* last modified 02/17/97 */
  7. /*
  8. ********************************************************************************
  9. *                                                                              *
  10. *   EnPrise() is used to analyze pieces (at the root of the search) to see if  *
  11. *   they can be captured.  this information is then used to order the moves at *
  12. *   the root of the tree to search moves that don't hang pieces first.         *
  13. *                                                                              *
  14. *   the algorithm is quite simple.  using AttacksTo(), we can enumerate all    *
  15. *   the pieces that are attacking [target] for either side.  then we simply    *
  16. *   use the lowest piece (value) for the correct side to capture on [target].  *
  17. *   we continually "flip" sides taking the lowest piece each time.             *
  18. *                                                                              *
  19. *   as a piece is "used", if it is a sliding piece (pawn, bishop, rook or      *
  20. *   queen) we use the AttacksTo(square) to see if a sliding piece is           *
  21. *   attacking this piece in the same direction, meaning that the sliding piece *
  22. *   can now be used in the swap sequence.  one final "fix" is that the piece   *
  23. *   on <from> must be used first in the capture sequence (if [from] is a real  *
  24. *   square.)                                                                   *
  25. *                                                                              *
  26. ********************************************************************************
  27. */
  28. int EnPrise(int target, int wtm)
  29. {
  30.   BITBOARD white_attackers, black_attackers;
  31.   BITBOARD attacks, temp_attacks;
  32.   BITBOARD *pawns[2], *knights[2], *bishops[2], 
  33.            *rooks[2], *queens[2], *kings[2];
  34.   int attacked_piece;
  35.   int square, direction;
  36.   int swap_sign, color, next_capture=0;
  37.   int swap_list[32];
  38.   TREE *tree=local[0];
  39. /*
  40.  ----------------------------------------------------------
  41. |                                                          |
  42. |   determine which squares attack <target> for each side. |
  43. |                                                          |
  44.  ----------------------------------------------------------
  45. */
  46.   temp_attacks=AttacksTo(tree,target);
  47.   white_attackers=And(temp_attacks,WhitePieces);
  48.   black_attackers=And(temp_attacks,BlackPieces);
  49. /*
  50.  ----------------------------------------------------------
  51. |                                                          |
  52. |   if the side-to-move isn't attacking <target> then we   |
  53. |   are done.                                              |
  54. |                                                          |
  55.  ----------------------------------------------------------
  56. */
  57.   if (wtm) {
  58.     if (!white_attackers) return(0);
  59.   }
  60.   else {
  61.     if (!black_attackers) return(0);
  62.   }
  63. /*
  64.  ----------------------------------------------------------
  65. |                                                          |
  66. |   initialize by placing the piece on <target> first in   |
  67. | the list as it is being captured to start things off.    |
  68. |                                                          |
  69.  ----------------------------------------------------------
  70. */
  71.   swap_list[0]=0;
  72.   attacked_piece=p_values[PieceOnSquare(target)+7];
  73. /*
  74.  ----------------------------------------------------------
  75. |                                                          |
  76. |   no quick exit.  set up for scanning the list of pieces |
  77. |   that attack <target> and play the "swaps" out.         |
  78. |                                                          |
  79.  ----------------------------------------------------------
  80. */
  81.   pawns[0]=&BlackPawns;
  82.   pawns[1]=&WhitePawns;
  83.   knights[0]=&BlackKnights;
  84.   knights[1]=&WhiteKnights;
  85.   bishops[0]=&BlackBishops;
  86.   bishops[1]=&WhiteBishops;
  87.   rooks[0]=&BlackRooks;
  88.   rooks[1]=&WhiteRooks;
  89.   queens[0]=&BlackQueens;
  90.   queens[1]=&WhiteQueens;
  91.   kings[0]=&BlackKing;
  92.   kings[1]=&WhiteKing;
  93.   swap_sign=1;
  94.   attacks=AttacksTo(tree,target);
  95.   color=wtm;
  96. /*
  97.  ----------------------------------------------------------
  98. |                                                          |
  99. |   now pick out the least valuable piece for the correct  |
  100. |   side that is bearing on <target>.  as we find one, we  |
  101. |   call SwapXray() to add the piece behind this piece     |
  102. |   that is indirectly bearing on <target> (if any).       |
  103. |                                                          |
  104.  ----------------------------------------------------------
  105. */
  106.   while (attacks) {
  107.     if (And(*pawns[color],attacks))
  108.       square=FirstOne(And(*pawns[color],attacks));
  109.     else if (And(*knights[color],attacks))
  110.       square=FirstOne(And(*knights[color],attacks));
  111.     else if (And(*bishops[color],attacks))
  112.       square=FirstOne(And(*bishops[color],attacks));
  113.     else if (And(*rooks[color],attacks))
  114.       square=FirstOne(And(*rooks[color],attacks));
  115.     else if (And(*queens[color],attacks))
  116.       square=FirstOne(And(*queens[color],attacks));
  117.     else if (And(*kings[color],attacks))
  118.       square=FirstOne(And(*kings[color],attacks));
  119.     else 
  120.       square=-1;
  121. /*
  122.  ------------------------------------------------
  123. |                                                |
  124. |  located the least valuable piece bearing on   |
  125. |  <target>.  remove it from the list and then   |
  126. |  find out what's behind it.                    |
  127. |                                                |
  128.  ------------------------------------------------
  129. */
  130.     if (square < 0) break;
  131.     if (next_capture)
  132.       swap_list[next_capture]=swap_list[next_capture-1]+
  133.                               swap_sign*attacked_piece;
  134.     else
  135.       swap_list[next_capture]=attacked_piece;
  136.     attacked_piece=p_values[PieceOnSquare(square)+7];
  137.     Clear(square,attacks);
  138.     direction=directions[target][square];
  139.     if (direction) attacks=SwapXray(tree,attacks,square,direction);
  140.     next_capture++;
  141.     swap_sign=-swap_sign;
  142.     color=ChangeSide(color);
  143.   }
  144. /*
  145.  ----------------------------------------------------------
  146. |                                                          |
  147. |   starting at the end of the sequence of values, use a   |
  148. |   "minimax" like procedure to decide where the captures  |
  149. |   will stop.                                             |
  150. |                                                          |
  151.  ----------------------------------------------------------
  152. */
  153.   next_capture--;
  154.   if(next_capture&1) 
  155.     swap_sign=-1;
  156.   else
  157.     swap_sign=1;
  158.   while (next_capture) {
  159.     if (swap_sign < 0) {
  160.       if(swap_list[next_capture] <= swap_list[next_capture-1])
  161.          swap_list[next_capture-1]=swap_list[next_capture];
  162.     }
  163.     else {
  164.       if(swap_list[next_capture] >= swap_list[next_capture-1])
  165.        swap_list[next_capture-1]=swap_list[next_capture];
  166.     }
  167.     next_capture--;
  168.     swap_sign=-swap_sign;
  169.   }
  170.   return (swap_list[0]);
  171. }
  172.