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