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