Subversion Repositories Games.Chess Giants

Rev

Rev 108 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "chess.h"
  2. #include "data.h"
  3. /* last modified 05/16/14 */
  4. /*
  5.  *******************************************************************************
  6.  *                                                                             *
  7.  *   SEE() is used to analyze capture moves to see whether or not they appear  *
  8.  *   to be profitable.  The basic algorithm is extremely fast since it uses    *
  9.  *   the bitmaps to determine which squares are attacking the [target] square. *
  10.  *                                                                             *
  11.  *   The algorithm is quite simple.  Using the attack bitmaps, we enumerate    *
  12.  *   all the pieces that are attacking [target] for either side.  Then we      *
  13.  *   simply use the lowest piece (value) for the correct side to capture on    *
  14.  *   [target]. we continually "flip" sides taking the lowest piece each time.  *
  15.  *                                                                             *
  16.  *   As a piece is used, if it is a sliding piece (pawn, bishop, rook or       *
  17.  *   queen) we remove the piece, then generate moves of bishop/queen or        *
  18.  *   rook/queen and then add those in to the attackers, removing any attacks   *
  19.  *   that have already been used.                                              *
  20.  *                                                                             *
  21.  *******************************************************************************
  22.  */
  23. int SEE(TREE * RESTRICT tree, int wtm, int move) {
  24.   uint64_t attacks, temp = 0, toccupied = OccupiedSquares;
  25.   uint64_t bsliders =
  26.       Bishops(white) | Bishops(black) | Queens(white) | Queens(black);
  27.   uint64_t rsliders =
  28.       Rooks(white) | Rooks(black) | Queens(white) | Queens(black);
  29.   int attacked_piece, piece, nc = 1, see_list[32];
  30.   int source = From(move), target = To(move);
  31.  
  32. /*
  33.  ************************************************************
  34.  *                                                          *
  35.  *  Determine which squares attack <target> for each side.  *
  36.  *  initialize by placing the piece on <target> first in    *
  37.  *  the list as it is being captured to start things off.   *
  38.  *                                                          *
  39.  ************************************************************
  40.  */
  41.   attacks = AttacksTo(tree, target);
  42.   attacked_piece = pcval[Captured(move)];
  43. /*
  44.  ************************************************************
  45.  *                                                          *
  46.  *  The first piece to capture on <target> is the piece     *
  47.  *  standing on <source>.                                   *
  48.  *                                                          *
  49.  ************************************************************
  50.  */
  51.   wtm = Flip(wtm);
  52.   see_list[0] = attacked_piece;
  53.   piece = Piece(move);
  54.   attacked_piece = pcval[piece];
  55.   Clear(source, toccupied);
  56.   if (piece & 1)
  57.     attacks |= BishopAttacks(target, toccupied) & bsliders;
  58.   if (piece != king && (piece == pawn || piece & 4))
  59.     attacks |= RookAttacks(target, toccupied) & rsliders;
  60. /*
  61.  ************************************************************
  62.  *                                                          *
  63.  *  Now pick out the least valuable piece for the correct   *
  64.  *  side that is bearing on <target>.  As we find one, we   *
  65.  *  update the attacks (if this is a sliding piece) to get  *
  66.  *  the attacks for any sliding piece that is lined up      *
  67.  *  behind the attacker we are removing.                    *
  68.  *                                                          *
  69.  *  Once we know there is a piece attacking the last        *
  70.  *  capturing piece, add it to the see list and repeat      *
  71.  *  until one side has no more captures.                    *
  72.  *                                                          *
  73.  ************************************************************
  74.  */
  75.   for (attacks &= toccupied; attacks; attacks &= toccupied) {
  76.     for (piece = pawn; piece <= king; piece++)
  77.       if ((temp = Pieces(wtm, piece) & attacks))
  78.         break;
  79.     if (piece > king)
  80.       break;
  81.     toccupied ^= (temp & -temp);
  82.     if (piece & 1)
  83.       attacks |= BishopAttacks(target, toccupied) & bsliders;
  84.     if (piece != king && piece & 4)
  85.       attacks |= RookAttacks(target, toccupied) & rsliders;
  86.     see_list[nc] = -see_list[nc - 1] + attacked_piece;
  87.     attacked_piece = pcval[piece];
  88.     if (see_list[nc++] - attacked_piece > 0)
  89.       break;
  90.     wtm = Flip(wtm);
  91.   }
  92. /*
  93.  ************************************************************
  94.  *                                                          *
  95.  *  Starting at the end of the sequence of values, use a    *
  96.  *  "minimax" like procedure to decide where the captures   *
  97.  *  will stop.                                              *
  98.  *                                                          *
  99.  ************************************************************
  100.  */
  101.   while (--nc)
  102.     see_list[nc - 1] = -Max(-see_list[nc - 1], see_list[nc]);
  103.   return see_list[0];
  104. }
  105.  
  106. /* last modified 05/16/14 */
  107. /*
  108.  *******************************************************************************
  109.  *                                                                             *
  110.  *   SEEO() is used to analyze a move already made to see if it appears to be  *
  111.  *   safe.  It is similar to SEE() except that the move has already been made  *
  112.  *   and we are checking to see whether the opponent can gain material by      *
  113.  *   capturing the piece just moved.                                           *
  114.  *                                                                             *
  115.  *******************************************************************************
  116.  */
  117. int SEEO(TREE * RESTRICT tree, int wtm, int move) {
  118.   uint64_t attacks, temp = 0, toccupied = OccupiedSquares;
  119.   uint64_t bsliders =
  120.       Bishops(white) | Bishops(black) | Queens(white) | Queens(black);
  121.   uint64_t rsliders =
  122.       Rooks(white) | Rooks(black) | Queens(white) | Queens(black);
  123.   int attacked_piece, piece, nc = 1, see_list[32], target = To(move);
  124.  
  125. /*
  126.  ************************************************************
  127.  *                                                          *
  128.  *  Determine which squares attack <target> for each side.  *
  129.  *  initialize by placing the piece on <target> first in    *
  130.  *  the list as it is being captured to start things off.   *
  131.  *                                                          *
  132.  ************************************************************
  133.  */
  134.   attacks = AttacksTo(tree, target);
  135.   attacked_piece = pcval[Piece(move)];
  136. /*
  137.  ************************************************************
  138.  *                                                          *
  139.  *  The first piece to capture on <target> is the piece     *
  140.  *  standing on that square.  We have to find out the least *
  141.  *  valuable attacker for that square first.                *
  142.  *                                                          *
  143.  ************************************************************
  144.  */
  145.   wtm = Flip(wtm);
  146.   see_list[0] = attacked_piece;
  147.   for (piece = pawn; piece <= king; piece++)
  148.     if ((temp = Pieces(wtm, piece) & attacks))
  149.       break;
  150.   if (piece > king)
  151.     return 0;
  152.   toccupied ^= (temp & -temp);
  153.   if (piece & 1)
  154.     attacks |= BishopAttacks(target, toccupied) & bsliders;
  155.   if (piece != king && piece & 4)
  156.     attacks |= RookAttacks(target, toccupied) & rsliders;
  157.   attacked_piece = pcval[piece];
  158.   wtm = Flip(wtm);
  159. /*
  160.  ************************************************************
  161.  *                                                          *
  162.  *  Now pick out the least valuable piece for the correct   *
  163.  *  side that is bearing on <target>.  As we find one, we   *
  164.  *  update the attacks (if this is a sliding piece) to get  *
  165.  *  the attacks for any sliding piece that is lined up      *
  166.  *  behind the attacker we are removing.                    *
  167.  *                                                          *
  168.  *  Once we know there is a piece attacking the last        *
  169.  *  capturing piece, add it to the see list and repeat      *
  170.  *  until one side has no more captures.                    *
  171.  *                                                          *
  172.  ************************************************************
  173.  */
  174.   for (attacks &= toccupied; attacks; attacks &= toccupied) {
  175.     for (piece = pawn; piece <= king; piece++)
  176.       if ((temp = Pieces(wtm, piece) & attacks))
  177.         break;
  178.     if (piece > king)
  179.       break;
  180.     toccupied ^= (temp & -temp);
  181.     if (piece & 1)
  182.       attacks |= BishopAttacks(target, toccupied) & bsliders;
  183.     if (piece != king && piece & 4)
  184.       attacks |= RookAttacks(target, toccupied) & rsliders;
  185.     see_list[nc] = -see_list[nc - 1] + attacked_piece;
  186.     attacked_piece = pcval[piece];
  187.     if (see_list[nc++] - attacked_piece > 0)
  188.       break;
  189.     wtm = Flip(wtm);
  190.   }
  191. /*
  192.  ************************************************************
  193.  *                                                          *
  194.  *  Starting at the end of the sequence of values, use a    *
  195.  *  "minimax" like procedure to decide where the captures   *
  196.  *  will stop.                                              *
  197.  *                                                          *
  198.  ************************************************************
  199.  */
  200.   while (--nc)
  201.     see_list[nc - 1] = -Max(-see_list[nc - 1], see_list[nc]);
  202.   return see_list[0];
  203. }
  204.