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