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