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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "chess.h"
  4. #include "data.h"
  5.  
  6. /* last modified 03/07/97 */
  7. /*
  8. ********************************************************************************
  9. *                                                                              *
  10. *   Swap() is used to analyze capture moves to see whether or not they appear  *
  11. *   to be profitable.  the basic algorithm is extremely fast since it uses the *
  12. *   bitmaps to determine which squares are attacking the [target] square.      *
  13. *                                                                              *
  14. *   the algorithm is quite simple.  using the attack bitmaps, we 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 queen) *
  20. *   we "peek" behind it to see if it is attacked by a sliding piece in the     *
  21. *   direction away from the piece being captured.  if so, and that sliding     *
  22. *   piece moves in this direction, then it is added to the list of attackers   *
  23. *   since its attack has been "uncovered" by moving the capturing piece.       *
  24. *                                                                              *
  25. ********************************************************************************
  26. */
  27. int Swap(TREE *tree, int source, int target, int wtm)
  28. {
  29.   register BITBOARD attacks;
  30.   register int attacked_piece;
  31.   register int square, direction;
  32.   register int sign, color, next_capture=1;
  33.   int swap_list[32];
  34. /*
  35.  ----------------------------------------------------------
  36. |                                                          |
  37. |   determine which squares attack <target> for each side. |
  38. |                                                          |
  39.  ----------------------------------------------------------
  40. */
  41.   attacks=AttacksTo(tree,target);
  42. /*
  43.  ----------------------------------------------------------
  44. |                                                          |
  45. |   initialize by placing the piece on <target> first in   |
  46. | the list as it is being captured to start things off.    |
  47. |                                                          |
  48.  ----------------------------------------------------------
  49. */
  50.   attacked_piece=p_values[PieceOnSquare(target)+7];
  51. /*
  52.  ----------------------------------------------------------
  53. |                                                          |
  54. |   the first piece to capture on <target> is the piece    |
  55. |   standing on <source>.                                  |
  56. |                                                          |
  57.  ----------------------------------------------------------
  58. */
  59.   color=ChangeSide(wtm);
  60.   swap_list[0]=attacked_piece;
  61.   sign=-1;
  62.   attacked_piece=p_values[PieceOnSquare(source)+7];
  63.   Clear(source,attacks);
  64.   direction=directions[target][source];
  65.   if (direction) attacks=SwapXray(tree,attacks,source,direction);
  66. /*
  67.  ----------------------------------------------------------
  68. |                                                          |
  69. |   now pick out the least valuable piece for the correct  |
  70. |   side that is bearing on <target>.  as we find one, we  |
  71. |   call SwapXray() to add the piece behind this piece     |
  72. |   that is indirectly bearing on <target> (if any).       |
  73. |                                                          |
  74.  ----------------------------------------------------------
  75. */
  76.   while (attacks) {
  77.     if (color) {
  78.       if (And(WhitePawns,attacks))
  79.         square=FirstOne(And(WhitePawns,attacks));
  80.       else if (And(WhiteKnights,attacks))
  81.         square=FirstOne(And(WhiteKnights,attacks));
  82.       else if (And(WhiteBishops,attacks))
  83.         square=FirstOne(And(WhiteBishops,attacks));
  84.       else if (And(WhiteRooks,attacks))
  85.         square=FirstOne(And(WhiteRooks,attacks));
  86.       else if (And(WhiteQueens,attacks))
  87.         square=FirstOne(And(WhiteQueens,attacks));
  88.       else if (And(WhiteKing,attacks))
  89.         square=WhiteKingSQ;
  90.       else break;
  91.     }
  92.     else {
  93.       if (And(BlackPawns,attacks))
  94.         square=FirstOne(And(BlackPawns,attacks));
  95.       else if (And(BlackKnights,attacks))
  96.         square=FirstOne(And(BlackKnights,attacks));
  97.       else if (And(BlackBishops,attacks))
  98.         square=FirstOne(And(BlackBishops,attacks));
  99.       else if (And(BlackRooks,attacks))
  100.         square=FirstOne(And(BlackRooks,attacks));
  101.       else if (And(BlackQueens,attacks))
  102.         square=FirstOne(And(BlackQueens,attacks));
  103.       else if (And(BlackKing,attacks))
  104.         square=BlackKingSQ;
  105.       else break;
  106.     }
  107. /*
  108.  ------------------------------------------------
  109. |                                                |
  110. |  located the least valuable piece bearing on   |
  111. |  <target>.  remove it from the list and then   |
  112. |  find out if a sliding piece behind it attacks |
  113. |  through this piece.                           |
  114. |                                                |
  115.  ------------------------------------------------
  116. */
  117.     swap_list[next_capture]=swap_list[next_capture-1]+sign*attacked_piece;
  118.     attacked_piece=p_values[PieceOnSquare(square)+7];
  119.     Clear(square,attacks);
  120.     direction=directions[target][square];
  121.     if (direction) attacks=SwapXray(tree,attacks,square,direction);
  122.     next_capture++;
  123.     sign=-sign;
  124.     color=ChangeSide(color);
  125.   }
  126. /*
  127.  ----------------------------------------------------------
  128. |                                                          |
  129. |   starting at the end of the sequence of values, use a   |
  130. |   "minimax" like procedure to decide where the captures  |
  131. |   will stop.                                             |
  132. |                                                          |
  133.  ----------------------------------------------------------
  134. */
  135.   next_capture--;
  136.   if(next_capture&1) sign=-1;
  137.   else sign=1;
  138.   while (next_capture) {
  139.     if (sign < 0) {
  140.       if(swap_list[next_capture] <= swap_list[next_capture-1])
  141.          swap_list[next_capture-1]=swap_list[next_capture];
  142.     }
  143.     else {
  144.       if(swap_list[next_capture] >= swap_list[next_capture-1])
  145.        swap_list[next_capture-1]=swap_list[next_capture];
  146.     }
  147.     next_capture--;
  148.     sign=-sign;
  149.   }
  150.   return (swap_list[0]);
  151. }
  152.  
  153. /*
  154. ********************************************************************************
  155. *                                                                              *
  156. *   SwapXray() is used to determine if a piece is "behind" the piece on        *
  157. *   <from>, and this piece would attack <to> if the piece on <from> were moved *
  158. *   (as in playing out sequences of swaps).  if so, this indirect attacker is  *
  159. *   added to the list of attackers bearing to <to>.                            *
  160. *                                                                              *
  161. ********************************************************************************
  162. */
  163. BITBOARD SwapXray(TREE *tree, BITBOARD attacks, int from, int direction)
  164. {
  165.   switch (direction) {
  166.   case 1: 
  167.     return(Or(attacks,
  168.               And(And(AttacksRank(from),RooksQueens),plus1dir[from])));
  169.   case 7: 
  170.     return(Or(attacks,
  171.               And(And(AttacksDiaga1(from),BishopsQueens),plus7dir[from])));
  172.   case 8: 
  173.     return(Or(attacks,
  174.               And(And(AttacksFile(from),RooksQueens),plus8dir[from])));
  175.   case 9: 
  176.     return(Or(attacks,
  177.               And(And(AttacksDiagh1(from),BishopsQueens),plus9dir[from])));
  178.   case -1: 
  179.     return(Or(attacks,
  180.               And(And(AttacksRank(from),RooksQueens),minus1dir[from])));
  181.   case -7: 
  182.     return(Or(attacks,
  183.               And(And(AttacksDiaga1(from),BishopsQueens),minus7dir[from])));
  184.   case -8: 
  185.     return(Or(attacks,
  186.               And(And(AttacksFile(from),RooksQueens),minus8dir[from])));
  187.   case -9: 
  188.     return(Or(attacks,
  189.               And(And(AttacksDiagh1(from),BishopsQueens),minus9dir[from])));
  190.   }
  191.   return(attacks);
  192. }
  193.