]> git.sesse.net Git - stockfish/blob - src/position.cpp
Revert "Simplify En Passant"
[stockfish] / src / position.cpp
1 /*
2   Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3   Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
4
5   Stockfish is free software: you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation, either version 3 of the License, or
8   (at your option) any later version.
9
10   Stockfish is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <algorithm>
20 #include <cassert>
21 #include <cstddef> // For offsetof()
22 #include <cstring> // For std::memset, std::memcmp
23 #include <iomanip>
24 #include <sstream>
25
26 #include "bitboard.h"
27 #include "misc.h"
28 #include "movegen.h"
29 #include "position.h"
30 #include "thread.h"
31 #include "tt.h"
32 #include "uci.h"
33 #include "syzygy/tbprobe.h"
34
35 using std::string;
36
37 namespace Stockfish {
38
39 namespace Zobrist {
40
41   Key psq[PIECE_NB][SQUARE_NB];
42   Key enpassant[FILE_NB];
43   Key castling[CASTLING_RIGHT_NB];
44   Key side, noPawns;
45 }
46
47 namespace {
48
49 const string PieceToChar(" PNBRQK  pnbrqk");
50
51 constexpr Piece Pieces[] = { W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
52                              B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING };
53 } // namespace
54
55
56 /// operator<<(Position) returns an ASCII representation of the position
57
58 std::ostream& operator<<(std::ostream& os, const Position& pos) {
59
60   os << "\n +---+---+---+---+---+---+---+---+\n";
61
62   for (Rank r = RANK_8; r >= RANK_1; --r)
63   {
64       for (File f = FILE_A; f <= FILE_H; ++f)
65           os << " | " << PieceToChar[pos.piece_on(make_square(f, r))];
66
67       os << " | " << (1 + r) << "\n +---+---+---+---+---+---+---+---+\n";
68   }
69
70   os << "   a   b   c   d   e   f   g   h\n"
71      << "\nFen: " << pos.fen() << "\nKey: " << std::hex << std::uppercase
72      << std::setfill('0') << std::setw(16) << pos.key()
73      << std::setfill(' ') << std::dec << "\nCheckers: ";
74
75   for (Bitboard b = pos.checkers(); b; )
76       os << UCI::square(pop_lsb(b)) << " ";
77
78   if (    int(Tablebases::MaxCardinality) >= popcount(pos.pieces())
79       && !pos.can_castle(ANY_CASTLING))
80   {
81       StateInfo st;
82       ASSERT_ALIGNED(&st, Eval::NNUE::CacheLineSize);
83
84       Position p;
85       p.set(pos.fen(), pos.is_chess960(), &st, pos.this_thread());
86       Tablebases::ProbeState s1, s2;
87       Tablebases::WDLScore wdl = Tablebases::probe_wdl(p, &s1);
88       int dtz = Tablebases::probe_dtz(p, &s2);
89       os << "\nTablebases WDL: " << std::setw(4) << wdl << " (" << s1 << ")"
90          << "\nTablebases DTZ: " << std::setw(4) << dtz << " (" << s2 << ")";
91   }
92
93   return os;
94 }
95
96
97 // Marcel van Kervinck's cuckoo algorithm for fast detection of "upcoming repetition"
98 // situations. Description of the algorithm in the following paper:
99 // https://marcelk.net/2013-04-06/paper/upcoming-rep-v2.pdf
100
101 // First and second hash functions for indexing the cuckoo tables
102 inline int H1(Key h) { return h & 0x1fff; }
103 inline int H2(Key h) { return (h >> 16) & 0x1fff; }
104
105 // Cuckoo tables with Zobrist hashes of valid reversible moves, and the moves themselves
106 Key cuckoo[8192];
107 Move cuckooMove[8192];
108
109
110 /// Position::init() initializes at startup the various arrays used to compute hash keys
111
112 void Position::init() {
113
114   PRNG rng(1070372);
115
116   for (Piece pc : Pieces)
117       for (Square s = SQ_A1; s <= SQ_H8; ++s)
118           Zobrist::psq[pc][s] = rng.rand<Key>();
119
120   for (File f = FILE_A; f <= FILE_H; ++f)
121       Zobrist::enpassant[f] = rng.rand<Key>();
122
123   for (int cr = NO_CASTLING; cr <= ANY_CASTLING; ++cr)
124       Zobrist::castling[cr] = rng.rand<Key>();
125
126   Zobrist::side = rng.rand<Key>();
127   Zobrist::noPawns = rng.rand<Key>();
128
129   // Prepare the cuckoo tables
130   std::memset(cuckoo, 0, sizeof(cuckoo));
131   std::memset(cuckooMove, 0, sizeof(cuckooMove));
132   int count = 0;
133   for (Piece pc : Pieces)
134       for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
135           for (Square s2 = Square(s1 + 1); s2 <= SQ_H8; ++s2)
136               if ((type_of(pc) != PAWN) && (attacks_bb(type_of(pc), s1, 0) & s2))
137               {
138                   Move move = make_move(s1, s2);
139                   Key key = Zobrist::psq[pc][s1] ^ Zobrist::psq[pc][s2] ^ Zobrist::side;
140                   int i = H1(key);
141                   while (true)
142                   {
143                       std::swap(cuckoo[i], key);
144                       std::swap(cuckooMove[i], move);
145                       if (move == MOVE_NONE) // Arrived at empty slot?
146                           break;
147                       i = (i == H1(key)) ? H2(key) : H1(key); // Push victim to alternative slot
148                   }
149                   count++;
150              }
151   assert(count == 3668);
152 }
153
154
155 /// Position::set() initializes the position object with the given FEN string.
156 /// This function is not very robust - make sure that input FENs are correct,
157 /// this is assumed to be the responsibility of the GUI.
158
159 Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Thread* th) {
160 /*
161    A FEN string defines a particular position using only the ASCII character set.
162
163    A FEN string contains six fields separated by a space. The fields are:
164
165    1) Piece placement (from white's perspective). Each rank is described, starting
166       with rank 8 and ending with rank 1. Within each rank, the contents of each
167       square are described from file A through file H. Following the Standard
168       Algebraic Notation (SAN), each piece is identified by a single letter taken
169       from the standard English names. White pieces are designated using upper-case
170       letters ("PNBRQK") whilst Black uses lowercase ("pnbrqk"). Blank squares are
171       noted using digits 1 through 8 (the number of blank squares), and "/"
172       separates ranks.
173
174    2) Active color. "w" means white moves next, "b" means black.
175
176    3) Castling availability. If neither side can castle, this is "-". Otherwise,
177       this has one or more letters: "K" (White can castle kingside), "Q" (White
178       can castle queenside), "k" (Black can castle kingside), and/or "q" (Black
179       can castle queenside).
180
181    4) En passant target square (in algebraic notation). If there's no en passant
182       target square, this is "-". If a pawn has just made a 2-square move, this
183       is the position "behind" the pawn. Following X-FEN standard, this is recorded only
184       if there is a pawn in position to make an en passant capture, and if there really
185       is a pawn that might have advanced two squares.
186
187    5) Halfmove clock. This is the number of halfmoves since the last pawn advance
188       or capture. This is used to determine if a draw can be claimed under the
189       fifty-move rule.
190
191    6) Fullmove number. The number of the full move. It starts at 1, and is
192       incremented after Black's move.
193 */
194
195   unsigned char col, row, token;
196   size_t idx;
197   Square sq = SQ_A8;
198   std::istringstream ss(fenStr);
199
200   std::memset(this, 0, sizeof(Position));
201   std::memset(si, 0, sizeof(StateInfo));
202   st = si;
203
204   ss >> std::noskipws;
205
206   // 1. Piece placement
207   while ((ss >> token) && !isspace(token))
208   {
209       if (isdigit(token))
210           sq += (token - '0') * EAST; // Advance the given number of files
211
212       else if (token == '/')
213           sq += 2 * SOUTH;
214
215       else if ((idx = PieceToChar.find(token)) != string::npos) {
216           put_piece(Piece(idx), sq);
217           ++sq;
218       }
219   }
220
221   // 2. Active color
222   ss >> token;
223   sideToMove = (token == 'w' ? WHITE : BLACK);
224   ss >> token;
225
226   // 3. Castling availability. Compatible with 3 standards: Normal FEN standard,
227   // Shredder-FEN that uses the letters of the columns on which the rooks began
228   // the game instead of KQkq and also X-FEN standard that, in case of Chess960,
229   // if an inner rook is associated with the castling right, the castling tag is
230   // replaced by the file letter of the involved rook, as for the Shredder-FEN.
231   while ((ss >> token) && !isspace(token))
232   {
233       Square rsq;
234       Color c = islower(token) ? BLACK : WHITE;
235       Piece rook = make_piece(c, ROOK);
236
237       token = char(toupper(token));
238
239       if (token == 'K')
240           for (rsq = relative_square(c, SQ_H1); piece_on(rsq) != rook; --rsq) {}
241
242       else if (token == 'Q')
243           for (rsq = relative_square(c, SQ_A1); piece_on(rsq) != rook; ++rsq) {}
244
245       else if (token >= 'A' && token <= 'H')
246           rsq = make_square(File(token - 'A'), relative_rank(c, RANK_1));
247
248       else
249           continue;
250
251       set_castling_right(c, rsq);
252   }
253
254   // 4. En passant square.
255   // Ignore if square is invalid or not on side to move relative rank 6.
256   bool enpassant = false;
257
258   if (   ((ss >> col) && (col >= 'a' && col <= 'h'))
259       && ((ss >> row) && (row == (sideToMove == WHITE ? '6' : '3'))))
260   {
261       st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
262
263       // En passant square will be considered only if
264       // a) side to move have a pawn threatening epSquare
265       // b) there is an enemy pawn in front of epSquare
266       // c) there is no piece on epSquare or behind epSquare
267       enpassant = pawn_attacks_bb(~sideToMove, st->epSquare) & pieces(sideToMove, PAWN)
268                && (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove)))
269                && !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove))));
270   }
271
272   if (!enpassant)
273       st->epSquare = SQ_NONE;
274
275   // 5-6. Halfmove clock and fullmove number
276   ss >> std::skipws >> st->rule50 >> gamePly;
277
278   // Convert from fullmove starting from 1 to gamePly starting from 0,
279   // handle also common incorrect FEN with fullmove = 0.
280   gamePly = std::max(2 * (gamePly - 1), 0) + (sideToMove == BLACK);
281
282   chess960 = isChess960;
283   thisThread = th;
284   set_state(st);
285   st->accumulator.state[WHITE] = Eval::NNUE::INIT;
286   st->accumulator.state[BLACK] = Eval::NNUE::INIT;
287
288   assert(pos_is_ok());
289
290   return *this;
291 }
292
293
294 /// Position::set_castling_right() is a helper function used to set castling
295 /// rights given the corresponding color and the rook starting square.
296
297 void Position::set_castling_right(Color c, Square rfrom) {
298
299   Square kfrom = square<KING>(c);
300   CastlingRights cr = c & (kfrom < rfrom ? KING_SIDE: QUEEN_SIDE);
301
302   st->castlingRights |= cr;
303   castlingRightsMask[kfrom] |= cr;
304   castlingRightsMask[rfrom] |= cr;
305   castlingRookSquare[cr] = rfrom;
306
307   Square kto = relative_square(c, cr & KING_SIDE ? SQ_G1 : SQ_C1);
308   Square rto = relative_square(c, cr & KING_SIDE ? SQ_F1 : SQ_D1);
309
310   castlingPath[cr] =   (between_bb(rfrom, rto) | between_bb(kfrom, kto))
311                     & ~(kfrom | rfrom);
312 }
313
314
315 /// Position::set_check_info() sets king attacks to detect if a move gives check
316
317 void Position::set_check_info(StateInfo* si) const {
318
319   si->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), si->pinners[BLACK]);
320   si->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), si->pinners[WHITE]);
321
322   Square ksq = square<KING>(~sideToMove);
323
324   si->checkSquares[PAWN]   = pawn_attacks_bb(~sideToMove, ksq);
325   si->checkSquares[KNIGHT] = attacks_bb<KNIGHT>(ksq);
326   si->checkSquares[BISHOP] = attacks_bb<BISHOP>(ksq, pieces());
327   si->checkSquares[ROOK]   = attacks_bb<ROOK>(ksq, pieces());
328   si->checkSquares[QUEEN]  = si->checkSquares[BISHOP] | si->checkSquares[ROOK];
329   si->checkSquares[KING]   = 0;
330 }
331
332
333 /// Position::set_state() computes the hash keys of the position, and other
334 /// data that once computed is updated incrementally as moves are made.
335 /// The function is only used when a new position is set up, and to verify
336 /// the correctness of the StateInfo data when running in debug mode.
337
338 void Position::set_state(StateInfo* si) const {
339
340   si->key = si->materialKey = 0;
341   si->pawnKey = Zobrist::noPawns;
342   si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
343   si->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
344
345   set_check_info(si);
346
347   for (Bitboard b = pieces(); b; )
348   {
349       Square s = pop_lsb(b);
350       Piece pc = piece_on(s);
351       si->key ^= Zobrist::psq[pc][s];
352
353       if (type_of(pc) == PAWN)
354           si->pawnKey ^= Zobrist::psq[pc][s];
355
356       else if (type_of(pc) != KING)
357           si->nonPawnMaterial[color_of(pc)] += PieceValue[MG][pc];
358   }
359
360   if (si->epSquare != SQ_NONE)
361       si->key ^= Zobrist::enpassant[file_of(si->epSquare)];
362
363   if (sideToMove == BLACK)
364       si->key ^= Zobrist::side;
365
366   si->key ^= Zobrist::castling[si->castlingRights];
367
368   for (Piece pc : Pieces)
369       for (int cnt = 0; cnt < pieceCount[pc]; ++cnt)
370           si->materialKey ^= Zobrist::psq[pc][cnt];
371 }
372
373
374 /// Position::set() is an overload to initialize the position object with
375 /// the given endgame code string like "KBPKN". It is mainly a helper to
376 /// get the material key out of an endgame code.
377
378 Position& Position::set(const string& code, Color c, StateInfo* si) {
379
380   assert(code[0] == 'K');
381
382   string sides[] = { code.substr(code.find('K', 1)),      // Weak
383                      code.substr(0, std::min(code.find('v'), code.find('K', 1))) }; // Strong
384
385   assert(sides[0].length() > 0 && sides[0].length() < 8);
386   assert(sides[1].length() > 0 && sides[1].length() < 8);
387
388   std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
389
390   string fenStr = "8/" + sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/"
391                        + sides[1] + char(8 - sides[1].length() + '0') + "/8 w - - 0 10";
392
393   return set(fenStr, false, si, nullptr);
394 }
395
396
397 /// Position::fen() returns a FEN representation of the position. In case of
398 /// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
399
400 string Position::fen() const {
401
402   int emptyCnt;
403   std::ostringstream ss;
404
405   for (Rank r = RANK_8; r >= RANK_1; --r)
406   {
407       for (File f = FILE_A; f <= FILE_H; ++f)
408       {
409           for (emptyCnt = 0; f <= FILE_H && empty(make_square(f, r)); ++f)
410               ++emptyCnt;
411
412           if (emptyCnt)
413               ss << emptyCnt;
414
415           if (f <= FILE_H)
416               ss << PieceToChar[piece_on(make_square(f, r))];
417       }
418
419       if (r > RANK_1)
420           ss << '/';
421   }
422
423   ss << (sideToMove == WHITE ? " w " : " b ");
424
425   if (can_castle(WHITE_OO))
426       ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE_OO ))) : 'K');
427
428   if (can_castle(WHITE_OOO))
429       ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE_OOO))) : 'Q');
430
431   if (can_castle(BLACK_OO))
432       ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK_OO ))) : 'k');
433
434   if (can_castle(BLACK_OOO))
435       ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK_OOO))) : 'q');
436
437   if (!can_castle(ANY_CASTLING))
438       ss << '-';
439
440   ss << (ep_square() == SQ_NONE ? " - " : " " + UCI::square(ep_square()) + " ")
441      << st->rule50 << " " << 1 + (gamePly - (sideToMove == BLACK)) / 2;
442
443   return ss.str();
444 }
445
446
447 /// Position::slider_blockers() returns a bitboard of all the pieces (both colors)
448 /// that are blocking attacks on the square 's' from 'sliders'. A piece blocks a
449 /// slider if removing that piece from the board would result in a position where
450 /// square 's' is attacked. For example, a king-attack blocking piece can be either
451 /// a pinned or a discovered check piece, according if its color is the opposite
452 /// or the same of the color of the slider.
453
454 Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
455
456   Bitboard blockers = 0;
457   pinners = 0;
458
459   // Snipers are sliders that attack 's' when a piece and other snipers are removed
460   Bitboard snipers = (  (attacks_bb<  ROOK>(s) & pieces(QUEEN, ROOK))
461                       | (attacks_bb<BISHOP>(s) & pieces(QUEEN, BISHOP))) & sliders;
462   Bitboard occupancy = pieces() ^ snipers;
463
464   while (snipers)
465   {
466     Square sniperSq = pop_lsb(snipers);
467     Bitboard b = between_bb(s, sniperSq) & occupancy;
468
469     if (b && !more_than_one(b))
470     {
471         blockers |= b;
472         if (b & pieces(color_of(piece_on(s))))
473             pinners |= sniperSq;
474     }
475   }
476   return blockers;
477 }
478
479
480 /// Position::attackers_to() computes a bitboard of all pieces which attack a
481 /// given square. Slider attacks use the occupied bitboard to indicate occupancy.
482
483 Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
484
485   return  (pawn_attacks_bb(BLACK, s)       & pieces(WHITE, PAWN))
486         | (pawn_attacks_bb(WHITE, s)       & pieces(BLACK, PAWN))
487         | (attacks_bb<KNIGHT>(s)           & pieces(KNIGHT))
488         | (attacks_bb<  ROOK>(s, occupied) & pieces(  ROOK, QUEEN))
489         | (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
490         | (attacks_bb<KING>(s)             & pieces(KING));
491 }
492
493
494 /// Position::legal() tests whether a pseudo-legal move is legal
495
496 bool Position::legal(Move m) const {
497
498   assert(is_ok(m));
499
500   Color us = sideToMove;
501   Square from = from_sq(m);
502   Square to = to_sq(m);
503
504   assert(color_of(moved_piece(m)) == us);
505   assert(piece_on(square<KING>(us)) == make_piece(us, KING));
506
507   // En passant captures are a tricky special case. Because they are rather
508   // uncommon, we do it simply by testing whether the king is attacked after
509   // the move is made.
510   if (type_of(m) == EN_PASSANT)
511   {
512       Square ksq = square<KING>(us);
513       Square capsq = to - pawn_push(us);
514       Bitboard occupied = (pieces() ^ from ^ capsq) | to;
515
516       assert(to == ep_square());
517       assert(moved_piece(m) == make_piece(us, PAWN));
518       assert(piece_on(capsq) == make_piece(~us, PAWN));
519       assert(piece_on(to) == NO_PIECE);
520
521       return   !(attacks_bb<  ROOK>(ksq, occupied) & pieces(~us, QUEEN, ROOK))
522             && !(attacks_bb<BISHOP>(ksq, occupied) & pieces(~us, QUEEN, BISHOP));
523   }
524
525   // Castling moves generation does not check if the castling path is clear of
526   // enemy attacks, it is delayed at a later time: now!
527   if (type_of(m) == CASTLING)
528   {
529       // After castling, the rook and king final positions are the same in
530       // Chess960 as they would be in standard chess.
531       to = relative_square(us, to > from ? SQ_G1 : SQ_C1);
532       Direction step = to > from ? WEST : EAST;
533
534       for (Square s = to; s != from; s += step)
535           if (attackers_to(s) & pieces(~us))
536               return false;
537
538       // In case of Chess960, verify if the Rook blocks some checks
539       // For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1.
540       return !chess960 || !(blockers_for_king(us) & to_sq(m));
541   }
542
543   // If the moving piece is a king, check whether the destination square is
544   // attacked by the opponent.
545   if (type_of(piece_on(from)) == KING)
546       return !(attackers_to(to, pieces() ^ from) & pieces(~us));
547
548   // A non-king move is legal if and only if it is not pinned or it
549   // is moving along the ray towards or away from the king.
550   return !(blockers_for_king(us) & from)
551       || aligned(from, to, square<KING>(us));
552 }
553
554
555 /// Position::pseudo_legal() takes a random move and tests whether the move is
556 /// pseudo legal. It is used to validate moves from TT that can be corrupted
557 /// due to SMP concurrent access or hash position key aliasing.
558
559 bool Position::pseudo_legal(const Move m) const {
560
561   Color us = sideToMove;
562   Square from = from_sq(m);
563   Square to = to_sq(m);
564   Piece pc = moved_piece(m);
565
566   // Use a slower but simpler function for uncommon cases
567   // yet we skip the legality check of MoveList<LEGAL>().
568   if (type_of(m) != NORMAL)
569       return checkers() ? MoveList<    EVASIONS>(*this).contains(m)
570                         : MoveList<NON_EVASIONS>(*this).contains(m);
571
572   // Is not a promotion, so promotion piece must be empty
573   if (promotion_type(m) - KNIGHT != NO_PIECE_TYPE)
574       return false;
575
576   // If the 'from' square is not occupied by a piece belonging to the side to
577   // move, the move is obviously not legal.
578   if (pc == NO_PIECE || color_of(pc) != us)
579       return false;
580
581   // The destination square cannot be occupied by a friendly piece
582   if (pieces(us) & to)
583       return false;
584
585   // Handle the special case of a pawn move
586   if (type_of(pc) == PAWN)
587   {
588       // We have already handled promotion moves, so destination
589       // cannot be on the 8th/1st rank.
590       if ((Rank8BB | Rank1BB) & to)
591           return false;
592
593       if (   !(pawn_attacks_bb(us, from) & pieces(~us) & to) // Not a capture
594           && !((from + pawn_push(us) == to) && empty(to))       // Not a single push
595           && !(   (from + 2 * pawn_push(us) == to)              // Not a double push
596                && (relative_rank(us, from) == RANK_2)
597                && empty(to)
598                && empty(to - pawn_push(us))))
599           return false;
600   }
601   else if (!(attacks_bb(type_of(pc), from, pieces()) & to))
602       return false;
603
604   // Evasions generator already takes care to avoid some kind of illegal moves
605   // and legal() relies on this. We therefore have to take care that the same
606   // kind of moves are filtered out here.
607   if (checkers())
608   {
609       if (type_of(pc) != KING)
610       {
611           // Double check? In this case a king move is required
612           if (more_than_one(checkers()))
613               return false;
614
615           // Our move must be a blocking interposition or a capture of the checking piece
616           if (!(between_bb(square<KING>(us), lsb(checkers())) & to))
617               return false;
618       }
619       // In case of king moves under check we have to remove king so as to catch
620       // invalid moves like b1a1 when opposite queen is on c1.
621       else if (attackers_to(to, pieces() ^ from) & pieces(~us))
622           return false;
623   }
624
625   return true;
626 }
627
628
629 /// Position::gives_check() tests whether a pseudo-legal move gives a check
630
631 bool Position::gives_check(Move m) const {
632
633   assert(is_ok(m));
634   assert(color_of(moved_piece(m)) == sideToMove);
635
636   Square from = from_sq(m);
637   Square to = to_sq(m);
638
639   // Is there a direct check?
640   if (check_squares(type_of(piece_on(from))) & to)
641       return true;
642
643   // Is there a discovered check?
644   if (   (blockers_for_king(~sideToMove) & from)
645       && !aligned(from, to, square<KING>(~sideToMove)))
646       return true;
647
648   switch (type_of(m))
649   {
650   case NORMAL:
651       return false;
652
653   case PROMOTION:
654       return attacks_bb(promotion_type(m), to, pieces() ^ from) & square<KING>(~sideToMove);
655
656   // En passant capture with check? We have already handled the case
657   // of direct checks and ordinary discovered check, so the only case we
658   // need to handle is the unusual case of a discovered check through
659   // the captured pawn.
660   case EN_PASSANT:
661   {
662       Square capsq = make_square(file_of(to), rank_of(from));
663       Bitboard b = (pieces() ^ from ^ capsq) | to;
664
665       return  (attacks_bb<  ROOK>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, ROOK))
666             | (attacks_bb<BISHOP>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, BISHOP));
667   }
668   default: //CASTLING
669   {
670       // Castling is encoded as 'king captures the rook'
671       Square ksq = square<KING>(~sideToMove);
672       Square rto = relative_square(sideToMove, to > from ? SQ_F1 : SQ_D1);
673
674       return   (attacks_bb<ROOK>(rto) & ksq)
675             && (attacks_bb<ROOK>(rto, pieces() ^ from ^ to) & ksq);
676   }
677   }
678 }
679
680
681 /// Position::do_move() makes a move, and saves all information necessary
682 /// to a StateInfo object. The move is assumed to be legal. Pseudo-legal
683 /// moves should be filtered out before this function is called.
684
685 void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
686
687   assert(is_ok(m));
688   assert(&newSt != st);
689
690   thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
691   Key k = st->key ^ Zobrist::side;
692
693   // Copy some fields of the old state to our new StateInfo object except the
694   // ones which are going to be recalculated from scratch anyway and then switch
695   // our state pointer to point to the new (ready to be updated) state.
696   std::memcpy(&newSt, st, offsetof(StateInfo, key));
697   newSt.previous = st;
698   st = &newSt;
699
700   // Increment ply counters. In particular, rule50 will be reset to zero later on
701   // in case of a capture or a pawn move.
702   ++gamePly;
703   ++st->rule50;
704   ++st->pliesFromNull;
705
706   // Used by NNUE
707   st->accumulator.state[WHITE] = Eval::NNUE::EMPTY;
708   st->accumulator.state[BLACK] = Eval::NNUE::EMPTY;
709   auto& dp = st->dirtyPiece;
710   dp.dirty_num = 1;
711
712   Color us = sideToMove;
713   Color them = ~us;
714   Square from = from_sq(m);
715   Square to = to_sq(m);
716   Piece pc = piece_on(from);
717   Piece captured = type_of(m) == EN_PASSANT ? make_piece(them, PAWN) : piece_on(to);
718
719   assert(color_of(pc) == us);
720   assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
721   assert(type_of(captured) != KING);
722
723   if (type_of(m) == CASTLING)
724   {
725       assert(pc == make_piece(us, KING));
726       assert(captured == make_piece(us, ROOK));
727
728       Square rfrom, rto;
729       do_castling<true>(us, from, to, rfrom, rto);
730
731       k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
732       captured = NO_PIECE;
733   }
734
735   if (captured)
736   {
737       Square capsq = to;
738
739       // If the captured piece is a pawn, update pawn hash key, otherwise
740       // update non-pawn material.
741       if (type_of(captured) == PAWN)
742       {
743           if (type_of(m) == EN_PASSANT)
744           {
745               capsq -= pawn_push(us);
746
747               assert(pc == make_piece(us, PAWN));
748               assert(to == st->epSquare);
749               assert(relative_rank(us, to) == RANK_6);
750               assert(piece_on(to) == NO_PIECE);
751               assert(piece_on(capsq) == make_piece(them, PAWN));
752           }
753
754           st->pawnKey ^= Zobrist::psq[captured][capsq];
755       }
756       else
757           st->nonPawnMaterial[them] -= PieceValue[MG][captured];
758
759       if (Eval::useNNUE)
760       {
761           dp.dirty_num = 2;  // 1 piece moved, 1 piece captured
762           dp.piece[1] = captured;
763           dp.from[1] = capsq;
764           dp.to[1] = SQ_NONE;
765       }
766
767       // Update board and piece lists
768       remove_piece(capsq);
769
770       if (type_of(m) == EN_PASSANT)
771           board[capsq] = NO_PIECE;
772
773       // Update material hash key and prefetch access to materialTable
774       k ^= Zobrist::psq[captured][capsq];
775       st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
776       prefetch(thisThread->materialTable[st->materialKey]);
777
778       // Reset rule 50 counter
779       st->rule50 = 0;
780   }
781
782   // Update hash key
783   k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
784
785   // Reset en passant square
786   if (st->epSquare != SQ_NONE)
787   {
788       k ^= Zobrist::enpassant[file_of(st->epSquare)];
789       st->epSquare = SQ_NONE;
790   }
791
792   // Update castling rights if needed
793   if (st->castlingRights && (castlingRightsMask[from] | castlingRightsMask[to]))
794   {
795       k ^= Zobrist::castling[st->castlingRights];
796       st->castlingRights &= ~(castlingRightsMask[from] | castlingRightsMask[to]);
797       k ^= Zobrist::castling[st->castlingRights];
798   }
799
800   // Move the piece. The tricky Chess960 castling is handled earlier
801   if (type_of(m) != CASTLING)
802   {
803       if (Eval::useNNUE)
804       {
805           dp.piece[0] = pc;
806           dp.from[0] = from;
807           dp.to[0] = to;
808       }
809
810       move_piece(from, to);
811   }
812
813   // If the moving piece is a pawn do some special extra work
814   if (type_of(pc) == PAWN)
815   {
816       // Set en passant square if the moved pawn can be captured
817       if (   (int(to) ^ int(from)) == 16
818           && (pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN)))
819       {
820           st->epSquare = to - pawn_push(us);
821           k ^= Zobrist::enpassant[file_of(st->epSquare)];
822       }
823
824       else if (type_of(m) == PROMOTION)
825       {
826           Piece promotion = make_piece(us, promotion_type(m));
827
828           assert(relative_rank(us, to) == RANK_8);
829           assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
830
831           remove_piece(to);
832           put_piece(promotion, to);
833
834           if (Eval::useNNUE)
835           {
836               // Promoting pawn to SQ_NONE, promoted piece from SQ_NONE
837               dp.to[0] = SQ_NONE;
838               dp.piece[dp.dirty_num] = promotion;
839               dp.from[dp.dirty_num] = SQ_NONE;
840               dp.to[dp.dirty_num] = to;
841               dp.dirty_num++;
842           }
843
844           // Update hash keys
845           k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
846           st->pawnKey ^= Zobrist::psq[pc][to];
847           st->materialKey ^=  Zobrist::psq[promotion][pieceCount[promotion]-1]
848                             ^ Zobrist::psq[pc][pieceCount[pc]];
849
850           // Update material
851           st->nonPawnMaterial[us] += PieceValue[MG][promotion];
852       }
853
854       // Update pawn hash key
855       st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
856
857       // Reset rule 50 draw counter
858       st->rule50 = 0;
859   }
860
861   // Set capture piece
862   st->capturedPiece = captured;
863
864   // Update the key with the final value
865   st->key = k;
866
867   // Calculate checkers bitboard (if move gives check)
868   st->checkersBB = givesCheck ? attackers_to(square<KING>(them)) & pieces(us) : 0;
869
870   sideToMove = ~sideToMove;
871
872   // Update king attacks used for fast check detection
873   set_check_info(st);
874
875   // Calculate the repetition info. It is the ply distance from the previous
876   // occurrence of the same position, negative in the 3-fold case, or zero
877   // if the position was not repeated.
878   st->repetition = 0;
879   int end = std::min(st->rule50, st->pliesFromNull);
880   if (end >= 4)
881   {
882       StateInfo* stp = st->previous->previous;
883       for (int i = 4; i <= end; i += 2)
884       {
885           stp = stp->previous->previous;
886           if (stp->key == st->key)
887           {
888               st->repetition = stp->repetition ? -i : i;
889               break;
890           }
891       }
892   }
893
894   assert(pos_is_ok());
895 }
896
897
898 /// Position::undo_move() unmakes a move. When it returns, the position should
899 /// be restored to exactly the same state as before the move was made.
900
901 void Position::undo_move(Move m) {
902
903   assert(is_ok(m));
904
905   sideToMove = ~sideToMove;
906
907   Color us = sideToMove;
908   Square from = from_sq(m);
909   Square to = to_sq(m);
910   Piece pc = piece_on(to);
911
912   assert(empty(from) || type_of(m) == CASTLING);
913   assert(type_of(st->capturedPiece) != KING);
914
915   if (type_of(m) == PROMOTION)
916   {
917       assert(relative_rank(us, to) == RANK_8);
918       assert(type_of(pc) == promotion_type(m));
919       assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);
920
921       remove_piece(to);
922       pc = make_piece(us, PAWN);
923       put_piece(pc, to);
924   }
925
926   if (type_of(m) == CASTLING)
927   {
928       Square rfrom, rto;
929       do_castling<false>(us, from, to, rfrom, rto);
930   }
931   else
932   {
933       move_piece(to, from); // Put the piece back at the source square
934
935       if (st->capturedPiece)
936       {
937           Square capsq = to;
938
939           if (type_of(m) == EN_PASSANT)
940           {
941               capsq -= pawn_push(us);
942
943               assert(type_of(pc) == PAWN);
944               assert(to == st->previous->epSquare);
945               assert(relative_rank(us, to) == RANK_6);
946               assert(piece_on(capsq) == NO_PIECE);
947               assert(st->capturedPiece == make_piece(~us, PAWN));
948           }
949
950           put_piece(st->capturedPiece, capsq); // Restore the captured piece
951       }
952   }
953
954   // Finally point our state pointer back to the previous state
955   st = st->previous;
956   --gamePly;
957
958   assert(pos_is_ok());
959 }
960
961
962 /// Position::do_castling() is a helper used to do/undo a castling move. This
963 /// is a bit tricky in Chess960 where from/to squares can overlap.
964 template<bool Do>
965 void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
966
967   bool kingSide = to > from;
968   rfrom = to; // Castling is encoded as "king captures friendly rook"
969   rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
970   to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
971
972   if (Do && Eval::useNNUE)
973   {
974       auto& dp = st->dirtyPiece;
975       dp.piece[0] = make_piece(us, KING);
976       dp.from[0] = from;
977       dp.to[0] = to;
978       dp.piece[1] = make_piece(us, ROOK);
979       dp.from[1] = rfrom;
980       dp.to[1] = rto;
981       dp.dirty_num = 2;
982   }
983
984   // Remove both pieces first since squares could overlap in Chess960
985   remove_piece(Do ? from : to);
986   remove_piece(Do ? rfrom : rto);
987   board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do this for us
988   put_piece(make_piece(us, KING), Do ? to : from);
989   put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
990 }
991
992
993 /// Position::do_null_move() is used to do a "null move": it flips
994 /// the side to move without executing any move on the board.
995
996 void Position::do_null_move(StateInfo& newSt) {
997
998   assert(!checkers());
999   assert(&newSt != st);
1000
1001   std::memcpy(&newSt, st, offsetof(StateInfo, accumulator));
1002
1003   newSt.previous = st;
1004   st = &newSt;
1005
1006   st->dirtyPiece.dirty_num = 0;
1007   st->dirtyPiece.piece[0] = NO_PIECE; // Avoid checks in UpdateAccumulator()
1008   st->accumulator.state[WHITE] = Eval::NNUE::EMPTY;
1009   st->accumulator.state[BLACK] = Eval::NNUE::EMPTY;
1010
1011   if (st->epSquare != SQ_NONE)
1012   {
1013       st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
1014       st->epSquare = SQ_NONE;
1015   }
1016
1017   st->key ^= Zobrist::side;
1018   prefetch(TT.first_entry(key()));
1019
1020   ++st->rule50;
1021   st->pliesFromNull = 0;
1022
1023   sideToMove = ~sideToMove;
1024
1025   set_check_info(st);
1026
1027   st->repetition = 0;
1028
1029   assert(pos_is_ok());
1030 }
1031
1032
1033 /// Position::undo_null_move() must be used to undo a "null move"
1034
1035 void Position::undo_null_move() {
1036
1037   assert(!checkers());
1038
1039   st = st->previous;
1040   sideToMove = ~sideToMove;
1041 }
1042
1043
1044 /// Position::key_after() computes the new hash key after the given move. Needed
1045 /// for speculative prefetch. It doesn't recognize special moves like castling,
1046 /// en passant and promotions.
1047
1048 Key Position::key_after(Move m) const {
1049
1050   Square from = from_sq(m);
1051   Square to = to_sq(m);
1052   Piece pc = piece_on(from);
1053   Piece captured = piece_on(to);
1054   Key k = st->key ^ Zobrist::side;
1055
1056   if (captured)
1057       k ^= Zobrist::psq[captured][to];
1058
1059   return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
1060 }
1061
1062
1063 /// Position::see_ge (Static Exchange Evaluation Greater or Equal) tests if the
1064 /// SEE value of move is greater or equal to the given threshold. We'll use an
1065 /// algorithm similar to alpha-beta pruning with a null window.
1066
1067 bool Position::see_ge(Move m, Value threshold) const {
1068
1069   assert(is_ok(m));
1070
1071   // Only deal with normal moves, assume others pass a simple SEE
1072   if (type_of(m) != NORMAL)
1073       return VALUE_ZERO >= threshold;
1074
1075   Square from = from_sq(m), to = to_sq(m);
1076
1077   int swap = PieceValue[MG][piece_on(to)] - threshold;
1078   if (swap < 0)
1079       return false;
1080
1081   swap = PieceValue[MG][piece_on(from)] - swap;
1082   if (swap <= 0)
1083       return true;
1084
1085   Bitboard occupied = pieces() ^ from ^ to;
1086   Color stm = color_of(piece_on(from));
1087   Bitboard attackers = attackers_to(to, occupied);
1088   Bitboard stmAttackers, bb;
1089   int res = 1;
1090
1091   while (true)
1092   {
1093       stm = ~stm;
1094       attackers &= occupied;
1095
1096       // If stm has no more attackers then give up: stm loses
1097       if (!(stmAttackers = attackers & pieces(stm)))
1098           break;
1099
1100       // Don't allow pinned pieces to attack as long as there are
1101       // pinners on their original square.
1102       if (pinners(~stm) & occupied)
1103           stmAttackers &= ~blockers_for_king(stm);
1104
1105       if (!stmAttackers)
1106           break;
1107
1108       res ^= 1;
1109
1110       // Locate and remove the next least valuable attacker, and add to
1111       // the bitboard 'attackers' any X-ray attackers behind it.
1112       if ((bb = stmAttackers & pieces(PAWN)))
1113       {
1114           if ((swap = PawnValueMg - swap) < res)
1115               break;
1116
1117           occupied ^= least_significant_square_bb(bb);
1118           attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
1119       }
1120
1121       else if ((bb = stmAttackers & pieces(KNIGHT)))
1122       {
1123           if ((swap = KnightValueMg - swap) < res)
1124               break;
1125
1126           occupied ^= least_significant_square_bb(bb);
1127       }
1128
1129       else if ((bb = stmAttackers & pieces(BISHOP)))
1130       {
1131           if ((swap = BishopValueMg - swap) < res)
1132               break;
1133
1134           occupied ^= least_significant_square_bb(bb);
1135           attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
1136       }
1137
1138       else if ((bb = stmAttackers & pieces(ROOK)))
1139       {
1140           if ((swap = RookValueMg - swap) < res)
1141               break;
1142
1143           occupied ^= least_significant_square_bb(bb);
1144           attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
1145       }
1146
1147       else if ((bb = stmAttackers & pieces(QUEEN)))
1148       {
1149           if ((swap = QueenValueMg - swap) < res)
1150               break;
1151
1152           occupied ^= least_significant_square_bb(bb);
1153           attackers |=  (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
1154                       | (attacks_bb<ROOK  >(to, occupied) & pieces(ROOK  , QUEEN));
1155       }
1156
1157       else // KING
1158            // If we "capture" with the king but opponent still has attackers,
1159            // reverse the result.
1160           return (attackers & ~pieces(stm)) ? res ^ 1 : res;
1161   }
1162
1163   return bool(res);
1164 }
1165
1166
1167 /// Position::is_draw() tests whether the position is drawn by 50-move rule
1168 /// or by repetition. It does not detect stalemates.
1169
1170 bool Position::is_draw(int ply) const {
1171
1172   if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
1173       return true;
1174
1175   // Return a draw score if a position repeats once earlier but strictly
1176   // after the root, or repeats twice before or at the root.
1177   return st->repetition && st->repetition < ply;
1178 }
1179
1180
1181 // Position::has_repeated() tests whether there has been at least one repetition
1182 // of positions since the last capture or pawn move.
1183
1184 bool Position::has_repeated() const {
1185
1186     StateInfo* stc = st;
1187     int end = std::min(st->rule50, st->pliesFromNull);
1188     while (end-- >= 4)
1189     {
1190         if (stc->repetition)
1191             return true;
1192
1193         stc = stc->previous;
1194     }
1195     return false;
1196 }
1197
1198
1199 /// Position::has_game_cycle() tests if the position has a move which draws by repetition,
1200 /// or an earlier position has a move that directly reaches the current position.
1201
1202 bool Position::has_game_cycle(int ply) const {
1203
1204   int j;
1205
1206   int end = std::min(st->rule50, st->pliesFromNull);
1207
1208   if (end < 3)
1209     return false;
1210
1211   Key originalKey = st->key;
1212   StateInfo* stp = st->previous;
1213
1214   for (int i = 3; i <= end; i += 2)
1215   {
1216       stp = stp->previous->previous;
1217
1218       Key moveKey = originalKey ^ stp->key;
1219       if (   (j = H1(moveKey), cuckoo[j] == moveKey)
1220           || (j = H2(moveKey), cuckoo[j] == moveKey))
1221       {
1222           Move move = cuckooMove[j];
1223           Square s1 = from_sq(move);
1224           Square s2 = to_sq(move);
1225
1226           if (!((between_bb(s1, s2) ^ s2) & pieces()))
1227           {
1228               if (ply > i)
1229                   return true;
1230
1231               // For nodes before or at the root, check that the move is a
1232               // repetition rather than a move to the current position.
1233               // In the cuckoo table, both moves Rc1c5 and Rc5c1 are stored in
1234               // the same location, so we have to select which square to check.
1235               if (color_of(piece_on(empty(s1) ? s2 : s1)) != side_to_move())
1236                   continue;
1237
1238               // For repetitions before or at the root, require one more
1239               if (stp->repetition)
1240                   return true;
1241           }
1242       }
1243   }
1244   return false;
1245 }
1246
1247
1248 /// Position::flip() flips position with the white and black sides reversed. This
1249 /// is only useful for debugging e.g. for finding evaluation symmetry bugs.
1250
1251 void Position::flip() {
1252
1253   string f, token;
1254   std::stringstream ss(fen());
1255
1256   for (Rank r = RANK_8; r >= RANK_1; --r) // Piece placement
1257   {
1258       std::getline(ss, token, r > RANK_1 ? '/' : ' ');
1259       f.insert(0, token + (f.empty() ? " " : "/"));
1260   }
1261
1262   ss >> token; // Active color
1263   f += (token == "w" ? "B " : "W "); // Will be lowercased later
1264
1265   ss >> token; // Castling availability
1266   f += token + " ";
1267
1268   std::transform(f.begin(), f.end(), f.begin(),
1269                  [](char c) { return char(islower(c) ? toupper(c) : tolower(c)); });
1270
1271   ss >> token; // En passant square
1272   f += (token == "-" ? token : token.replace(1, 1, token[1] == '3' ? "6" : "3"));
1273
1274   std::getline(ss, token); // Half and full moves
1275   f += token;
1276
1277   set(f, is_chess960(), st, this_thread());
1278
1279   assert(pos_is_ok());
1280 }
1281
1282
1283 /// Position::pos_is_ok() performs some consistency checks for the
1284 /// position object and raises an asserts if something wrong is detected.
1285 /// This is meant to be helpful when debugging.
1286
1287 bool Position::pos_is_ok() const {
1288
1289   constexpr bool Fast = true; // Quick (default) or full check?
1290
1291   if (   (sideToMove != WHITE && sideToMove != BLACK)
1292       || piece_on(square<KING>(WHITE)) != W_KING
1293       || piece_on(square<KING>(BLACK)) != B_KING
1294       || (   ep_square() != SQ_NONE
1295           && relative_rank(sideToMove, ep_square()) != RANK_6))
1296       assert(0 && "pos_is_ok: Default");
1297
1298   if (Fast)
1299       return true;
1300
1301   if (   pieceCount[W_KING] != 1
1302       || pieceCount[B_KING] != 1
1303       || attackers_to(square<KING>(~sideToMove)) & pieces(sideToMove))
1304       assert(0 && "pos_is_ok: Kings");
1305
1306   if (   (pieces(PAWN) & (Rank1BB | Rank8BB))
1307       || pieceCount[W_PAWN] > 8
1308       || pieceCount[B_PAWN] > 8)
1309       assert(0 && "pos_is_ok: Pawns");
1310
1311   if (   (pieces(WHITE) & pieces(BLACK))
1312       || (pieces(WHITE) | pieces(BLACK)) != pieces()
1313       || popcount(pieces(WHITE)) > 16
1314       || popcount(pieces(BLACK)) > 16)
1315       assert(0 && "pos_is_ok: Bitboards");
1316
1317   for (PieceType p1 = PAWN; p1 <= KING; ++p1)
1318       for (PieceType p2 = PAWN; p2 <= KING; ++p2)
1319           if (p1 != p2 && (pieces(p1) & pieces(p2)))
1320               assert(0 && "pos_is_ok: Bitboards");
1321
1322   StateInfo si = *st;
1323   ASSERT_ALIGNED(&si, Eval::NNUE::CacheLineSize);
1324
1325   set_state(&si);
1326   if (std::memcmp(&si, st, sizeof(StateInfo)))
1327       assert(0 && "pos_is_ok: State");
1328
1329   for (Piece pc : Pieces)
1330       if (   pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
1331           || pieceCount[pc] != std::count(board, board + SQUARE_NB, pc))
1332           assert(0 && "pos_is_ok: Pieces");
1333
1334   for (Color c : { WHITE, BLACK })
1335       for (CastlingRights cr : {c & KING_SIDE, c & QUEEN_SIDE})
1336       {
1337           if (!can_castle(cr))
1338               continue;
1339
1340           if (   piece_on(castlingRookSquare[cr]) != make_piece(c, ROOK)
1341               || castlingRightsMask[castlingRookSquare[cr]] != cr
1342               || (castlingRightsMask[square<KING>(c)] & cr) != cr)
1343               assert(0 && "pos_is_ok: Castling");
1344       }
1345
1346   return true;
1347 }
1348
1349 } // namespace Stockfish