]> git.sesse.net Git - stockfish/blob - src/position.cpp
Remove classical evaluation
[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   assert(pos_is_ok());
288
289   return *this;
290 }
291
292
293 /// Position::set_castling_right() is a helper function used to set castling
294 /// rights given the corresponding color and the rook starting square.
295
296 void Position::set_castling_right(Color c, Square rfrom) {
297
298   Square kfrom = square<KING>(c);
299   CastlingRights cr = c & (kfrom < rfrom ? KING_SIDE: QUEEN_SIDE);
300
301   st->castlingRights |= cr;
302   castlingRightsMask[kfrom] |= cr;
303   castlingRightsMask[rfrom] |= cr;
304   castlingRookSquare[cr] = rfrom;
305
306   Square kto = relative_square(c, cr & KING_SIDE ? SQ_G1 : SQ_C1);
307   Square rto = relative_square(c, cr & KING_SIDE ? SQ_F1 : SQ_D1);
308
309   castlingPath[cr] =   (between_bb(rfrom, rto) | between_bb(kfrom, kto))
310                     & ~(kfrom | rfrom);
311 }
312
313
314 /// Position::set_check_info() sets king attacks to detect if a move gives check
315
316 void Position::set_check_info() const {
317
318   st->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), st->pinners[BLACK]);
319   st->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), st->pinners[WHITE]);
320
321   Square ksq = square<KING>(~sideToMove);
322
323   st->checkSquares[PAWN]   = pawn_attacks_bb(~sideToMove, ksq);
324   st->checkSquares[KNIGHT] = attacks_bb<KNIGHT>(ksq);
325   st->checkSquares[BISHOP] = attacks_bb<BISHOP>(ksq, pieces());
326   st->checkSquares[ROOK]   = attacks_bb<ROOK>(ksq, pieces());
327   st->checkSquares[QUEEN]  = st->checkSquares[BISHOP] | st->checkSquares[ROOK];
328   st->checkSquares[KING]   = 0;
329 }
330
331
332 /// Position::set_state() computes the hash keys of the position, and other
333 /// data that once computed is updated incrementally as moves are made.
334 /// The function is only used when a new position is set up
335
336 void Position::set_state() const {
337
338   st->key = st->materialKey = 0;
339   st->pawnKey = Zobrist::noPawns;
340   st->nonPawnMaterial[WHITE] = st->nonPawnMaterial[BLACK] = VALUE_ZERO;
341   st->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
342
343   set_check_info();
344
345   for (Bitboard b = pieces(); b; )
346   {
347       Square s = pop_lsb(b);
348       Piece pc = piece_on(s);
349       st->key ^= Zobrist::psq[pc][s];
350
351       if (type_of(pc) == PAWN)
352           st->pawnKey ^= Zobrist::psq[pc][s];
353
354       else if (type_of(pc) != KING)
355           st->nonPawnMaterial[color_of(pc)] += PieceValue[MG][pc];
356   }
357
358   if (st->epSquare != SQ_NONE)
359       st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
360
361   if (sideToMove == BLACK)
362       st->key ^= Zobrist::side;
363
364   st->key ^= Zobrist::castling[st->castlingRights];
365
366   for (Piece pc : Pieces)
367       for (int cnt = 0; cnt < pieceCount[pc]; ++cnt)
368           st->materialKey ^= Zobrist::psq[pc][cnt];
369 }
370
371
372 /// Position::set() is an overload to initialize the position object with
373 /// the given endgame code string like "KBPKN". It is mainly a helper to
374 /// get the material key out of an endgame code.
375
376 Position& Position::set(const string& code, Color c, StateInfo* si) {
377
378   assert(code[0] == 'K');
379
380   string sides[] = { code.substr(code.find('K', 1)),      // Weak
381                      code.substr(0, std::min(code.find('v'), code.find('K', 1))) }; // Strong
382
383   assert(sides[0].length() > 0 && sides[0].length() < 8);
384   assert(sides[1].length() > 0 && sides[1].length() < 8);
385
386   std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
387
388   string fenStr = "8/" + sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/"
389                        + sides[1] + char(8 - sides[1].length() + '0') + "/8 w - - 0 10";
390
391   return set(fenStr, false, si, nullptr);
392 }
393
394
395 /// Position::fen() returns a FEN representation of the position. In case of
396 /// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
397
398 string Position::fen() const {
399
400   int emptyCnt;
401   std::ostringstream ss;
402
403   for (Rank r = RANK_8; r >= RANK_1; --r)
404   {
405       for (File f = FILE_A; f <= FILE_H; ++f)
406       {
407           for (emptyCnt = 0; f <= FILE_H && empty(make_square(f, r)); ++f)
408               ++emptyCnt;
409
410           if (emptyCnt)
411               ss << emptyCnt;
412
413           if (f <= FILE_H)
414               ss << PieceToChar[piece_on(make_square(f, r))];
415       }
416
417       if (r > RANK_1)
418           ss << '/';
419   }
420
421   ss << (sideToMove == WHITE ? " w " : " b ");
422
423   if (can_castle(WHITE_OO))
424       ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE_OO ))) : 'K');
425
426   if (can_castle(WHITE_OOO))
427       ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE_OOO))) : 'Q');
428
429   if (can_castle(BLACK_OO))
430       ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK_OO ))) : 'k');
431
432   if (can_castle(BLACK_OOO))
433       ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK_OOO))) : 'q');
434
435   if (!can_castle(ANY_CASTLING))
436       ss << '-';
437
438   ss << (ep_square() == SQ_NONE ? " - " : " " + UCI::square(ep_square()) + " ")
439      << st->rule50 << " " << 1 + (gamePly - (sideToMove == BLACK)) / 2;
440
441   return ss.str();
442 }
443
444
445 /// Position::slider_blockers() returns a bitboard of all the pieces (both colors)
446 /// that are blocking attacks on the square 's' from 'sliders'. A piece blocks a
447 /// slider if removing that piece from the board would result in a position where
448 /// square 's' is attacked. For example, a king-attack blocking piece can be either
449 /// a pinned or a discovered check piece, according if its color is the opposite
450 /// or the same of the color of the slider.
451
452 Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
453
454   Bitboard blockers = 0;
455   pinners = 0;
456
457   // Snipers are sliders that attack 's' when a piece and other snipers are removed
458   Bitboard snipers = (  (attacks_bb<  ROOK>(s) & pieces(QUEEN, ROOK))
459                       | (attacks_bb<BISHOP>(s) & pieces(QUEEN, BISHOP))) & sliders;
460   Bitboard occupancy = pieces() ^ snipers;
461
462   while (snipers)
463   {
464     Square sniperSq = pop_lsb(snipers);
465     Bitboard b = between_bb(s, sniperSq) & occupancy;
466
467     if (b && !more_than_one(b))
468     {
469         blockers |= b;
470         if (b & pieces(color_of(piece_on(s))))
471             pinners |= sniperSq;
472     }
473   }
474   return blockers;
475 }
476
477
478 /// Position::attackers_to() computes a bitboard of all pieces which attack a
479 /// given square. Slider attacks use the occupied bitboard to indicate occupancy.
480
481 Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
482
483   return  (pawn_attacks_bb(BLACK, s)       & pieces(WHITE, PAWN))
484         | (pawn_attacks_bb(WHITE, s)       & pieces(BLACK, PAWN))
485         | (attacks_bb<KNIGHT>(s)           & pieces(KNIGHT))
486         | (attacks_bb<  ROOK>(s, occupied) & pieces(  ROOK, QUEEN))
487         | (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
488         | (attacks_bb<KING>(s)             & pieces(KING));
489 }
490
491
492 /// Position::legal() tests whether a pseudo-legal move is legal
493
494 bool Position::legal(Move m) const {
495
496   assert(is_ok(m));
497
498   Color us = sideToMove;
499   Square from = from_sq(m);
500   Square to = to_sq(m);
501
502   assert(color_of(moved_piece(m)) == us);
503   assert(piece_on(square<KING>(us)) == make_piece(us, KING));
504
505   // En passant captures are a tricky special case. Because they are rather
506   // uncommon, we do it simply by testing whether the king is attacked after
507   // the move is made.
508   if (type_of(m) == EN_PASSANT)
509   {
510       Square ksq = square<KING>(us);
511       Square capsq = to - pawn_push(us);
512       Bitboard occupied = (pieces() ^ from ^ capsq) | to;
513
514       assert(to == ep_square());
515       assert(moved_piece(m) == make_piece(us, PAWN));
516       assert(piece_on(capsq) == make_piece(~us, PAWN));
517       assert(piece_on(to) == NO_PIECE);
518
519       return   !(attacks_bb<  ROOK>(ksq, occupied) & pieces(~us, QUEEN, ROOK))
520             && !(attacks_bb<BISHOP>(ksq, occupied) & pieces(~us, QUEEN, BISHOP));
521   }
522
523   // Castling moves generation does not check if the castling path is clear of
524   // enemy attacks, it is delayed at a later time: now!
525   if (type_of(m) == CASTLING)
526   {
527       // After castling, the rook and king final positions are the same in
528       // Chess960 as they would be in standard chess.
529       to = relative_square(us, to > from ? SQ_G1 : SQ_C1);
530       Direction step = to > from ? WEST : EAST;
531
532       for (Square s = to; s != from; s += step)
533           if (attackers_to(s) & pieces(~us))
534               return false;
535
536       // In case of Chess960, verify if the Rook blocks some checks
537       // For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1.
538       return !chess960 || !(blockers_for_king(us) & to_sq(m));
539   }
540
541   // If the moving piece is a king, check whether the destination square is
542   // attacked by the opponent.
543   if (type_of(piece_on(from)) == KING)
544       return !(attackers_to(to, pieces() ^ from) & pieces(~us));
545
546   // A non-king move is legal if and only if it is not pinned or it
547   // is moving along the ray towards or away from the king.
548   return !(blockers_for_king(us) & from)
549       || aligned(from, to, square<KING>(us));
550 }
551
552
553 /// Position::pseudo_legal() takes a random move and tests whether the move is
554 /// pseudo legal. It is used to validate moves from TT that can be corrupted
555 /// due to SMP concurrent access or hash position key aliasing.
556
557 bool Position::pseudo_legal(const Move m) const {
558
559   Color us = sideToMove;
560   Square from = from_sq(m);
561   Square to = to_sq(m);
562   Piece pc = moved_piece(m);
563
564   // Use a slower but simpler function for uncommon cases
565   // yet we skip the legality check of MoveList<LEGAL>().
566   if (type_of(m) != NORMAL)
567       return checkers() ? MoveList<    EVASIONS>(*this).contains(m)
568                         : MoveList<NON_EVASIONS>(*this).contains(m);
569
570   // Is not a promotion, so promotion piece must be empty
571   assert(promotion_type(m) - KNIGHT == NO_PIECE_TYPE);
572
573   // If the 'from' square is not occupied by a piece belonging to the side to
574   // move, the move is obviously not legal.
575   if (pc == NO_PIECE || color_of(pc) != us)
576       return false;
577
578   // The destination square cannot be occupied by a friendly piece
579   if (pieces(us) & to)
580       return false;
581
582   // Handle the special case of a pawn move
583   if (type_of(pc) == PAWN)
584   {
585       // We have already handled promotion moves, so destination
586       // cannot be on the 8th/1st rank.
587       if ((Rank8BB | Rank1BB) & to)
588           return false;
589
590       if (   !(pawn_attacks_bb(us, from) & pieces(~us) & to) // Not a capture
591           && !((from + pawn_push(us) == to) && empty(to))       // Not a single push
592           && !(   (from + 2 * pawn_push(us) == to)              // Not a double push
593                && (relative_rank(us, from) == RANK_2)
594                && empty(to)
595                && empty(to - pawn_push(us))))
596           return false;
597   }
598   else if (!(attacks_bb(type_of(pc), from, pieces()) & to))
599       return false;
600
601   // Evasions generator already takes care to avoid some kind of illegal moves
602   // and legal() relies on this. We therefore have to take care that the same
603   // kind of moves are filtered out here.
604   if (checkers())
605   {
606       if (type_of(pc) != KING)
607       {
608           // Double check? In this case a king move is required
609           if (more_than_one(checkers()))
610               return false;
611
612           // Our move must be a blocking interposition or a capture of the checking piece
613           if (!(between_bb(square<KING>(us), lsb(checkers())) & to))
614               return false;
615       }
616       // In case of king moves under check we have to remove king so as to catch
617       // invalid moves like b1a1 when opposite queen is on c1.
618       else if (attackers_to(to, pieces() ^ from) & pieces(~us))
619           return false;
620   }
621
622   return true;
623 }
624
625
626 /// Position::gives_check() tests whether a pseudo-legal move gives a check
627
628 bool Position::gives_check(Move m) const {
629
630   assert(is_ok(m));
631   assert(color_of(moved_piece(m)) == sideToMove);
632
633   Square from = from_sq(m);
634   Square to = to_sq(m);
635
636   // Is there a direct check?
637   if (check_squares(type_of(piece_on(from))) & to)
638       return true;
639
640   // Is there a discovered check?
641   if (blockers_for_king(~sideToMove) & from)
642       return   !aligned(from, to, square<KING>(~sideToMove))
643             || type_of(m) == CASTLING;
644
645   switch (type_of(m))
646   {
647   case NORMAL:
648       return false;
649
650   case PROMOTION:
651       return attacks_bb(promotion_type(m), to, pieces() ^ from) & square<KING>(~sideToMove);
652
653   // En passant capture with check? We have already handled the case
654   // of direct checks and ordinary discovered check, so the only case we
655   // need to handle is the unusual case of a discovered check through
656   // the captured pawn.
657   case EN_PASSANT:
658   {
659       Square capsq = make_square(file_of(to), rank_of(from));
660       Bitboard b = (pieces() ^ from ^ capsq) | to;
661
662       return  (attacks_bb<  ROOK>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, ROOK))
663             | (attacks_bb<BISHOP>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, BISHOP));
664   }
665   default: //CASTLING
666   {
667       // Castling is encoded as 'king captures the rook'
668       Square rto = relative_square(sideToMove, to > from ? SQ_F1 : SQ_D1);
669
670       return check_squares(ROOK) & rto;
671   }
672   }
673 }
674
675
676 /// Position::do_move() makes a move, and saves all information necessary
677 /// to a StateInfo object. The move is assumed to be legal. Pseudo-legal
678 /// moves should be filtered out before this function is called.
679
680 void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
681
682   assert(is_ok(m));
683   assert(&newSt != st);
684
685   thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
686   Key k = st->key ^ Zobrist::side;
687
688   // Copy some fields of the old state to our new StateInfo object except the
689   // ones which are going to be recalculated from scratch anyway and then switch
690   // our state pointer to point to the new (ready to be updated) state.
691   std::memcpy(&newSt, st, offsetof(StateInfo, key));
692   newSt.previous = st;
693   st = &newSt;
694
695   // Increment ply counters. In particular, rule50 will be reset to zero later on
696   // in case of a capture or a pawn move.
697   ++gamePly;
698   ++st->rule50;
699   ++st->pliesFromNull;
700
701   // Used by NNUE
702   st->accumulator.computed[WHITE] = false;
703   st->accumulator.computed[BLACK] = false;
704   auto& dp = st->dirtyPiece;
705   dp.dirty_num = 1;
706
707   Color us = sideToMove;
708   Color them = ~us;
709   Square from = from_sq(m);
710   Square to = to_sq(m);
711   Piece pc = piece_on(from);
712   Piece captured = type_of(m) == EN_PASSANT ? make_piece(them, PAWN) : piece_on(to);
713
714   assert(color_of(pc) == us);
715   assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
716   assert(type_of(captured) != KING);
717
718   if (type_of(m) == CASTLING)
719   {
720       assert(pc == make_piece(us, KING));
721       assert(captured == make_piece(us, ROOK));
722
723       Square rfrom, rto;
724       do_castling<true>(us, from, to, rfrom, rto);
725
726       k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
727       captured = NO_PIECE;
728   }
729
730   if (captured)
731   {
732       Square capsq = to;
733
734       // If the captured piece is a pawn, update pawn hash key, otherwise
735       // update non-pawn material.
736       if (type_of(captured) == PAWN)
737       {
738           if (type_of(m) == EN_PASSANT)
739           {
740               capsq -= pawn_push(us);
741
742               assert(pc == make_piece(us, PAWN));
743               assert(to == st->epSquare);
744               assert(relative_rank(us, to) == RANK_6);
745               assert(piece_on(to) == NO_PIECE);
746               assert(piece_on(capsq) == make_piece(them, PAWN));
747           }
748
749           st->pawnKey ^= Zobrist::psq[captured][capsq];
750       }
751       else
752           st->nonPawnMaterial[them] -= PieceValue[MG][captured];
753
754       dp.dirty_num = 2;  // 1 piece moved, 1 piece captured
755       dp.piece[1] = captured;
756       dp.from[1] = capsq;
757       dp.to[1] = SQ_NONE;
758
759       // Update board and piece lists
760       remove_piece(capsq);
761
762       // Update material hash key and prefetch access to materialTable
763       k ^= Zobrist::psq[captured][capsq];
764       st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
765
766       // Reset rule 50 counter
767       st->rule50 = 0;
768   }
769
770   // Update hash key
771   k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
772
773   // Reset en passant square
774   if (st->epSquare != SQ_NONE)
775   {
776       k ^= Zobrist::enpassant[file_of(st->epSquare)];
777       st->epSquare = SQ_NONE;
778   }
779
780   // Update castling rights if needed
781   if (st->castlingRights && (castlingRightsMask[from] | castlingRightsMask[to]))
782   {
783       k ^= Zobrist::castling[st->castlingRights];
784       st->castlingRights &= ~(castlingRightsMask[from] | castlingRightsMask[to]);
785       k ^= Zobrist::castling[st->castlingRights];
786   }
787
788   // Move the piece. The tricky Chess960 castling is handled earlier
789   if (type_of(m) != CASTLING)
790   {
791       dp.piece[0] = pc;
792       dp.from[0] = from;
793       dp.to[0] = to;
794
795       move_piece(from, to);
796   }
797
798   // If the moving piece is a pawn do some special extra work
799   if (type_of(pc) == PAWN)
800   {
801       // Set en passant square if the moved pawn can be captured
802       if (   (int(to) ^ int(from)) == 16
803           && (pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN)))
804       {
805           st->epSquare = to - pawn_push(us);
806           k ^= Zobrist::enpassant[file_of(st->epSquare)];
807       }
808
809       else if (type_of(m) == PROMOTION)
810       {
811           Piece promotion = make_piece(us, promotion_type(m));
812
813           assert(relative_rank(us, to) == RANK_8);
814           assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
815
816           remove_piece(to);
817           put_piece(promotion, to);
818
819           // Promoting pawn to SQ_NONE, promoted piece from SQ_NONE
820           dp.to[0] = SQ_NONE;
821           dp.piece[dp.dirty_num] = promotion;
822           dp.from[dp.dirty_num] = SQ_NONE;
823           dp.to[dp.dirty_num] = to;
824           dp.dirty_num++;
825
826           // Update hash keys
827           k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
828           st->pawnKey ^= Zobrist::psq[pc][to];
829           st->materialKey ^=  Zobrist::psq[promotion][pieceCount[promotion]-1]
830                             ^ Zobrist::psq[pc][pieceCount[pc]];
831
832           // Update material
833           st->nonPawnMaterial[us] += PieceValue[MG][promotion];
834       }
835
836       // Update pawn hash key
837       st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
838
839       // Reset rule 50 draw counter
840       st->rule50 = 0;
841   }
842
843   // Set capture piece
844   st->capturedPiece = captured;
845
846   // Update the key with the final value
847   st->key = k;
848
849   // Calculate checkers bitboard (if move gives check)
850   st->checkersBB = givesCheck ? attackers_to(square<KING>(them)) & pieces(us) : 0;
851
852   sideToMove = ~sideToMove;
853
854   // Update king attacks used for fast check detection
855   set_check_info();
856
857   // Calculate the repetition info. It is the ply distance from the previous
858   // occurrence of the same position, negative in the 3-fold case, or zero
859   // if the position was not repeated.
860   st->repetition = 0;
861   int end = std::min(st->rule50, st->pliesFromNull);
862   if (end >= 4)
863   {
864       StateInfo* stp = st->previous->previous;
865       for (int i = 4; i <= end; i += 2)
866       {
867           stp = stp->previous->previous;
868           if (stp->key == st->key)
869           {
870               st->repetition = stp->repetition ? -i : i;
871               break;
872           }
873       }
874   }
875
876   assert(pos_is_ok());
877 }
878
879
880 /// Position::undo_move() unmakes a move. When it returns, the position should
881 /// be restored to exactly the same state as before the move was made.
882
883 void Position::undo_move(Move m) {
884
885   assert(is_ok(m));
886
887   sideToMove = ~sideToMove;
888
889   Color us = sideToMove;
890   Square from = from_sq(m);
891   Square to = to_sq(m);
892   Piece pc = piece_on(to);
893
894   assert(empty(from) || type_of(m) == CASTLING);
895   assert(type_of(st->capturedPiece) != KING);
896
897   if (type_of(m) == PROMOTION)
898   {
899       assert(relative_rank(us, to) == RANK_8);
900       assert(type_of(pc) == promotion_type(m));
901       assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);
902
903       remove_piece(to);
904       pc = make_piece(us, PAWN);
905       put_piece(pc, to);
906   }
907
908   if (type_of(m) == CASTLING)
909   {
910       Square rfrom, rto;
911       do_castling<false>(us, from, to, rfrom, rto);
912   }
913   else
914   {
915       move_piece(to, from); // Put the piece back at the source square
916
917       if (st->capturedPiece)
918       {
919           Square capsq = to;
920
921           if (type_of(m) == EN_PASSANT)
922           {
923               capsq -= pawn_push(us);
924
925               assert(type_of(pc) == PAWN);
926               assert(to == st->previous->epSquare);
927               assert(relative_rank(us, to) == RANK_6);
928               assert(piece_on(capsq) == NO_PIECE);
929               assert(st->capturedPiece == make_piece(~us, PAWN));
930           }
931
932           put_piece(st->capturedPiece, capsq); // Restore the captured piece
933       }
934   }
935
936   // Finally point our state pointer back to the previous state
937   st = st->previous;
938   --gamePly;
939
940   assert(pos_is_ok());
941 }
942
943
944 /// Position::do_castling() is a helper used to do/undo a castling move. This
945 /// is a bit tricky in Chess960 where from/to squares can overlap.
946 template<bool Do>
947 void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
948
949   bool kingSide = to > from;
950   rfrom = to; // Castling is encoded as "king captures friendly rook"
951   rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
952   to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
953
954   if (Do)
955   {
956       auto& dp = st->dirtyPiece;
957       dp.piece[0] = make_piece(us, KING);
958       dp.from[0] = from;
959       dp.to[0] = to;
960       dp.piece[1] = make_piece(us, ROOK);
961       dp.from[1] = rfrom;
962       dp.to[1] = rto;
963       dp.dirty_num = 2;
964   }
965
966   // Remove both pieces first since squares could overlap in Chess960
967   remove_piece(Do ? from : to);
968   remove_piece(Do ? rfrom : rto);
969   board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do this for us
970   put_piece(make_piece(us, KING), Do ? to : from);
971   put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
972 }
973
974
975 /// Position::do_null_move() is used to do a "null move": it flips
976 /// the side to move without executing any move on the board.
977
978 void Position::do_null_move(StateInfo& newSt) {
979
980   assert(!checkers());
981   assert(&newSt != st);
982
983   std::memcpy(&newSt, st, offsetof(StateInfo, accumulator));
984
985   newSt.previous = st;
986   st = &newSt;
987
988   st->dirtyPiece.dirty_num = 0;
989   st->dirtyPiece.piece[0] = NO_PIECE; // Avoid checks in UpdateAccumulator()
990   st->accumulator.computed[WHITE] = false;
991   st->accumulator.computed[BLACK] = false;
992
993   if (st->epSquare != SQ_NONE)
994   {
995       st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
996       st->epSquare = SQ_NONE;
997   }
998
999   st->key ^= Zobrist::side;
1000   ++st->rule50;
1001   prefetch(TT.first_entry(key()));
1002
1003   st->pliesFromNull = 0;
1004
1005   sideToMove = ~sideToMove;
1006
1007   set_check_info();
1008
1009   st->repetition = 0;
1010
1011   assert(pos_is_ok());
1012 }
1013
1014
1015 /// Position::undo_null_move() must be used to undo a "null move"
1016
1017 void Position::undo_null_move() {
1018
1019   assert(!checkers());
1020
1021   st = st->previous;
1022   sideToMove = ~sideToMove;
1023 }
1024
1025
1026 /// Position::key_after() computes the new hash key after the given move. Needed
1027 /// for speculative prefetch. It doesn't recognize special moves like castling,
1028 /// en passant and promotions.
1029
1030 Key Position::key_after(Move m) const {
1031
1032   Square from = from_sq(m);
1033   Square to = to_sq(m);
1034   Piece pc = piece_on(from);
1035   Piece captured = piece_on(to);
1036   Key k = st->key ^ Zobrist::side;
1037
1038   if (captured)
1039       k ^= Zobrist::psq[captured][to];
1040
1041   k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
1042
1043   return (captured || type_of(pc) == PAWN)
1044       ? k : adjust_key50<true>(k);
1045 }
1046
1047
1048 /// Position::see_ge (Static Exchange Evaluation Greater or Equal) tests if the
1049 /// SEE value of move is greater or equal to the given threshold. We'll use an
1050 /// algorithm similar to alpha-beta pruning with a null window.
1051
1052 bool Position::see_ge(Move m, Bitboard& occupied, Value threshold) const {
1053
1054   assert(is_ok(m));
1055
1056   // Only deal with normal moves, assume others pass a simple SEE
1057   if (type_of(m) != NORMAL)
1058       return VALUE_ZERO >= threshold;
1059
1060   Square from = from_sq(m), to = to_sq(m);
1061
1062   int swap = PieceValue[MG][piece_on(to)] - threshold;
1063   if (swap < 0)
1064       return false;
1065
1066   swap = PieceValue[MG][piece_on(from)] - swap;
1067   if (swap <= 0)
1068       return true;
1069
1070   assert(color_of(piece_on(from)) == sideToMove);
1071   occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
1072   Color stm = sideToMove;
1073   Bitboard attackers = attackers_to(to, occupied);
1074   Bitboard stmAttackers, bb;
1075   int res = 1;
1076
1077   while (true)
1078   {
1079       stm = ~stm;
1080       attackers &= occupied;
1081
1082       // If stm has no more attackers then give up: stm loses
1083       if (!(stmAttackers = attackers & pieces(stm)))
1084           break;
1085
1086       // Don't allow pinned pieces to attack as long as there are
1087       // pinners on their original square.
1088       if (pinners(~stm) & occupied)
1089       {
1090           stmAttackers &= ~blockers_for_king(stm);
1091
1092           if (!stmAttackers)
1093               break;
1094       }
1095
1096       res ^= 1;
1097
1098       // Locate and remove the next least valuable attacker, and add to
1099       // the bitboard 'attackers' any X-ray attackers behind it.
1100       if ((bb = stmAttackers & pieces(PAWN)))
1101       {
1102           occupied ^= least_significant_square_bb(bb);
1103           if ((swap = PawnValueMg - swap) < res)
1104               break;
1105
1106           attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
1107       }
1108
1109       else if ((bb = stmAttackers & pieces(KNIGHT)))
1110       {
1111           occupied ^= least_significant_square_bb(bb);
1112           if ((swap = KnightValueMg - swap) < res)
1113               break;
1114       }
1115
1116       else if ((bb = stmAttackers & pieces(BISHOP)))
1117       {
1118           occupied ^= least_significant_square_bb(bb);
1119           if ((swap = BishopValueMg - swap) < res)
1120               break;
1121
1122           attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
1123       }
1124
1125       else if ((bb = stmAttackers & pieces(ROOK)))
1126       {
1127           occupied ^= least_significant_square_bb(bb);
1128           if ((swap = RookValueMg - swap) < res)
1129               break;
1130
1131           attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
1132       }
1133
1134       else if ((bb = stmAttackers & pieces(QUEEN)))
1135       {
1136           occupied ^= least_significant_square_bb(bb);
1137           if ((swap = QueenValueMg - swap) < res)
1138               break;
1139
1140           attackers |=  (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
1141                       | (attacks_bb<ROOK  >(to, occupied) & pieces(ROOK  , QUEEN));
1142       }
1143
1144       else // KING
1145            // If we "capture" with the king but opponent still has attackers,
1146            // reverse the result.
1147           return (attackers & ~pieces(stm)) ? res ^ 1 : res;
1148   }
1149
1150   return bool(res);
1151 }
1152
1153 bool Position::see_ge(Move m, Value threshold) const {
1154     Bitboard occupied;
1155     return see_ge(m, occupied, threshold);
1156 }
1157
1158
1159 /// Position::is_draw() tests whether the position is drawn by 50-move rule
1160 /// or by repetition. It does not detect stalemates.
1161
1162 bool Position::is_draw(int ply) const {
1163
1164   if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
1165       return true;
1166
1167   // Return a draw score if a position repeats once earlier but strictly
1168   // after the root, or repeats twice before or at the root.
1169   return st->repetition && st->repetition < ply;
1170 }
1171
1172
1173 // Position::has_repeated() tests whether there has been at least one repetition
1174 // of positions since the last capture or pawn move.
1175
1176 bool Position::has_repeated() const {
1177
1178     StateInfo* stc = st;
1179     int end = std::min(st->rule50, st->pliesFromNull);
1180     while (end-- >= 4)
1181     {
1182         if (stc->repetition)
1183             return true;
1184
1185         stc = stc->previous;
1186     }
1187     return false;
1188 }
1189
1190
1191 /// Position::has_game_cycle() tests if the position has a move which draws by repetition,
1192 /// or an earlier position has a move that directly reaches the current position.
1193
1194 bool Position::has_game_cycle(int ply) const {
1195
1196   int j;
1197
1198   int end = std::min(st->rule50, st->pliesFromNull);
1199
1200   if (end < 3)
1201     return false;
1202
1203   Key originalKey = st->key;
1204   StateInfo* stp = st->previous;
1205
1206   for (int i = 3; i <= end; i += 2)
1207   {
1208       stp = stp->previous->previous;
1209
1210       Key moveKey = originalKey ^ stp->key;
1211       if (   (j = H1(moveKey), cuckoo[j] == moveKey)
1212           || (j = H2(moveKey), cuckoo[j] == moveKey))
1213       {
1214           Move move = cuckooMove[j];
1215           Square s1 = from_sq(move);
1216           Square s2 = to_sq(move);
1217
1218           if (!((between_bb(s1, s2) ^ s2) & pieces()))
1219           {
1220               if (ply > i)
1221                   return true;
1222
1223               // For nodes before or at the root, check that the move is a
1224               // repetition rather than a move to the current position.
1225               // In the cuckoo table, both moves Rc1c5 and Rc5c1 are stored in
1226               // the same location, so we have to select which square to check.
1227               if (color_of(piece_on(empty(s1) ? s2 : s1)) != side_to_move())
1228                   continue;
1229
1230               // For repetitions before or at the root, require one more
1231               if (stp->repetition)
1232                   return true;
1233           }
1234       }
1235   }
1236   return false;
1237 }
1238
1239
1240 /// Position::flip() flips position with the white and black sides reversed. This
1241 /// is only useful for debugging e.g. for finding evaluation symmetry bugs.
1242
1243 void Position::flip() {
1244
1245   string f, token;
1246   std::stringstream ss(fen());
1247
1248   for (Rank r = RANK_8; r >= RANK_1; --r) // Piece placement
1249   {
1250       std::getline(ss, token, r > RANK_1 ? '/' : ' ');
1251       f.insert(0, token + (f.empty() ? " " : "/"));
1252   }
1253
1254   ss >> token; // Active color
1255   f += (token == "w" ? "B " : "W "); // Will be lowercased later
1256
1257   ss >> token; // Castling availability
1258   f += token + " ";
1259
1260   std::transform(f.begin(), f.end(), f.begin(),
1261                  [](char c) { return char(islower(c) ? toupper(c) : tolower(c)); });
1262
1263   ss >> token; // En passant square
1264   f += (token == "-" ? token : token.replace(1, 1, token[1] == '3' ? "6" : "3"));
1265
1266   std::getline(ss, token); // Half and full moves
1267   f += token;
1268
1269   set(f, is_chess960(), st, this_thread());
1270
1271   assert(pos_is_ok());
1272 }
1273
1274
1275 /// Position::pos_is_ok() performs some consistency checks for the
1276 /// position object and raises an asserts if something wrong is detected.
1277 /// This is meant to be helpful when debugging.
1278
1279 bool Position::pos_is_ok() const {
1280
1281   constexpr bool Fast = true; // Quick (default) or full check?
1282
1283   if (   (sideToMove != WHITE && sideToMove != BLACK)
1284       || piece_on(square<KING>(WHITE)) != W_KING
1285       || piece_on(square<KING>(BLACK)) != B_KING
1286       || (   ep_square() != SQ_NONE
1287           && relative_rank(sideToMove, ep_square()) != RANK_6))
1288       assert(0 && "pos_is_ok: Default");
1289
1290   if (Fast)
1291       return true;
1292
1293   if (   pieceCount[W_KING] != 1
1294       || pieceCount[B_KING] != 1
1295       || attackers_to(square<KING>(~sideToMove)) & pieces(sideToMove))
1296       assert(0 && "pos_is_ok: Kings");
1297
1298   if (   (pieces(PAWN) & (Rank1BB | Rank8BB))
1299       || pieceCount[W_PAWN] > 8
1300       || pieceCount[B_PAWN] > 8)
1301       assert(0 && "pos_is_ok: Pawns");
1302
1303   if (   (pieces(WHITE) & pieces(BLACK))
1304       || (pieces(WHITE) | pieces(BLACK)) != pieces()
1305       || popcount(pieces(WHITE)) > 16
1306       || popcount(pieces(BLACK)) > 16)
1307       assert(0 && "pos_is_ok: Bitboards");
1308
1309   for (PieceType p1 = PAWN; p1 <= KING; ++p1)
1310       for (PieceType p2 = PAWN; p2 <= KING; ++p2)
1311           if (p1 != p2 && (pieces(p1) & pieces(p2)))
1312               assert(0 && "pos_is_ok: Bitboards");
1313
1314
1315   for (Piece pc : Pieces)
1316       if (   pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
1317           || pieceCount[pc] != std::count(board, board + SQUARE_NB, pc))
1318           assert(0 && "pos_is_ok: Pieces");
1319
1320   for (Color c : { WHITE, BLACK })
1321       for (CastlingRights cr : {c & KING_SIDE, c & QUEEN_SIDE})
1322       {
1323           if (!can_castle(cr))
1324               continue;
1325
1326           if (   piece_on(castlingRookSquare[cr]) != make_piece(c, ROOK)
1327               || castlingRightsMask[castlingRookSquare[cr]] != cr
1328               || (castlingRightsMask[square<KING>(c)] & cr) != cr)
1329               assert(0 && "pos_is_ok: Castling");
1330       }
1331
1332   return true;
1333 }
1334
1335 } // namespace Stockfish