]> git.sesse.net Git - stockfish/blob - src/position.cpp
Clean-up some shifting in space calculation (#1955)
[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 is removed
502   Bitboard snipers = (  (PseudoAttacks[  ROOK][s] & pieces(QUEEN, ROOK))
503                       | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
504
505   while (snipers)
506   {
507     Square sniperSq = pop_lsb(&snipers);
508     Bitboard b = between_bb(s, sniperSq) & pieces();
509
510     if (b && !more_than_one(b))
511     {
512         blockers |= b;
513         if (b & pieces(color_of(piece_on(s))))
514             pinners |= sniperSq;
515     }
516   }
517   return blockers;
518 }
519
520
521 /// Position::attackers_to() computes a bitboard of all pieces which attack a
522 /// given square. Slider attacks use the occupied bitboard to indicate occupancy.
523
524 Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
525
526   return  (attacks_from<PAWN>(s, BLACK)    & pieces(WHITE, PAWN))
527         | (attacks_from<PAWN>(s, WHITE)    & pieces(BLACK, PAWN))
528         | (attacks_from<KNIGHT>(s)         & pieces(KNIGHT))
529         | (attacks_bb<  ROOK>(s, occupied) & pieces(  ROOK, QUEEN))
530         | (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
531         | (attacks_from<KING>(s)           & pieces(KING));
532 }
533
534
535 /// Position::legal() tests whether a pseudo-legal move is legal
536
537 bool Position::legal(Move m) const {
538
539   assert(is_ok(m));
540
541   Color us = sideToMove;
542   Square from = from_sq(m);
543   Square to = to_sq(m);
544
545   assert(color_of(moved_piece(m)) == us);
546   assert(piece_on(square<KING>(us)) == make_piece(us, KING));
547
548   // En passant captures are a tricky special case. Because they are rather
549   // uncommon, we do it simply by testing whether the king is attacked after
550   // the move is made.
551   if (type_of(m) == ENPASSANT)
552   {
553       Square ksq = square<KING>(us);
554       Square capsq = to - pawn_push(us);
555       Bitboard occupied = (pieces() ^ from ^ capsq) | to;
556
557       assert(to == ep_square());
558       assert(moved_piece(m) == make_piece(us, PAWN));
559       assert(piece_on(capsq) == make_piece(~us, PAWN));
560       assert(piece_on(to) == NO_PIECE);
561
562       return   !(attacks_bb<  ROOK>(ksq, occupied) & pieces(~us, QUEEN, ROOK))
563             && !(attacks_bb<BISHOP>(ksq, occupied) & pieces(~us, QUEEN, BISHOP));
564   }
565
566   // Castling moves generation does not check if the castling path is clear of
567   // enemy attacks, it is delayed at a later time: now!
568   if (type_of(m) == CASTLING)
569   {
570       // After castling, the rook and king final positions are the same in
571       // Chess960 as they would be in standard chess.
572       to = relative_square(us, to > from ? SQ_G1 : SQ_C1);
573       Direction step = to > from ? WEST : EAST;
574
575       for (Square s = to; s != from; s += step)
576           if (attackers_to(s) & pieces(~us))
577               return false;
578
579       // In case of Chess960, verify that when moving the castling rook we do
580       // not discover some hidden checker.
581       // For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1.
582       return   !chess960
583             || !(attacks_bb<ROOK>(to, pieces() ^ to_sq(m)) & pieces(~us, ROOK, QUEEN));
584   }
585
586   // If the moving piece is a king, check whether the destination square is
587   // attacked by the opponent.
588   if (type_of(piece_on(from)) == KING)
589       return !(attackers_to(to) & pieces(~us));
590
591   // A non-king move is legal if and only if it is not pinned or it
592   // is moving along the ray towards or away from the king.
593   return   !(blockers_for_king(us) & from)
594         ||  aligned(from, to, square<KING>(us));
595 }
596
597
598 /// Position::pseudo_legal() takes a random move and tests whether the move is
599 /// pseudo legal. It is used to validate moves from TT that can be corrupted
600 /// due to SMP concurrent access or hash position key aliasing.
601
602 bool Position::pseudo_legal(const Move m) const {
603
604   Color us = sideToMove;
605   Square from = from_sq(m);
606   Square to = to_sq(m);
607   Piece pc = moved_piece(m);
608
609   // Use a slower but simpler function for uncommon cases
610   if (type_of(m) != NORMAL)
611       return MoveList<LEGAL>(*this).contains(m);
612
613   // Is not a promotion, so promotion piece must be empty
614   if (promotion_type(m) - KNIGHT != NO_PIECE_TYPE)
615       return false;
616
617   // If the 'from' square is not occupied by a piece belonging to the side to
618   // move, the move is obviously not legal.
619   if (pc == NO_PIECE || color_of(pc) != us)
620       return false;
621
622   // The destination square cannot be occupied by a friendly piece
623   if (pieces(us) & to)
624       return false;
625
626   // Handle the special case of a pawn move
627   if (type_of(pc) == PAWN)
628   {
629       // We have already handled promotion moves, so destination
630       // cannot be on the 8th/1st rank.
631       if (rank_of(to) == relative_rank(us, RANK_8))
632           return false;
633
634       if (   !(attacks_from<PAWN>(from, us) & pieces(~us) & to) // Not a capture
635           && !((from + pawn_push(us) == to) && empty(to))       // Not a single push
636           && !(   (from + 2 * pawn_push(us) == to)              // Not a double push
637                && (rank_of(from) == relative_rank(us, RANK_2))
638                && empty(to)
639                && empty(to - pawn_push(us))))
640           return false;
641   }
642   else if (!(attacks_from(type_of(pc), from) & to))
643       return false;
644
645   // Evasions generator already takes care to avoid some kind of illegal moves
646   // and legal() relies on this. We therefore have to take care that the same
647   // kind of moves are filtered out here.
648   if (checkers())
649   {
650       if (type_of(pc) != KING)
651       {
652           // Double check? In this case a king move is required
653           if (more_than_one(checkers()))
654               return false;
655
656           // Our move must be a blocking evasion or a capture of the checking piece
657           if (!((between_bb(lsb(checkers()), square<KING>(us)) | checkers()) & to))
658               return false;
659       }
660       // In case of king moves under check we have to remove king so as to catch
661       // invalid moves like b1a1 when opposite queen is on c1.
662       else if (attackers_to(to, pieces() ^ from) & pieces(~us))
663           return false;
664   }
665
666   return true;
667 }
668
669
670 /// Position::gives_check() tests whether a pseudo-legal move gives a check
671
672 bool Position::gives_check(Move m) const {
673
674   assert(is_ok(m));
675   assert(color_of(moved_piece(m)) == sideToMove);
676
677   Square from = from_sq(m);
678   Square to = to_sq(m);
679
680   // Is there a direct check?
681   if (st->checkSquares[type_of(piece_on(from))] & to)
682       return true;
683
684   // Is there a discovered check?
685   if (   (st->blockersForKing[~sideToMove] & from)
686       && !aligned(from, to, square<KING>(~sideToMove)))
687       return true;
688
689   switch (type_of(m))
690   {
691   case NORMAL:
692       return false;
693
694   case PROMOTION:
695       return attacks_bb(promotion_type(m), to, pieces() ^ from) & square<KING>(~sideToMove);
696
697   // En passant capture with check? We have already handled the case
698   // of direct checks and ordinary discovered check, so the only case we
699   // need to handle is the unusual case of a discovered check through
700   // the captured pawn.
701   case ENPASSANT:
702   {
703       Square capsq = make_square(file_of(to), rank_of(from));
704       Bitboard b = (pieces() ^ from ^ capsq) | to;
705
706       return  (attacks_bb<  ROOK>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, ROOK))
707             | (attacks_bb<BISHOP>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, BISHOP));
708   }
709   case CASTLING:
710   {
711       Square kfrom = from;
712       Square rfrom = to; // Castling is encoded as 'King captures the rook'
713       Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1);
714       Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1);
715
716       return   (PseudoAttacks[ROOK][rto] & square<KING>(~sideToMove))
717             && (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove));
718   }
719   default:
720       assert(false);
721       return false;
722   }
723 }
724
725
726 /// Position::do_move() makes a move, and saves all information necessary
727 /// to a StateInfo object. The move is assumed to be legal. Pseudo-legal
728 /// moves should be filtered out before this function is called.
729
730 void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
731
732   assert(is_ok(m));
733   assert(&newSt != st);
734
735   thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
736   Key k = st->key ^ Zobrist::side;
737
738   // Copy some fields of the old state to our new StateInfo object except the
739   // ones which are going to be recalculated from scratch anyway and then switch
740   // our state pointer to point to the new (ready to be updated) state.
741   std::memcpy(&newSt, st, offsetof(StateInfo, key));
742   newSt.previous = st;
743   st = &newSt;
744
745   // Increment ply counters. In particular, rule50 will be reset to zero later on
746   // in case of a capture or a pawn move.
747   ++gamePly;
748   ++st->rule50;
749   ++st->pliesFromNull;
750
751   Color us = sideToMove;
752   Color them = ~us;
753   Square from = from_sq(m);
754   Square to = to_sq(m);
755   Piece pc = piece_on(from);
756   Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);
757
758   assert(color_of(pc) == us);
759   assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
760   assert(type_of(captured) != KING);
761
762   if (type_of(m) == CASTLING)
763   {
764       assert(pc == make_piece(us, KING));
765       assert(captured == make_piece(us, ROOK));
766
767       Square rfrom, rto;
768       do_castling<true>(us, from, to, rfrom, rto);
769
770       k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
771       captured = NO_PIECE;
772   }
773
774   if (captured)
775   {
776       Square capsq = to;
777
778       // If the captured piece is a pawn, update pawn hash key, otherwise
779       // update non-pawn material.
780       if (type_of(captured) == PAWN)
781       {
782           if (type_of(m) == ENPASSANT)
783           {
784               capsq -= pawn_push(us);
785
786               assert(pc == make_piece(us, PAWN));
787               assert(to == st->epSquare);
788               assert(relative_rank(us, to) == RANK_6);
789               assert(piece_on(to) == NO_PIECE);
790               assert(piece_on(capsq) == make_piece(them, PAWN));
791
792               board[capsq] = NO_PIECE; // Not done by remove_piece()
793           }
794
795           st->pawnKey ^= Zobrist::psq[captured][capsq];
796       }
797       else
798           st->nonPawnMaterial[them] -= PieceValue[MG][captured];
799
800       // Update board and piece lists
801       remove_piece(captured, capsq);
802
803       // Update material hash key and prefetch access to materialTable
804       k ^= Zobrist::psq[captured][capsq];
805       st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
806       prefetch(thisThread->materialTable[st->materialKey]);
807
808       // Reset rule 50 counter
809       st->rule50 = 0;
810   }
811
812   // Update hash key
813   k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
814
815   // Reset en passant square
816   if (st->epSquare != SQ_NONE)
817   {
818       k ^= Zobrist::enpassant[file_of(st->epSquare)];
819       st->epSquare = SQ_NONE;
820   }
821
822   // Update castling rights if needed
823   if (st->castlingRights && (castlingRightsMask[from] | castlingRightsMask[to]))
824   {
825       int cr = castlingRightsMask[from] | castlingRightsMask[to];
826       k ^= Zobrist::castling[st->castlingRights & cr];
827       st->castlingRights &= ~cr;
828   }
829
830   // Move the piece. The tricky Chess960 castling is handled earlier
831   if (type_of(m) != CASTLING)
832       move_piece(pc, from, to);
833
834   // If the moving piece is a pawn do some special extra work
835   if (type_of(pc) == PAWN)
836   {
837       // Set en-passant square if the moved pawn can be captured
838       if (   (int(to) ^ int(from)) == 16
839           && (attacks_from<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
840       {
841           st->epSquare = to - pawn_push(us);
842           k ^= Zobrist::enpassant[file_of(st->epSquare)];
843       }
844
845       else if (type_of(m) == PROMOTION)
846       {
847           Piece promotion = make_piece(us, promotion_type(m));
848
849           assert(relative_rank(us, to) == RANK_8);
850           assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
851
852           remove_piece(pc, to);
853           put_piece(promotion, to);
854
855           // Update hash keys
856           k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
857           st->pawnKey ^= Zobrist::psq[pc][to];
858           st->materialKey ^=  Zobrist::psq[promotion][pieceCount[promotion]-1]
859                             ^ Zobrist::psq[pc][pieceCount[pc]];
860
861           // Update material
862           st->nonPawnMaterial[us] += PieceValue[MG][promotion];
863       }
864
865       // Update pawn hash key and prefetch access to pawnsTable
866       st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
867       prefetch2(thisThread->pawnsTable[st->pawnKey]);
868
869       // Reset rule 50 draw counter
870       st->rule50 = 0;
871   }
872
873   // Set capture piece
874   st->capturedPiece = captured;
875
876   // Update the key with the final value
877   st->key = k;
878
879   // Calculate checkers bitboard (if move gives check)
880   st->checkersBB = givesCheck ? attackers_to(square<KING>(them)) & pieces(us) : 0;
881
882   sideToMove = ~sideToMove;
883
884   // Update king attacks used for fast check detection
885   set_check_info(st);
886
887   assert(pos_is_ok());
888 }
889
890
891 /// Position::undo_move() unmakes a move. When it returns, the position should
892 /// be restored to exactly the same state as before the move was made.
893
894 void Position::undo_move(Move m) {
895
896   assert(is_ok(m));
897
898   sideToMove = ~sideToMove;
899
900   Color us = sideToMove;
901   Square from = from_sq(m);
902   Square to = to_sq(m);
903   Piece pc = piece_on(to);
904
905   assert(empty(from) || type_of(m) == CASTLING);
906   assert(type_of(st->capturedPiece) != KING);
907
908   if (type_of(m) == PROMOTION)
909   {
910       assert(relative_rank(us, to) == RANK_8);
911       assert(type_of(pc) == promotion_type(m));
912       assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);
913
914       remove_piece(pc, to);
915       pc = make_piece(us, PAWN);
916       put_piece(pc, to);
917   }
918
919   if (type_of(m) == CASTLING)
920   {
921       Square rfrom, rto;
922       do_castling<false>(us, from, to, rfrom, rto);
923   }
924   else
925   {
926       move_piece(pc, to, from); // Put the piece back at the source square
927
928       if (st->capturedPiece)
929       {
930           Square capsq = to;
931
932           if (type_of(m) == ENPASSANT)
933           {
934               capsq -= pawn_push(us);
935
936               assert(type_of(pc) == PAWN);
937               assert(to == st->previous->epSquare);
938               assert(relative_rank(us, to) == RANK_6);
939               assert(piece_on(capsq) == NO_PIECE);
940               assert(st->capturedPiece == make_piece(~us, PAWN));
941           }
942
943           put_piece(st->capturedPiece, capsq); // Restore the captured piece
944       }
945   }
946
947   // Finally point our state pointer back to the previous state
948   st = st->previous;
949   --gamePly;
950
951   assert(pos_is_ok());
952 }
953
954
955 /// Position::do_castling() is a helper used to do/undo a castling move. This
956 /// is a bit tricky in Chess960 where from/to squares can overlap.
957 template<bool Do>
958 void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
959
960   bool kingSide = to > from;
961   rfrom = to; // Castling is encoded as "king captures friendly rook"
962   rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
963   to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
964
965   // Remove both pieces first since squares could overlap in Chess960
966   remove_piece(make_piece(us, KING), Do ? from : to);
967   remove_piece(make_piece(us, ROOK), Do ? rfrom : rto);
968   board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
969   put_piece(make_piece(us, KING), Do ? to : from);
970   put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
971 }
972
973
974 /// Position::do(undo)_null_move() is used to do(undo) a "null move": It flips
975 /// the side to move without executing any move on the board.
976
977 void Position::do_null_move(StateInfo& newSt) {
978
979   assert(!checkers());
980   assert(&newSt != st);
981
982   std::memcpy(&newSt, st, sizeof(StateInfo));
983   newSt.previous = st;
984   st = &newSt;
985
986   if (st->epSquare != SQ_NONE)
987   {
988       st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
989       st->epSquare = SQ_NONE;
990   }
991
992   st->key ^= Zobrist::side;
993   prefetch(TT.first_entry(st->key));
994
995   ++st->rule50;
996   st->pliesFromNull = 0;
997
998   sideToMove = ~sideToMove;
999
1000   set_check_info(st);
1001
1002   assert(pos_is_ok());
1003 }
1004
1005 void Position::undo_null_move() {
1006
1007   assert(!checkers());
1008
1009   st = st->previous;
1010   sideToMove = ~sideToMove;
1011 }
1012
1013
1014 /// Position::key_after() computes the new hash key after the given move. Needed
1015 /// for speculative prefetch. It doesn't recognize special moves like castling,
1016 /// en-passant and promotions.
1017
1018 Key Position::key_after(Move m) const {
1019
1020   Square from = from_sq(m);
1021   Square to = to_sq(m);
1022   Piece pc = piece_on(from);
1023   Piece captured = piece_on(to);
1024   Key k = st->key ^ Zobrist::side;
1025
1026   if (captured)
1027       k ^= Zobrist::psq[captured][to];
1028
1029   return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
1030 }
1031
1032
1033 /// Position::see_ge (Static Exchange Evaluation Greater or Equal) tests if the
1034 /// SEE value of move is greater or equal to the given threshold. We'll use an
1035 /// algorithm similar to alpha-beta pruning with a null window.
1036
1037 bool Position::see_ge(Move m, Value threshold) const {
1038
1039   assert(is_ok(m));
1040
1041   // Only deal with normal moves, assume others pass a simple see
1042   if (type_of(m) != NORMAL)
1043       return VALUE_ZERO >= threshold;
1044
1045   Bitboard stmAttackers;
1046   Square from = from_sq(m), to = to_sq(m);
1047   PieceType nextVictim = type_of(piece_on(from));
1048   Color us = color_of(piece_on(from));
1049   Color stm = ~us; // First consider opponent's move
1050   Value balance;   // Values of the pieces taken by us minus opponent's ones
1051
1052   // The opponent may be able to recapture so this is the best result
1053   // we can hope for.
1054   balance = PieceValue[MG][piece_on(to)] - threshold;
1055
1056   if (balance < VALUE_ZERO)
1057       return false;
1058
1059   // Now assume the worst possible result: that the opponent can
1060   // capture our piece for free.
1061   balance -= PieceValue[MG][nextVictim];
1062
1063   // If it is enough (like in PxQ) then return immediately. Note that
1064   // in case nextVictim == KING we always return here, this is ok
1065   // if the given move is legal.
1066   if (balance >= VALUE_ZERO)
1067       return true;
1068
1069   // Find all attackers to the destination square, with the moving piece
1070   // removed, but possibly an X-ray attacker added behind it.
1071   Bitboard occupied = pieces() ^ from ^ to;
1072   Bitboard attackers = attackers_to(to, occupied) & occupied;
1073
1074   while (true)
1075   {
1076       stmAttackers = attackers & pieces(stm);
1077
1078       // Don't allow pinned pieces to attack (except the king) as long as
1079       // all pinners are on their original square.
1080       if (!(st->pinners[~stm] & ~occupied))
1081           stmAttackers &= ~st->blockersForKing[stm];
1082
1083       // If stm has no more attackers then give up: stm loses
1084       if (!stmAttackers)
1085           break;
1086
1087       // Locate and remove the next least valuable attacker, and add to
1088       // the bitboard 'attackers' the possibly X-ray attackers behind it.
1089       nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
1090
1091       stm = ~stm; // Switch side to move
1092
1093       // Negamax the balance with alpha = balance, beta = balance+1 and
1094       // add nextVictim's value.
1095       //
1096       //      (balance, balance+1) -> (-balance-1, -balance)
1097       //
1098       assert(balance < VALUE_ZERO);
1099
1100       balance = -balance - 1 - PieceValue[MG][nextVictim];
1101
1102       // If balance is still non-negative after giving away nextVictim then we
1103       // win. The only thing to be careful about it is that we should revert
1104       // stm if we captured with the king when the opponent still has attackers.
1105       if (balance >= VALUE_ZERO)
1106       {
1107           if (nextVictim == KING && (attackers & pieces(stm)))
1108               stm = ~stm;
1109           break;
1110       }
1111       assert(nextVictim != KING);
1112   }
1113   return us != stm; // We break the above loop when stm loses
1114 }
1115
1116
1117 /// Position::is_draw() tests whether the position is drawn by 50-move rule
1118 /// or by repetition. It does not detect stalemates.
1119
1120 bool Position::is_draw(int ply) const {
1121
1122   if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
1123       return true;
1124
1125   int end = std::min(st->rule50, st->pliesFromNull);
1126
1127   if (end < 4)
1128     return false;
1129
1130   StateInfo* stp = st->previous->previous;
1131   int cnt = 0;
1132
1133   for (int i = 4; i <= end; i += 2)
1134   {
1135       stp = stp->previous->previous;
1136
1137       // Return a draw score if a position repeats once earlier but strictly
1138       // after the root, or repeats twice before or at the root.
1139       if (   stp->key == st->key
1140           && ++cnt + (ply > i) == 2)
1141           return true;
1142   }
1143
1144   return false;
1145 }
1146
1147
1148 // Position::has_repeated() tests whether there has been at least one repetition
1149 // of positions since the last capture or pawn move.
1150
1151 bool Position::has_repeated() const {
1152
1153     StateInfo* stc = st;
1154     while (true)
1155     {
1156         int i = 4, end = std::min(stc->rule50, stc->pliesFromNull);
1157
1158         if (end < i)
1159             return false;
1160
1161         StateInfo* stp = stc->previous->previous;
1162
1163         do {
1164             stp = stp->previous->previous;
1165
1166             if (stp->key == stc->key)
1167                 return true;
1168
1169             i += 2;
1170         } while (i <= end);
1171
1172         stc = stc->previous;
1173     }
1174 }
1175
1176
1177 /// Position::has_game_cycle() tests if the position has a move which draws by repetition,
1178 /// or an earlier position has a move that directly reaches the current position.
1179
1180 bool Position::has_game_cycle(int ply) const {
1181
1182   int j;
1183
1184   int end = std::min(st->rule50, st->pliesFromNull);
1185
1186   if (end < 3)
1187     return false;
1188
1189   Key originalKey = st->key;
1190   StateInfo* stp = st->previous;
1191
1192   for (int i = 3; i <= end; i += 2)
1193   {
1194       stp = stp->previous->previous;
1195
1196       Key moveKey = originalKey ^ stp->key;
1197       if (   (j = H1(moveKey), cuckoo[j] == moveKey)
1198           || (j = H2(moveKey), cuckoo[j] == moveKey))
1199       {
1200           Move move = cuckooMove[j];
1201           Square s1 = from_sq(move);
1202           Square s2 = to_sq(move);
1203
1204           if (!(between_bb(s1, s2) & pieces()))
1205           {
1206               // In the cuckoo table, both moves Rc1c5 and Rc5c1 are stored in the same
1207               // location. We select the legal one by reversing the move variable if necessary.
1208               if (empty(s1))
1209                   move = make_move(s2, s1);
1210
1211               if (ply > i)
1212                   return true;
1213
1214               // For repetitions before or at the root, require one more
1215               StateInfo* next_stp = stp;
1216               for (int k = i + 2; k <= end; k += 2)
1217               {
1218                   next_stp = next_stp->previous->previous;
1219                   if (next_stp->key == stp->key)
1220                      return true;
1221               }
1222           }
1223       }
1224   }
1225   return false;
1226 }
1227
1228
1229 /// Position::flip() flips position with the white and black sides reversed. This
1230 /// is only useful for debugging e.g. for finding evaluation symmetry bugs.
1231
1232 void Position::flip() {
1233
1234   string f, token;
1235   std::stringstream ss(fen());
1236
1237   for (Rank r = RANK_8; r >= RANK_1; --r) // Piece placement
1238   {
1239       std::getline(ss, token, r > RANK_1 ? '/' : ' ');
1240       f.insert(0, token + (f.empty() ? " " : "/"));
1241   }
1242
1243   ss >> token; // Active color
1244   f += (token == "w" ? "B " : "W "); // Will be lowercased later
1245
1246   ss >> token; // Castling availability
1247   f += token + " ";
1248
1249   std::transform(f.begin(), f.end(), f.begin(),
1250                  [](char c) { return char(islower(c) ? toupper(c) : tolower(c)); });
1251
1252   ss >> token; // En passant square
1253   f += (token == "-" ? token : token.replace(1, 1, token[1] == '3' ? "6" : "3"));
1254
1255   std::getline(ss, token); // Half and full moves
1256   f += token;
1257
1258   set(f, is_chess960(), st, this_thread());
1259
1260   assert(pos_is_ok());
1261 }
1262
1263
1264 /// Position::pos_is_ok() performs some consistency checks for the
1265 /// position object and raises an asserts if something wrong is detected.
1266 /// This is meant to be helpful when debugging.
1267
1268 bool Position::pos_is_ok() const {
1269
1270   constexpr bool Fast = true; // Quick (default) or full check?
1271
1272   if (   (sideToMove != WHITE && sideToMove != BLACK)
1273       || piece_on(square<KING>(WHITE)) != W_KING
1274       || piece_on(square<KING>(BLACK)) != B_KING
1275       || (   ep_square() != SQ_NONE
1276           && relative_rank(sideToMove, ep_square()) != RANK_6))
1277       assert(0 && "pos_is_ok: Default");
1278
1279   if (Fast)
1280       return true;
1281
1282   if (   pieceCount[W_KING] != 1
1283       || pieceCount[B_KING] != 1
1284       || attackers_to(square<KING>(~sideToMove)) & pieces(sideToMove))
1285       assert(0 && "pos_is_ok: Kings");
1286
1287   if (   (pieces(PAWN) & (Rank1BB | Rank8BB))
1288       || pieceCount[W_PAWN] > 8
1289       || pieceCount[B_PAWN] > 8)
1290       assert(0 && "pos_is_ok: Pawns");
1291
1292   if (   (pieces(WHITE) & pieces(BLACK))
1293       || (pieces(WHITE) | pieces(BLACK)) != pieces()
1294       || popcount(pieces(WHITE)) > 16
1295       || popcount(pieces(BLACK)) > 16)
1296       assert(0 && "pos_is_ok: Bitboards");
1297
1298   for (PieceType p1 = PAWN; p1 <= KING; ++p1)
1299       for (PieceType p2 = PAWN; p2 <= KING; ++p2)
1300           if (p1 != p2 && (pieces(p1) & pieces(p2)))
1301               assert(0 && "pos_is_ok: Bitboards");
1302
1303   StateInfo si = *st;
1304   set_state(&si);
1305   if (std::memcmp(&si, st, sizeof(StateInfo)))
1306       assert(0 && "pos_is_ok: State");
1307
1308   for (Piece pc : Pieces)
1309   {
1310       if (   pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
1311           || pieceCount[pc] != std::count(board, board + SQUARE_NB, pc))
1312           assert(0 && "pos_is_ok: Pieces");
1313
1314       for (int i = 0; i < pieceCount[pc]; ++i)
1315           if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
1316               assert(0 && "pos_is_ok: Index");
1317   }
1318
1319   for (Color c = WHITE; c <= BLACK; ++c)
1320       for (CastlingSide s = KING_SIDE; s <= QUEEN_SIDE; s = CastlingSide(s + 1))
1321       {
1322           if (!can_castle(c | s))
1323               continue;
1324
1325           if (   piece_on(castlingRookSquare[c | s]) != make_piece(c, ROOK)
1326               || castlingRightsMask[castlingRookSquare[c | s]] != (c | s)
1327               || (castlingRightsMask[square<KING>(c)] & (c | s)) != (c | s))
1328               assert(0 && "pos_is_ok: Castling");
1329       }
1330
1331   return true;
1332 }