Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
108 pmbaty 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;
156 pmbaty 81
    toccupied ^= (temp & (0-temp)); // Pierre-Marie Baty -- signedness fix
108 pmbaty 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;
156 pmbaty 152
  toccupied ^= (temp & (0-temp)); // Pierre-Marie Baty -- signedness fix
108 pmbaty 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;
156 pmbaty 180
    toccupied ^= (temp & (0-temp)); // Pierre-Marie Baty -- signedness fix
108 pmbaty 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
}