Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 pmbaty 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
}