Subversion Repositories Games.Chess Giants

Rev

Rev 96 | Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 96 Rev 154
Line 18... Line 18...
18
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
*/
19
*/
20
 
20
 
21
#include <algorithm>
21
#include <algorithm>
22
#include <cassert>
22
#include <cassert>
-
 
23
#include <cstddef> // For offsetof()
23
#include <cstring>   // For std::memset, std::memcmp
24
#include <cstring> // For std::memset, std::memcmp
24
#include <iomanip>
25
#include <iomanip>
25
#include <sstream>
26
#include <sstream>
26
 
27
 
27
#include "bitcount.h"
28
#include "bitboard.h"
28
#include "misc.h"
29
#include "misc.h"
29
#include "movegen.h"
30
#include "movegen.h"
30
#include "position.h"
31
#include "position.h"
31
#include "thread.h"
32
#include "thread.h"
32
#include "tt.h"
33
#include "tt.h"
33
#include "uci.h"
34
#include "uci.h"
34
 
35
 
35
using std::string;
36
using std::string;
36
 
37
 
37
Value PieceValue[PHASE_NB][PIECE_NB] = {
38
namespace PSQT {
38
{ VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg },
-
 
39
{ VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg } };
39
  extern Score psq[PIECE_NB][SQUARE_NB];
-
 
40
}
40
 
41
 
41
namespace Zobrist {
42
namespace Zobrist {
42
 
43
 
43
  Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
44
  Key psq[PIECE_NB][SQUARE_NB];
44
  Key enpassant[FILE_NB];
45
  Key enpassant[FILE_NB];
45
  Key castling[CASTLING_RIGHT_NB];
46
  Key castling[CASTLING_RIGHT_NB];
46
  Key side;
47
  Key side;
47
  Key exclusion;
-
 
48
}
48
}
49
 
-
 
50
Key Position::exclusion_key() const { return st->key ^ Zobrist::exclusion; }
-
 
51
 
49
 
52
namespace {
50
namespace {
53
 
51
 
54
const string PieceToChar(" PNBRQK  pnbrqk");
52
const string PieceToChar(" PNBRQK  pnbrqk");
55
 
53
 
Line 81... Line 79...
81
PieceType min_attacker<KING>(const Bitboard*, Square, Bitboard, Bitboard&, Bitboard&) {
79
PieceType min_attacker<KING>(const Bitboard*, Square, Bitboard, Bitboard&, Bitboard&) {
82
  return KING; // No need to update bitboards: it is the last cycle
80
  return KING; // No need to update bitboards: it is the last cycle
83
}
81
}
84
 
82
 
85
} // namespace
83
} // namespace
86
 
-
 
87
 
-
 
88
/// CheckInfo constructor
-
 
89
 
-
 
90
CheckInfo::CheckInfo(const Position& pos) {
-
 
91
 
-
 
92
  Color them = ~pos.side_to_move();
-
 
93
  ksq = pos.square<KING>(them);
-
 
94
 
-
 
95
  pinned = pos.pinned_pieces(pos.side_to_move());
-
 
96
  dcCandidates = pos.discovered_check_candidates();
-
 
97
 
-
 
98
  checkSquares[PAWN]   = pos.attacks_from<PAWN>(ksq, them);
-
 
99
  checkSquares[KNIGHT] = pos.attacks_from<KNIGHT>(ksq);
-
 
100
  checkSquares[BISHOP] = pos.attacks_from<BISHOP>(ksq);
-
 
101
  checkSquares[ROOK]   = pos.attacks_from<ROOK>(ksq);
-
 
102
  checkSquares[QUEEN]  = checkSquares[BISHOP] | checkSquares[ROOK];
-
 
103
  checkSquares[KING]   = 0;
-
 
104
}
-
 
105
 
84
 
106
 
85
 
107
/// operator<<(Position) returns an ASCII representation of the position
86
/// operator<<(Position) returns an ASCII representation of the position
108
 
87
 
109
std::ostream& operator<<(std::ostream& os, const Position& pos) {
88
std::ostream& operator<<(std::ostream& os, const Position& pos) {
Line 133... Line 112...
133
 
112
 
134
void Position::init() {
113
void Position::init() {
135
 
114
 
136
  PRNG rng(1070372);
115
  PRNG rng(1070372);
137
 
116
 
138
  for (Color c = WHITE; c <= BLACK; ++c)
117
  for (Piece pc : Pieces)
139
      for (PieceType pt = PAWN; pt <= KING; ++pt)
-
 
140
          for (Square s = SQ_A1; s <= SQ_H8; ++s)
118
      for (Square s = SQ_A1; s <= SQ_H8; ++s)
141
              Zobrist::psq[c][pt][s] = rng.rand<Key>();
119
          Zobrist::psq[pc][s] = rng.rand<Key>();
142
 
120
 
143
  for (File f = FILE_A; f <= FILE_H; ++f)
121
  for (File f = FILE_A; f <= FILE_H; ++f)
144
      Zobrist::enpassant[f] = rng.rand<Key>();
122
      Zobrist::enpassant[f] = rng.rand<Key>();
145
 
123
 
146
  for (int cr = NO_CASTLING; cr <= ANY_CASTLING; ++cr)
124
  for (int cr = NO_CASTLING; cr <= ANY_CASTLING; ++cr)
Line 153... Line 131...
153
          Zobrist::castling[cr] ^= k ? k : rng.rand<Key>();
131
          Zobrist::castling[cr] ^= k ? k : rng.rand<Key>();
154
      }
132
      }
155
  }
133
  }
156
 
134
 
157
  Zobrist::side = rng.rand<Key>();
135
  Zobrist::side = rng.rand<Key>();
158
  Zobrist::exclusion  = rng.rand<Key>();
-
 
159
}
-
 
160
 
-
 
161
 
-
 
162
/// Position::operator=() creates a copy of 'pos' but detaching the state pointer
-
 
163
/// from the source to be self-consistent and not depending on any external data.
-
 
164
 
-
 
165
Position& Position::operator=(const Position& pos) {
-
 
166
 
-
 
167
  std::memcpy(this, &pos, sizeof(Position));
-
 
168
  std::memcpy(&startState, st, sizeof(StateInfo));
-
 
169
  st = &startState;
-
 
170
  nodes = 0;
-
 
171
 
-
 
172
  assert(pos_is_ok());
-
 
173
 
-
 
174
  return *this;
-
 
175
}
-
 
176
 
-
 
177
 
-
 
178
/// Position::clear() erases the position object to a pristine state, with an
-
 
179
/// empty board, white to move, and no castling rights.
-
 
180
 
-
 
181
void Position::clear() {
-
 
182
 
-
 
183
  std::memset(this, 0, sizeof(Position));
-
 
184
  startState.epSquare = SQ_NONE;
-
 
185
  st = &startState;
-
 
186
 
-
 
187
  for (int i = 0; i < PIECE_TYPE_NB; ++i)
-
 
188
      for (int j = 0; j < 16; ++j)
-
 
189
          pieceList[WHITE][i][j] = pieceList[BLACK][i][j] = SQ_NONE;
-
 
190
}
136
}
191
 
137
 
192
 
138
 
193
/// Position::set() initializes the position object with the given FEN string.
139
/// Position::set() initializes the position object with the given FEN string.
194
/// This function is not very robust - make sure that input FENs are correct,
140
/// This function is not very robust - make sure that input FENs are correct,
195
/// this is assumed to be the responsibility of the GUI.
141
/// this is assumed to be the responsibility of the GUI.
196
 
142
 
197
void Position::set(const string& fenStr, bool isChess960, Thread* th) {
143
Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Thread* th) {
198
/*
144
/*
199
   A FEN string defines a particular position using only the ASCII character set.
145
   A FEN string defines a particular position using only the ASCII character set.
200
 
146
 
201
   A FEN string contains six fields separated by a space. The fields are:
147
   A FEN string contains six fields separated by a space. The fields are:
202
 
148
 
Line 232... Line 178...
232
  unsigned char col, row, token;
178
  unsigned char col, row, token;
233
  size_t idx;
179
  size_t idx;
234
  Square sq = SQ_A8;
180
  Square sq = SQ_A8;
235
  std::istringstream ss(fenStr);
181
  std::istringstream ss(fenStr);
236
 
182
 
-
 
183
  std::memset(this, 0, sizeof(Position));
-
 
184
  std::memset(si, 0, sizeof(StateInfo));
-
 
185
  std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
237
  clear();
186
  st = si;
-
 
187
 
238
  ss >> std::noskipws;
188
  ss >> std::noskipws;
239
 
189
 
240
  // 1. Piece placement
190
  // 1. Piece placement
241
  while ((ss >> token) && !isspace(token))
191
  while ((ss >> token) && !isspace(token))
242
  {
192
  {
Line 246... Line 196...
246
      else if (token == '/')
196
      else if (token == '/')
247
          sq -= Square(16);
197
          sq -= Square(16);
248
 
198
 
249
      else if ((idx = PieceToChar.find(token)) != string::npos)
199
      else if ((idx = PieceToChar.find(token)) != string::npos)
250
      {
200
      {
251
          put_piece(color_of(Piece(idx)), type_of(Piece(idx)), sq);
201
          put_piece(Piece(idx), sq);
252
          ++sq;
202
          ++sq;
253
      }
203
      }
254
  }
204
  }
255
 
205
 
256
  // 2. Active color
206
  // 2. Active color
Line 293... Line 243...
293
      st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
243
      st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
294
 
244
 
295
      if (!(attackers_to(st->epSquare) & pieces(sideToMove, PAWN)))
245
      if (!(attackers_to(st->epSquare) & pieces(sideToMove, PAWN)))
296
          st->epSquare = SQ_NONE;
246
          st->epSquare = SQ_NONE;
297
  }
247
  }
-
 
248
  else
-
 
249
      st->epSquare = SQ_NONE;
298
 
250
 
299
  // 5-6. Halfmove clock and fullmove number
251
  // 5-6. Halfmove clock and fullmove number
300
  ss >> std::skipws >> st->rule50 >> gamePly;
252
  ss >> std::skipws >> st->rule50 >> gamePly;
301
 
253
 
302
  // Convert from fullmove starting from 1 to ply starting from 0,
254
  // Convert from fullmove starting from 1 to ply starting from 0,
Line 306... Line 258...
306
  chess960 = isChess960;
258
  chess960 = isChess960;
307
  thisThread = th;
259
  thisThread = th;
308
  set_state(st);
260
  set_state(st);
309
 
261
 
310
  assert(pos_is_ok());
262
  assert(pos_is_ok());
-
 
263
 
-
 
264
  return *this;
311
}
265
}
312
 
266
 
313
 
267
 
314
/// Position::set_castling_right() is a helper function used to set castling
268
/// Position::set_castling_right() is a helper function used to set castling
315
/// rights given the corresponding color and the rook starting square.
269
/// rights given the corresponding color and the rook starting square.
Line 333... Line 287...
333
          castlingPath[cr] |= s;
287
          castlingPath[cr] |= s;
334
 
288
 
335
  for (Square s = std::min(kfrom, kto); s <= std::max(kfrom, kto); ++s)
289
  for (Square s = std::min(kfrom, kto); s <= std::max(kfrom, kto); ++s)
336
      if (s != kfrom && s != rfrom)
290
      if (s != kfrom && s != rfrom)
337
          castlingPath[cr] |= s;
291
          castlingPath[cr] |= s;
-
 
292
}
-
 
293
 
-
 
294
 
-
 
295
/// Position::set_check_info() sets king attacks to detect if a move gives check
-
 
296
 
-
 
297
void Position::set_check_info(StateInfo* si) const {
-
 
298
 
-
 
299
  si->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), si->pinnersForKing[WHITE]);
-
 
300
  si->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), si->pinnersForKing[BLACK]);
-
 
301
 
-
 
302
  Square ksq = square<KING>(~sideToMove);
-
 
303
 
-
 
304
  si->checkSquares[PAWN]   = attacks_from<PAWN>(ksq, ~sideToMove);
-
 
305
  si->checkSquares[KNIGHT] = attacks_from<KNIGHT>(ksq);
-
 
306
  si->checkSquares[BISHOP] = attacks_from<BISHOP>(ksq);
-
 
307
  si->checkSquares[ROOK]   = attacks_from<ROOK>(ksq);
-
 
308
  si->checkSquares[QUEEN]  = si->checkSquares[BISHOP] | si->checkSquares[ROOK];
-
 
309
  si->checkSquares[KING]   = 0;
338
}
310
}
339
 
311
 
340
 
312
 
341
/// Position::set_state() computes the hash keys of the position, and other
313
/// Position::set_state() computes the hash keys of the position, and other
342
/// data that once computed is updated incrementally as moves are made.
314
/// data that once computed is updated incrementally as moves are made.
Line 346... Line 318...
346
void Position::set_state(StateInfo* si) const {
318
void Position::set_state(StateInfo* si) const {
347
 
319
 
348
  si->key = si->pawnKey = si->materialKey = 0;
320
  si->key = si->pawnKey = si->materialKey = 0;
349
  si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
321
  si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
350
  si->psq = SCORE_ZERO;
322
  si->psq = SCORE_ZERO;
351
 
-
 
352
  si->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
323
  si->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
-
 
324
 
-
 
325
  set_check_info(si);
353
 
326
 
354
  for (Bitboard b = pieces(); b; )
327
  for (Bitboard b = pieces(); b; )
355
  {
328
  {
356
      Square s = pop_lsb(&b);
329
      Square s = pop_lsb(&b);
357
      Piece pc = piece_on(s);
330
      Piece pc = piece_on(s);
358
      si->key ^= Zobrist::psq[color_of(pc)][type_of(pc)][s];
331
      si->key ^= Zobrist::psq[pc][s];
359
      si->psq += PSQT::psq[color_of(pc)][type_of(pc)][s];
332
      si->psq += PSQT::psq[pc][s];
360
  }
333
  }
361
 
334
 
362
  if (si->epSquare != SQ_NONE)
335
  if (si->epSquare != SQ_NONE)
363
      si->key ^= Zobrist::enpassant[file_of(si->epSquare)];
336
      si->key ^= Zobrist::enpassant[file_of(si->epSquare)];
364
 
337
 
Line 368... Line 341...
368
  si->key ^= Zobrist::castling[si->castlingRights];
341
  si->key ^= Zobrist::castling[si->castlingRights];
369
 
342
 
370
  for (Bitboard b = pieces(PAWN); b; )
343
  for (Bitboard b = pieces(PAWN); b; )
371
  {
344
  {
372
      Square s = pop_lsb(&b);
345
      Square s = pop_lsb(&b);
373
      si->pawnKey ^= Zobrist::psq[color_of(piece_on(s))][PAWN][s];
346
      si->pawnKey ^= Zobrist::psq[piece_on(s)][s];
374
  }
347
  }
375
 
348
 
376
  for (Color c = WHITE; c <= BLACK; ++c)
349
  for (Piece pc : Pieces)
-
 
350
  {
377
      for (PieceType pt = PAWN; pt <= KING; ++pt)
351
      if (type_of(pc) != PAWN && type_of(pc) != KING)
378
          for (int cnt = 0; cnt < pieceCount[c][pt]; ++cnt)
352
          si->nonPawnMaterial[color_of(pc)] += pieceCount[pc] * PieceValue[MG][pc];
379
              si->materialKey ^= Zobrist::psq[c][pt][cnt];
-
 
380
 
353
 
381
  for (Color c = WHITE; c <= BLACK; ++c)
-
 
382
      for (PieceType pt = KNIGHT; pt <= QUEEN; ++pt)
354
      for (int cnt = 0; cnt < pieceCount[pc]; ++cnt)
383
          si->nonPawnMaterial[c] += pieceCount[c][pt] * PieceValue[MG][pt];
355
          si->materialKey ^= Zobrist::psq[pc][cnt];
-
 
356
  }
384
}
357
}
385
 
358
 
386
 
359
 
387
/// Position::fen() returns a FEN representation of the position. In case of
360
/// Position::fen() returns a FEN representation of the position. In case of
388
/// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
361
/// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
Line 445... Line 418...
445
 
418
 
446
  return Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
419
  return Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
447
}
420
}
448
 
421
 
449
 
422
 
450
/// Position::check_blockers() returns a bitboard of all the pieces with color
423
/// Position::slider_blockers() returns a bitboard of all the pieces (both colors)
451
/// 'c' that are blocking check on the king with color 'kingColor'. A piece
424
/// that are blocking attacks on the square 's' from 'sliders'. A piece blocks a
452
/// blocks a check if removing that piece from the board would result in a
425
/// slider if removing that piece from the board would result in a position where
453
/// position where the king is in check. A check blocking piece can be either a
426
/// square 's' is attacked. For example, a king-attack blocking piece can be either
454
/// pinned or a discovered check piece, according if its color 'c' is the same
427
/// a pinned or a discovered check piece, according if its color is the opposite
455
/// or the opposite of 'kingColor'.
428
/// or the same of the color of the slider.
456
 
429
 
457
Bitboard Position::check_blockers(Color c, Color kingColor) const {
430
Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
458
 
431
 
459
  Bitboard b, pinners, result = 0;
432
  Bitboard result = 0;
460
  Square ksq = square<KING>(kingColor);
433
  pinners = 0;
461
 
434
 
462
  // Pinners are sliders that give check when a pinned piece is removed
435
  // Snipers are sliders that attack 's' when a piece is removed
463
  pinners = (  (pieces(  ROOK, QUEEN) & PseudoAttacks[ROOK  ][ksq])
436
  Bitboard snipers = (  (PseudoAttacks[ROOK  ][s] & pieces(QUEEN, ROOK))
464
             | (pieces(BISHOP, QUEEN) & PseudoAttacks[BISHOP][ksq])) & pieces(~kingColor);
437
                      | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
465
 
438
 
466
  while (pinners)
439
  while (snipers)
467
  {
440
  {
-
 
441
    Square sniperSq = pop_lsb(&snipers);
468
      b = between_bb(ksq, pop_lsb(&pinners)) & pieces();
442
    Bitboard b = between_bb(s, sniperSq) & pieces();
469
 
443
 
470
      if (!more_than_one(b))
444
    if (!more_than_one(b))
-
 
445
    {
471
          result |= b & pieces(c);
446
        result |= b;
-
 
447
        if (b & pieces(color_of(piece_on(s))))
-
 
448
            pinners |= sniperSq;
-
 
449
    }
472
  }
450
  }
473
  return result;
451
  return result;
474
}
452
}
475
 
453
 
476
 
454
 
Line 488... Line 466...
488
}
466
}
489
 
467
 
490
 
468
 
491
/// Position::legal() tests whether a pseudo-legal move is legal
469
/// Position::legal() tests whether a pseudo-legal move is legal
492
 
470
 
493
bool Position::legal(Move m, Bitboard pinned) const {
471
bool Position::legal(Move m) const {
494
 
472
 
495
  assert(is_ok(m));
473
  assert(is_ok(m));
496
  assert(pinned == pinned_pieces(sideToMove));
-
 
497
 
474
 
498
  Color us = sideToMove;
475
  Color us = sideToMove;
499
  Square from = from_sq(m);
476
  Square from = from_sq(m);
500
 
477
 
501
  assert(color_of(moved_piece(m)) == us);
478
  assert(color_of(moved_piece(m)) == us);
Line 526... Line 503...
526
  if (type_of(piece_on(from)) == KING)
503
  if (type_of(piece_on(from)) == KING)
527
      return type_of(m) == CASTLING || !(attackers_to(to_sq(m)) & pieces(~us));
504
      return type_of(m) == CASTLING || !(attackers_to(to_sq(m)) & pieces(~us));
528
 
505
 
529
  // A non-king move is legal if and only if it is not pinned or it
506
  // A non-king move is legal if and only if it is not pinned or it
530
  // is moving along the ray towards or away from the king.
507
  // is moving along the ray towards or away from the king.
531
  return   !pinned
-
 
532
        || !(pinned & from)
508
  return   !(pinned_pieces(us) & from)
533
        ||  aligned(from, to_sq(m), square<KING>(us));
509
        ||  aligned(from, to_sq(m), square<KING>(us));
534
}
510
}
535
 
511
 
536
 
512
 
537
/// Position::pseudo_legal() takes a random move and tests whether the move is
513
/// Position::pseudo_legal() takes a random move and tests whether the move is
Line 606... Line 582...
606
}
582
}
607
 
583
 
608
 
584
 
609
/// Position::gives_check() tests whether a pseudo-legal move gives a check
585
/// Position::gives_check() tests whether a pseudo-legal move gives a check
610
 
586
 
611
bool Position::gives_check(Move m, const CheckInfo& ci) const {
587
bool Position::gives_check(Move m) const {
612
 
588
 
613
  assert(is_ok(m));
589
  assert(is_ok(m));
614
  assert(ci.dcCandidates == discovered_check_candidates());
-
 
615
  assert(color_of(moved_piece(m)) == sideToMove);
590
  assert(color_of(moved_piece(m)) == sideToMove);
616
 
591
 
617
  Square from = from_sq(m);
592
  Square from = from_sq(m);
618
  Square to = to_sq(m);
593
  Square to = to_sq(m);
619
 
594
 
620
  // Is there a direct check?
595
  // Is there a direct check?
621
  if (ci.checkSquares[type_of(piece_on(from))] & to)
596
  if (st->checkSquares[type_of(piece_on(from))] & to)
622
      return true;
597
      return true;
623
 
598
 
624
  // Is there a discovered check?
599
  // Is there a discovered check?
625
  if (    ci.dcCandidates
-
 
626
      && (ci.dcCandidates & from)
600
  if (   (discovered_check_candidates() & from)
627
      && !aligned(from, to, ci.ksq))
601
      && !aligned(from, to, square<KING>(~sideToMove)))
628
      return true;
602
      return true;
629
 
603
 
630
  switch (type_of(m))
604
  switch (type_of(m))
631
  {
605
  {
632
  case NORMAL:
606
  case NORMAL:
633
      return false;
607
      return false;
634
 
608
 
635
  case PROMOTION:
609
  case PROMOTION:
636
      return attacks_bb(Piece(promotion_type(m)), to, pieces() ^ from) & ci.ksq;
610
      return attacks_bb(Piece(promotion_type(m)), to, pieces() ^ from) & square<KING>(~sideToMove);
637
 
611
 
638
  // En passant capture with check? We have already handled the case
612
  // En passant capture with check? We have already handled the case
639
  // of direct checks and ordinary discovered check, so the only case we
613
  // of direct checks and ordinary discovered check, so the only case we
640
  // need to handle is the unusual case of a discovered check through
614
  // need to handle is the unusual case of a discovered check through
641
  // the captured pawn.
615
  // the captured pawn.
642
  case ENPASSANT:
616
  case ENPASSANT:
643
  {
617
  {
644
      Square capsq = make_square(file_of(to), rank_of(from));
618
      Square capsq = make_square(file_of(to), rank_of(from));
645
      Bitboard b = (pieces() ^ from ^ capsq) | to;
619
      Bitboard b = (pieces() ^ from ^ capsq) | to;
646
 
620
 
647
      return  (attacks_bb<  ROOK>(ci.ksq, b) & pieces(sideToMove, QUEEN, ROOK))
621
      return  (attacks_bb<  ROOK>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, ROOK))
648
            | (attacks_bb<BISHOP>(ci.ksq, b) & pieces(sideToMove, QUEEN, BISHOP));
622
            | (attacks_bb<BISHOP>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, BISHOP));
649
  }
623
  }
650
  case CASTLING:
624
  case CASTLING:
651
  {
625
  {
652
      Square kfrom = from;
626
      Square kfrom = from;
653
      Square rfrom = to; // Castling is encoded as 'King captures the rook'
627
      Square rfrom = to; // Castling is encoded as 'King captures the rook'
654
      Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1);
628
      Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1);
655
      Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1);
629
      Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1);
656
 
630
 
657
      return   (PseudoAttacks[ROOK][rto] & ci.ksq)
631
      return   (PseudoAttacks[ROOK][rto] & square<KING>(~sideToMove))
658
            && (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & ci.ksq);
632
            && (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove));
659
  }
633
  }
660
  default:
634
  default:
661
      assert(false);
635
      assert(false);
662
      return false;
636
      return false;
663
  }
637
  }
Line 691... Line 665...
691
 
665
 
692
  Color us = sideToMove;
666
  Color us = sideToMove;
693
  Color them = ~us;
667
  Color them = ~us;
694
  Square from = from_sq(m);
668
  Square from = from_sq(m);
695
  Square to = to_sq(m);
669
  Square to = to_sq(m);
696
  PieceType pt = type_of(piece_on(from));
670
  Piece pc = piece_on(from);
697
  PieceType captured = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to));
671
  Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);
698
 
672
 
699
  assert(color_of(piece_on(from)) == us);
673
  assert(color_of(pc) == us);
700
  assert(piece_on(to) == NO_PIECE || color_of(piece_on(to)) == (type_of(m) != CASTLING ? them : us));
674
  assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
701
  assert(captured != KING);
675
  assert(type_of(captured) != KING);
702
 
676
 
703
  if (type_of(m) == CASTLING)
677
  if (type_of(m) == CASTLING)
704
  {
678
  {
705
      assert(pt == KING);
679
      assert(pc == make_piece(us, KING));
-
 
680
      assert(captured == make_piece(us, ROOK));
706
 
681
 
707
      Square rfrom, rto;
682
      Square rfrom, rto;
708
      do_castling<true>(us, from, to, rfrom, rto);
683
      do_castling<true>(us, from, to, rfrom, rto);
709
 
684
 
710
      captured = NO_PIECE_TYPE;
-
 
711
      st->psq += PSQT::psq[us][ROOK][rto] - PSQT::psq[us][ROOK][rfrom];
685
      st->psq += PSQT::psq[captured][rto] - PSQT::psq[captured][rfrom];
712
      k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
686
      k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
-
 
687
      captured = NO_PIECE;
713
  }
688
  }
714
 
689
 
715
  if (captured)
690
  if (captured)
716
  {
691
  {
717
      Square capsq = to;
692
      Square capsq = to;
718
 
693
 
719
      // If the captured piece is a pawn, update pawn hash key, otherwise
694
      // If the captured piece is a pawn, update pawn hash key, otherwise
720
      // update non-pawn material.
695
      // update non-pawn material.
721
      if (captured == PAWN)
696
      if (type_of(captured) == PAWN)
722
      {
697
      {
723
          if (type_of(m) == ENPASSANT)
698
          if (type_of(m) == ENPASSANT)
724
          {
699
          {
725
              capsq -= pawn_push(us);
700
              capsq -= pawn_push(us);
726
 
701
 
727
              assert(pt == PAWN);
702
              assert(pc == make_piece(us, PAWN));
728
              assert(to == st->epSquare);
703
              assert(to == st->epSquare);
729
              assert(relative_rank(us, to) == RANK_6);
704
              assert(relative_rank(us, to) == RANK_6);
730
              assert(piece_on(to) == NO_PIECE);
705
              assert(piece_on(to) == NO_PIECE);
731
              assert(piece_on(capsq) == make_piece(them, PAWN));
706
              assert(piece_on(capsq) == make_piece(them, PAWN));
732
 
707
 
733
              board[capsq] = NO_PIECE; // Not done by remove_piece()
708
              board[capsq] = NO_PIECE; // Not done by remove_piece()
734
          }
709
          }
735
 
710
 
736
          st->pawnKey ^= Zobrist::psq[them][PAWN][capsq];
711
          st->pawnKey ^= Zobrist::psq[captured][capsq];
737
      }
712
      }
738
      else
713
      else
739
          st->nonPawnMaterial[them] -= PieceValue[MG][captured];
714
          st->nonPawnMaterial[them] -= PieceValue[MG][captured];
740
 
715
 
741
      // Update board and piece lists
716
      // Update board and piece lists
742
      remove_piece(them, captured, capsq);
717
      remove_piece(captured, capsq);
743
 
718
 
744
      // Update material hash key and prefetch access to materialTable
719
      // Update material hash key and prefetch access to materialTable
745
      k ^= Zobrist::psq[them][captured][capsq];
720
      k ^= Zobrist::psq[captured][capsq];
746
      st->materialKey ^= Zobrist::psq[them][captured][pieceCount[them][captured]];
721
      st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
747
      prefetch(thisThread->materialTable[st->materialKey]);
722
      prefetch(thisThread->materialTable[st->materialKey]);
748
 
723
 
749
      // Update incremental scores
724
      // Update incremental scores
750
      st->psq -= PSQT::psq[them][captured][capsq];
725
      st->psq -= PSQT::psq[captured][capsq];
751
 
726
 
752
      // Reset rule 50 counter
727
      // Reset rule 50 counter
753
      st->rule50 = 0;
728
      st->rule50 = 0;
754
  }
729
  }
755
 
730
 
756
  // Update hash key
731
  // Update hash key
757
  k ^= Zobrist::psq[us][pt][from] ^ Zobrist::psq[us][pt][to];
732
  k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
758
 
733
 
759
  // Reset en passant square
734
  // Reset en passant square
760
  if (st->epSquare != SQ_NONE)
735
  if (st->epSquare != SQ_NONE)
761
  {
736
  {
762
      k ^= Zobrist::enpassant[file_of(st->epSquare)];
737
      k ^= Zobrist::enpassant[file_of(st->epSquare)];
Line 771... Line 746...
771
      st->castlingRights &= ~cr;
746
      st->castlingRights &= ~cr;
772
  }
747
  }
773
 
748
 
774
  // Move the piece. The tricky Chess960 castling is handled earlier
749
  // Move the piece. The tricky Chess960 castling is handled earlier
775
  if (type_of(m) != CASTLING)
750
  if (type_of(m) != CASTLING)
776
      move_piece(us, pt, from, to);
751
      move_piece(pc, from, to);
777
 
752
 
778
  // If the moving piece is a pawn do some special extra work
753
  // If the moving piece is a pawn do some special extra work
779
  if (pt == PAWN)
754
  if (type_of(pc) == PAWN)
780
  {
755
  {
781
      // Set en-passant square if the moved pawn can be captured
756
      // Set en-passant square if the moved pawn can be captured
782
      if (   (int(to) ^ int(from)) == 16
757
      if (   (int(to) ^ int(from)) == 16
783
          && (attacks_from<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
758
          && (attacks_from<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
784
      {
759
      {
Line 786... Line 761...
786
          k ^= Zobrist::enpassant[file_of(st->epSquare)];
761
          k ^= Zobrist::enpassant[file_of(st->epSquare)];
787
      }
762
      }
788
 
763
 
789
      else if (type_of(m) == PROMOTION)
764
      else if (type_of(m) == PROMOTION)
790
      {
765
      {
791
          PieceType promotion = promotion_type(m);
766
          Piece promotion = make_piece(us, promotion_type(m));
792
 
767
 
793
          assert(relative_rank(us, to) == RANK_8);
768
          assert(relative_rank(us, to) == RANK_8);
794
          assert(promotion >= KNIGHT && promotion <= QUEEN);
769
          assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
795
 
770
 
796
          remove_piece(us, PAWN, to);
771
          remove_piece(pc, to);
797
          put_piece(us, promotion, to);
772
          put_piece(promotion, to);
798
 
773
 
799
          // Update hash keys
774
          // Update hash keys
800
          k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to];
775
          k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
801
          st->pawnKey ^= Zobrist::psq[us][PAWN][to];
776
          st->pawnKey ^= Zobrist::psq[pc][to];
802
          st->materialKey ^=  Zobrist::psq[us][promotion][pieceCount[us][promotion]-1]
777
          st->materialKey ^=  Zobrist::psq[promotion][pieceCount[promotion]-1]
803
                            ^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
778
                            ^ Zobrist::psq[pc][pieceCount[pc]];
804
 
779
 
805
          // Update incremental score
780
          // Update incremental score
806
          st->psq += PSQT::psq[us][promotion][to] - PSQT::psq[us][PAWN][to];
781
          st->psq += PSQT::psq[promotion][to] - PSQT::psq[pc][to];
807
 
782
 
808
          // Update material
783
          // Update material
809
          st->nonPawnMaterial[us] += PieceValue[MG][promotion];
784
          st->nonPawnMaterial[us] += PieceValue[MG][promotion];
810
      }
785
      }
811
 
786
 
812
      // Update pawn hash key and prefetch access to pawnsTable
787
      // Update pawn hash key and prefetch access to pawnsTable
813
      st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to];
788
      st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
814
      prefetch(thisThread->pawnsTable[st->pawnKey]);
789
      prefetch(thisThread->pawnsTable[st->pawnKey]);
815
 
790
 
816
      // Reset rule 50 draw counter
791
      // Reset rule 50 draw counter
817
      st->rule50 = 0;
792
      st->rule50 = 0;
818
  }
793
  }
819
 
794
 
820
  // Update incremental scores
795
  // Update incremental scores
821
  st->psq += PSQT::psq[us][pt][to] - PSQT::psq[us][pt][from];
796
  st->psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];
822
 
797
 
823
  // Set capture piece
798
  // Set capture piece
824
  st->capturedType = captured;
799
  st->capturedPiece = captured;
825
 
800
 
826
  // Update the key with the final value
801
  // Update the key with the final value
827
  st->key = k;
802
  st->key = k;
828
 
803
 
829
  // Calculate checkers bitboard (if move gives check)
804
  // Calculate checkers bitboard (if move gives check)
830
  st->checkersBB = givesCheck ? attackers_to(square<KING>(them)) & pieces(us) : 0;
805
  st->checkersBB = givesCheck ? attackers_to(square<KING>(them)) & pieces(us) : 0;
831
 
806
 
832
  sideToMove = ~sideToMove;
807
  sideToMove = ~sideToMove;
-
 
808
 
-
 
809
  // Update king attacks used for fast check detection
-
 
810
  set_check_info(st);
833
 
811
 
834
  assert(pos_is_ok());
812
  assert(pos_is_ok());
835
}
813
}
836
 
814
 
837
 
815
 
Line 845... Line 823...
845
  sideToMove = ~sideToMove;
823
  sideToMove = ~sideToMove;
846
 
824
 
847
  Color us = sideToMove;
825
  Color us = sideToMove;
848
  Square from = from_sq(m);
826
  Square from = from_sq(m);
849
  Square to = to_sq(m);
827
  Square to = to_sq(m);
850
  PieceType pt = type_of(piece_on(to));
828
  Piece pc = piece_on(to);
851
 
829
 
852
  assert(empty(from) || type_of(m) == CASTLING);
830
  assert(empty(from) || type_of(m) == CASTLING);
853
  assert(st->capturedType != KING);
831
  assert(type_of(st->capturedPiece) != KING);
854
 
832
 
855
  if (type_of(m) == PROMOTION)
833
  if (type_of(m) == PROMOTION)
856
  {
834
  {
857
      assert(relative_rank(us, to) == RANK_8);
835
      assert(relative_rank(us, to) == RANK_8);
858
      assert(pt == promotion_type(m));
836
      assert(type_of(pc) == promotion_type(m));
859
      assert(pt >= KNIGHT && pt <= QUEEN);
837
      assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);
860
 
838
 
861
      remove_piece(us, pt, to);
839
      remove_piece(pc, to);
862
      put_piece(us, PAWN, to);
840
      pc = make_piece(us, PAWN);
863
      pt = PAWN;
841
      put_piece(pc, to);
864
  }
842
  }
865
 
843
 
866
  if (type_of(m) == CASTLING)
844
  if (type_of(m) == CASTLING)
867
  {
845
  {
868
      Square rfrom, rto;
846
      Square rfrom, rto;
869
      do_castling<false>(us, from, to, rfrom, rto);
847
      do_castling<false>(us, from, to, rfrom, rto);
870
  }
848
  }
871
  else
849
  else
872
  {
850
  {
873
      move_piece(us, pt, to, from); // Put the piece back at the source square
851
      move_piece(pc, to, from); // Put the piece back at the source square
874
 
852
 
875
      if (st->capturedType)
853
      if (st->capturedPiece)
876
      {
854
      {
877
          Square capsq = to;
855
          Square capsq = to;
878
 
856
 
879
          if (type_of(m) == ENPASSANT)
857
          if (type_of(m) == ENPASSANT)
880
          {
858
          {
881
              capsq -= pawn_push(us);
859
              capsq -= pawn_push(us);
882
 
860
 
883
              assert(pt == PAWN);
861
              assert(type_of(pc) == PAWN);
884
              assert(to == st->previous->epSquare);
862
              assert(to == st->previous->epSquare);
885
              assert(relative_rank(us, to) == RANK_6);
863
              assert(relative_rank(us, to) == RANK_6);
886
              assert(piece_on(capsq) == NO_PIECE);
864
              assert(piece_on(capsq) == NO_PIECE);
887
              assert(st->capturedType == PAWN);
865
              assert(st->capturedPiece == make_piece(~us, PAWN));
888
          }
866
          }
889
 
867
 
890
          put_piece(~us, st->capturedType, capsq); // Restore the captured piece
868
          put_piece(st->capturedPiece, capsq); // Restore the captured piece
891
      }
869
      }
892
  }
870
  }
893
 
871
 
894
  // Finally point our state pointer back to the previous state
872
  // Finally point our state pointer back to the previous state
895
  st = st->previous;
873
  st = st->previous;
Line 898... Line 876...
898
  assert(pos_is_ok());
876
  assert(pos_is_ok());
899
}
877
}
900
 
878
 
901
 
879
 
902
/// Position::do_castling() is a helper used to do/undo a castling move. This
880
/// Position::do_castling() is a helper used to do/undo a castling move. This
903
/// is a bit tricky, especially in Chess960.
881
/// is a bit tricky in Chess960 where from/to squares can overlap.
904
template<bool Do>
882
template<bool Do>
905
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
883
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
906
 
884
 
907
  bool kingSide = to > from;
885
  bool kingSide = to > from;
908
  rfrom = to; // Castling is encoded as "king captures friendly rook"
886
  rfrom = to; // Castling is encoded as "king captures friendly rook"
909
  rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
887
  rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
910
  to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
888
  to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
911
 
889
 
912
  // Remove both pieces first since squares could overlap in Chess960
890
  // Remove both pieces first since squares could overlap in Chess960
913
  remove_piece(us, KING, Do ? from : to);
891
  remove_piece(make_piece(us, KING), Do ? from : to);
914
  remove_piece(us, ROOK, Do ? rfrom : rto);
892
  remove_piece(make_piece(us, ROOK), Do ? rfrom : rto);
915
  board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
893
  board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
916
  put_piece(us, KING, Do ? to : from);
894
  put_piece(make_piece(us, KING), Do ? to : from);
917
  put_piece(us, ROOK, Do ? rto : rfrom);
895
  put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
918
}
896
}
919
 
897
 
920
 
898
 
921
/// Position::do(undo)_null_move() is used to do(undo) a "null move": It flips
899
/// Position::do(undo)_null_move() is used to do(undo) a "null move": It flips
922
/// the side to move without executing any move on the board.
900
/// the side to move without executing any move on the board.
Line 941... Line 919...
941
 
919
 
942
  ++st->rule50;
920
  ++st->rule50;
943
  st->pliesFromNull = 0;
921
  st->pliesFromNull = 0;
944
 
922
 
945
  sideToMove = ~sideToMove;
923
  sideToMove = ~sideToMove;
-
 
924
 
-
 
925
  set_check_info(st);
946
 
926
 
947
  assert(pos_is_ok());
927
  assert(pos_is_ok());
948
}
928
}
949
 
929
 
950
void Position::undo_null_move() {
930
void Position::undo_null_move() {
Line 960... Line 940...
960
/// for speculative prefetch. It doesn't recognize special moves like castling,
940
/// for speculative prefetch. It doesn't recognize special moves like castling,
961
/// en-passant and promotions.
941
/// en-passant and promotions.
962
 
942
 
963
Key Position::key_after(Move m) const {
943
Key Position::key_after(Move m) const {
964
 
944
 
965
  Color us = sideToMove;
-
 
966
  Square from = from_sq(m);
945
  Square from = from_sq(m);
967
  Square to = to_sq(m);
946
  Square to = to_sq(m);
968
  PieceType pt = type_of(piece_on(from));
947
  Piece pc = piece_on(from);
969
  PieceType captured = type_of(piece_on(to));
948
  Piece captured = piece_on(to);
970
  Key k = st->key ^ Zobrist::side;
949
  Key k = st->key ^ Zobrist::side;
971
 
950
 
972
  if (captured)
951
  if (captured)
973
      k ^= Zobrist::psq[~us][captured][to];
952
      k ^= Zobrist::psq[captured][to];
974
 
953
 
975
  return k ^ Zobrist::psq[us][pt][to] ^ Zobrist::psq[us][pt][from];
954
  return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
976
}
955
}
977
 
956
 
978
 
957
 
979
/// Position::see() is a static exchange evaluator: It tries to estimate the
958
/// Position::see_ge (Static Exchange Evaluation Greater or Equal) tests if the
-
 
959
/// SEE value of move is greater or equal to the given value. We'll use an
980
/// material gain or loss resulting from a move.
960
/// algorithm similar to alpha-beta pruning with a null window.
981
 
961
 
982
Value Position::see_sign(Move m) const {
962
bool Position::see_ge(Move m, Value v) const {
983
 
963
 
984
  assert(is_ok(m));
964
  assert(is_ok(m));
985
 
965
 
986
  // Early return if SEE cannot be negative because captured piece value
966
  // Castling moves are implemented as king capturing the rook so cannot be
987
  // is not less then capturing one. Note that king moves always return
967
  // handled correctly. Simply assume the SEE value is VALUE_ZERO that is always
988
  // here because king midgame value is set to 0.
968
  // correct unless in the rare case the rook ends up under attack.
989
  if (PieceValue[MG][moved_piece(m)] <= PieceValue[MG][piece_on(to_sq(m))])
969
  if (type_of(m) == CASTLING)
990
      return VALUE_KNOWN_WIN;
970
      return VALUE_ZERO >= v;
991
 
971
 
-
 
972
  Square from = from_sq(m), to = to_sq(m);
-
 
973
  PieceType nextVictim = type_of(piece_on(from));
-
 
974
  Color stm = ~color_of(piece_on(from)); // First consider opponent's move
-
 
975
  Value balance; // Values of the pieces taken by us minus opponent's ones
992
  return see(m);
976
  Bitboard occupied, stmAttackers;
993
}
-
 
994
 
977
 
-
 
978
  if (type_of(m) == ENPASSANT)
-
 
979
  {
-
 
980
      occupied = SquareBB[to - pawn_push(~stm)]; // Remove the captured pawn
-
 
981
      balance = PieceValue[MG][PAWN];
-
 
982
  }
-
 
983
  else
-
 
984
  {
995
Value Position::see(Move m) const {
985
      balance = PieceValue[MG][piece_on(to)];
-
 
986
      occupied = 0;
-
 
987
  }
996
 
988
 
997
  Square from, to;
-
 
998
  Bitboard occupied, attackers, stmAttackers;
-
 
999
  Value swapList[32];
-
 
1000
  int slIndex = 1;
989
  if (balance < v)
1001
  PieceType captured;
990
      return false;
1002
  Color stm;
-
 
1003
 
991
 
-
 
992
  if (nextVictim == KING)
1004
  assert(is_ok(m));
993
      return true;
1005
 
994
 
1006
  from = from_sq(m);
-
 
1007
  to = to_sq(m);
-
 
1008
  swapList[0] = PieceValue[MG][piece_on(to)];
995
  balance -= PieceValue[MG][nextVictim];
1009
  stm = color_of(piece_on(from));
-
 
1010
  occupied = pieces() ^ from;
-
 
1011
 
996
 
1012
  // Castling moves are implemented as king capturing the rook so cannot
-
 
1013
  // be handled correctly. Simply return VALUE_ZERO that is always correct
-
 
1014
  // unless in the rare case the rook ends up under attack.
-
 
1015
  if (type_of(m) == CASTLING)
997
  if (balance >= v)
1016
      return VALUE_ZERO;
998
      return true;
1017
 
999
 
1018
  if (type_of(m) == ENPASSANT)
-
 
1019
  {
-
 
1020
      occupied ^= to - pawn_push(stm); // Remove the captured pawn
1000
  bool relativeStm = true; // True if the opponent is to move
1021
      swapList[0] = PieceValue[MG][PAWN];
1001
  occupied ^= pieces() ^ from ^ to;
1022
  }
-
 
1023
 
1002
 
1024
  // Find all attackers to the destination square, with the moving piece
1003
  // Find all attackers to the destination square, with the moving piece removed,
1025
  // removed, but possibly an X-ray attacker added behind it.
1004
  // but possibly an X-ray attacker added behind it.
1026
  attackers = attackers_to(to, occupied) & occupied;
1005
  Bitboard attackers = attackers_to(to, occupied) & occupied;
1027
 
1006
 
1028
  // If the opponent has no attackers we are finished
-
 
1029
  stm = ~stm;
1007
  while (true)
-
 
1008
  {
1030
  stmAttackers = attackers & pieces(stm);
1009
      stmAttackers = attackers & pieces(stm);
1031
  if (!stmAttackers)
-
 
1032
      return swapList[0];
-
 
1033
 
1010
 
1034
  // The destination square is defended, which makes things rather more
1011
      // Don't allow pinned pieces to attack pieces except the king as long all
1035
  // difficult to compute. We proceed by building up a "swap list" containing
-
 
1036
  // the material gain or loss at each stop in a sequence of captures to the
-
 
1037
  // destination square, where the sides alternately capture, and always
1012
      // pinners are on their original square.
1038
  // capture with the least valuable piece. After each capture, we look for
-
 
1039
  // new X-ray attacks from behind the capturing piece.
1013
      if (!(st->pinnersForKing[stm] & ~occupied))
1040
  captured = type_of(piece_on(from));
1014
          stmAttackers &= ~st->blockersForKing[stm];
1041
 
1015
 
1042
  do {
-
 
1043
      assert(slIndex < 32);
1016
      if (!stmAttackers)
1044
 
-
 
1045
      // Add the new entry to the swap list
1017
          return relativeStm;
1046
      swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured];
-
 
1047
 
1018
 
1048
      // Locate and remove the next least valuable attacker
1019
      // Locate and remove the next least valuable attacker
1049
      captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
1020
      nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
1050
      stm = ~stm;
-
 
1051
      stmAttackers = attackers & pieces(stm);
-
 
1052
      ++slIndex;
-
 
1053
 
1021
 
-
 
1022
      if (nextVictim == KING)
1054
  } while (stmAttackers && (captured != KING || (--slIndex, false))); // Stop before a king capture
1023
          return relativeStm == bool(attackers & pieces(~stm));
1055
 
1024
 
1056
  // Having built the swap list, we negamax through it to find the best
1025
      balance += relativeStm ?  PieceValue[MG][nextVictim]
1057
  // achievable score from the point of view of the side to move.
1026
                             : -PieceValue[MG][nextVictim];
1058
  while (--slIndex)
-
 
1059
      swapList[slIndex - 1] = std::min(-swapList[slIndex], swapList[slIndex - 1]);
-
 
1060
 
1027
 
-
 
1028
      relativeStm = !relativeStm;
-
 
1029
 
-
 
1030
      if (relativeStm == (balance >= v))
1061
  return swapList[0];
1031
          return relativeStm;
-
 
1032
 
-
 
1033
      stm = ~stm;
-
 
1034
  }
1062
}
1035
}
1063
 
1036
 
1064
 
1037
 
1065
/// Position::is_draw() tests whether the position is drawn by 50-move rule
1038
/// Position::is_draw() tests whether the position is drawn by 50-move rule
1066
/// or by repetition. It does not detect stalemates.
1039
/// or by repetition. It does not detect stalemates.
Line 1110... Line 1083...
1110
  f += (token == "-" ? token : token.replace(1, 1, token[1] == '3' ? "6" : "3"));
1083
  f += (token == "-" ? token : token.replace(1, 1, token[1] == '3' ? "6" : "3"));
1111
 
1084
 
1112
  std::getline(ss, token); // Half and full moves
1085
  std::getline(ss, token); // Half and full moves
1113
  f += token;
1086
  f += token;
1114
 
1087
 
1115
  set(f, is_chess960(), this_thread());
1088
  set(f, is_chess960(), st, this_thread());
1116
 
1089
 
1117
  assert(pos_is_ok());
1090
  assert(pos_is_ok());
1118
}
1091
}
1119
 
1092
 
1120
 
1093
 
Line 1165... Line 1138...
1165
          if (std::memcmp(&si, st, sizeof(StateInfo)))
1138
          if (std::memcmp(&si, st, sizeof(StateInfo)))
1166
              return false;
1139
              return false;
1167
      }
1140
      }
1168
 
1141
 
1169
      if (step == Lists)
1142
      if (step == Lists)
1170
          for (Color c = WHITE; c <= BLACK; ++c)
1143
          for (Piece pc : Pieces)
1171
              for (PieceType pt = PAWN; pt <= KING; ++pt)
-
 
1172
              {
1144
          {
1173
                  if (pieceCount[c][pt] != popcount<Full>(pieces(c, pt)))
1145
              if (pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc))))
1174
                      return false;
1146
                  return false;
1175
 
1147
 
1176
                  for (int i = 0; i < pieceCount[c][pt];  ++i)
1148
              for (int i = 0; i < pieceCount[pc]; ++i)
1177
                      if (   board[pieceList[c][pt][i]] != make_piece(c, pt)
1149
                  if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
1178
                          || index[pieceList[c][pt][i]] != i)
-
 
1179
                          return false;
1150
                      return false;
1180
              }
1151
          }
1181
 
1152
 
1182
      if (step == Castling)
1153
      if (step == Castling)
1183
          for (Color c = WHITE; c <= BLACK; ++c)
1154
          for (Color c = WHITE; c <= BLACK; ++c)
1184
              for (CastlingSide s = KING_SIDE; s <= QUEEN_SIDE; s = CastlingSide(s + 1))
1155
              for (CastlingSide s = KING_SIDE; s <= QUEEN_SIDE; s = CastlingSide(s + 1))
1185
              {
1156
              {