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