Subversion Repositories Games.Chess Giants

Rev

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