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-2012 Marco Costalba, Joona Kiiski, Tord Romstad
6 Stockfish is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 Stockfish is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
38 Key Position::zobrist[2][8][64];
39 Key Position::zobEp[8];
40 Key Position::zobCastle[16];
41 Key Position::zobSideToMove;
42 Key Position::zobExclusion;
44 Score Position::pieceSquareTable[16][64];
46 // Material values arrays, indexed by Piece
47 const Value PieceValueMidgame[17] = {
49 PawnValueMidgame, KnightValueMidgame, BishopValueMidgame,
50 RookValueMidgame, QueenValueMidgame,
51 VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
52 PawnValueMidgame, KnightValueMidgame, BishopValueMidgame,
53 RookValueMidgame, QueenValueMidgame
56 const Value PieceValueEndgame[17] = {
58 PawnValueEndgame, KnightValueEndgame, BishopValueEndgame,
59 RookValueEndgame, QueenValueEndgame,
60 VALUE_ZERO, VALUE_ZERO, VALUE_ZERO,
61 PawnValueEndgame, KnightValueEndgame, BishopValueEndgame,
62 RookValueEndgame, QueenValueEndgame
68 // Bonus for having the side to move (modified by Joona Kiiski)
69 const Score Tempo = make_score(48, 22);
71 // To convert a Piece to and from a FEN char
72 const string PieceToChar(" PNBRQK pnbrqk .");
78 CheckInfo::CheckInfo(const Position& pos) {
80 Color them = ~pos.side_to_move();
81 ksq = pos.king_square(them);
83 pinned = pos.pinned_pieces();
84 dcCandidates = pos.discovered_check_candidates();
86 checkSq[PAWN] = pos.attacks_from<PAWN>(ksq, them);
87 checkSq[KNIGHT] = pos.attacks_from<KNIGHT>(ksq);
88 checkSq[BISHOP] = pos.attacks_from<BISHOP>(ksq);
89 checkSq[ROOK] = pos.attacks_from<ROOK>(ksq);
90 checkSq[QUEEN] = checkSq[BISHOP] | checkSq[ROOK];
95 /// Position::copy() creates a copy of 'pos'. We want the new born Position
96 /// object do not depend on any external data so we detach state pointer from
99 void Position::copy(const Position& pos, Thread* th) {
101 memcpy(this, &pos, sizeof(Position));
111 /// Position::from_fen() initializes the position object with the given FEN
112 /// string. This function is not very robust - make sure that input FENs are
113 /// correct (this is assumed to be the responsibility of the GUI).
115 void Position::from_fen(const string& fenStr, bool isChess960, Thread* th) {
117 A FEN string defines a particular position using only the ASCII character set.
119 A FEN string contains six fields separated by a space. The fields are:
121 1) Piece placement (from white's perspective). Each rank is described, starting
122 with rank 8 and ending with rank 1; within each rank, the contents of each
123 square are described from file A through file H. Following the Standard
124 Algebraic Notation (SAN), each piece is identified by a single letter taken
125 from the standard English names. White pieces are designated using upper-case
126 letters ("PNBRQK") while Black take lowercase ("pnbrqk"). Blank squares are
127 noted using digits 1 through 8 (the number of blank squares), and "/"
130 2) Active color. "w" means white moves next, "b" means black.
132 3) Castling availability. If neither side can castle, this is "-". Otherwise,
133 this has one or more letters: "K" (White can castle kingside), "Q" (White
134 can castle queenside), "k" (Black can castle kingside), and/or "q" (Black
135 can castle queenside).
137 4) En passant target square (in algebraic notation). If there's no en passant
138 target square, this is "-". If a pawn has just made a 2-square move, this
139 is the position "behind" the pawn. This is recorded regardless of whether
140 there is a pawn in position to make an en passant capture.
142 5) Halfmove clock. This is the number of halfmoves since the last pawn advance
143 or capture. This is used to determine if a draw can be claimed under the
146 6) Fullmove number. The number of the full move. It starts at 1, and is
147 incremented after Black's move.
150 char col, row, token;
153 std::istringstream fen(fenStr);
156 fen >> std::noskipws;
158 // 1. Piece placement
159 while ((fen >> token) && !isspace(token))
162 sq += Square(token - '0'); // Advance the given number of files
164 else if (token == '/')
165 sq = make_square(FILE_A, rank_of(sq) - Rank(2));
167 else if ((p = PieceToChar.find(token)) != string::npos)
169 put_piece(Piece(p), sq);
176 sideToMove = (token == 'w' ? WHITE : BLACK);
179 // 3. Castling availability. Compatible with 3 standards: Normal FEN standard,
180 // Shredder-FEN that uses the letters of the columns on which the rooks began
181 // the game instead of KQkq and also X-FEN standard that, in case of Chess960,
182 // if an inner rook is associated with the castling right, the castling tag is
183 // replaced by the file letter of the involved rook, as for the Shredder-FEN.
184 while ((fen >> token) && !isspace(token))
187 Color c = islower(token) ? BLACK : WHITE;
189 token = char(toupper(token));
192 for (rsq = relative_square(c, SQ_H1); type_of(piece_on(rsq)) != ROOK; rsq--) {}
194 else if (token == 'Q')
195 for (rsq = relative_square(c, SQ_A1); type_of(piece_on(rsq)) != ROOK; rsq++) {}
197 else if (token >= 'A' && token <= 'H')
198 rsq = make_square(File(token - 'A'), relative_rank(c, RANK_1));
203 set_castle_right(c, rsq);
206 // 4. En passant square. Ignore if no pawn capture is possible
207 if ( ((fen >> col) && (col >= 'a' && col <= 'h'))
208 && ((fen >> row) && (row == '3' || row == '6')))
210 st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
212 if (!(attackers_to(st->epSquare) & pieces(PAWN, sideToMove)))
213 st->epSquare = SQ_NONE;
216 // 5-6. Halfmove clock and fullmove number
217 fen >> std::skipws >> st->rule50 >> startPosPly;
219 // Convert from fullmove starting from 1 to ply starting from 0,
220 // handle also common incorrect FEN with fullmove = 0.
221 startPosPly = std::max(2 * (startPosPly - 1), 0) + int(sideToMove == BLACK);
223 st->key = compute_key();
224 st->pawnKey = compute_pawn_key();
225 st->materialKey = compute_material_key();
226 st->psqScore = compute_psq_score();
227 st->npMaterial[WHITE] = compute_non_pawn_material(WHITE);
228 st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
229 st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
230 chess960 = isChess960;
237 /// Position::set_castle_right() is an helper function used to set castling
238 /// rights given the corresponding color and the rook starting square.
240 void Position::set_castle_right(Color c, Square rfrom) {
242 Square kfrom = king_square(c);
243 bool kingSide = kfrom < rfrom;
244 int cr = (kingSide ? WHITE_OO : WHITE_OOO) << c;
246 st->castleRights |= cr;
247 castleRightsMask[kfrom] |= cr;
248 castleRightsMask[rfrom] |= cr;
249 castleRookSquare[cr] = rfrom;
251 Square kto = relative_square(c, kingSide ? SQ_G1 : SQ_C1);
252 Square rto = relative_square(c, kingSide ? SQ_F1 : SQ_D1);
254 for (Square s = std::min(rfrom, rto); s <= std::max(rfrom, rto); s++)
255 if (s != kfrom && s != rfrom)
258 for (Square s = std::min(kfrom, kto); s <= std::max(kfrom, kto); s++)
259 if (s != kfrom && s != rfrom)
264 /// Position::to_fen() returns a FEN representation of the position. In case
265 /// of Chess960 the Shredder-FEN notation is used. Mainly a debugging function.
267 const string Position::to_fen() const {
269 std::ostringstream fen;
273 for (Rank rank = RANK_8; rank >= RANK_1; rank--)
277 for (File file = FILE_A; file <= FILE_H; file++)
279 sq = make_square(file, rank);
281 if (square_empty(sq))
290 fen << PieceToChar[piece_on(sq)];
301 fen << (sideToMove == WHITE ? " w " : " b ");
303 if (can_castle(WHITE_OO))
304 fen << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE_OO))))) : 'K');
306 if (can_castle(WHITE_OOO))
307 fen << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE_OOO))))) : 'Q');
309 if (can_castle(BLACK_OO))
310 fen << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK_OO))) : 'k');
312 if (can_castle(BLACK_OOO))
313 fen << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK_OOO))) : 'q');
315 if (st->castleRights == CASTLES_NONE)
318 fen << (ep_square() == SQ_NONE ? " - " : " " + square_to_string(ep_square()) + " ")
319 << st->rule50 << " " << 1 + (startPosPly - int(sideToMove == BLACK)) / 2;
325 /// Position::print() prints an ASCII representation of the position to
326 /// the standard output. If a move is given then also the san is printed.
328 void Position::print(Move move) const {
330 const char* dottedLine = "\n+---+---+---+---+---+---+---+---+\n";
334 Position p(*this, thisThread);
335 cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") << move_to_san(p, move);
338 for (Rank rank = RANK_8; rank >= RANK_1; rank--)
340 cout << dottedLine << '|';
341 for (File file = FILE_A; file <= FILE_H; file++)
343 Square sq = make_square(file, rank);
344 Piece piece = piece_on(sq);
345 char c = (color_of(piece) == BLACK ? '=' : ' ');
347 if (piece == NO_PIECE && !opposite_colors(sq, SQ_A1))
348 piece++; // Index the dot
350 cout << c << PieceToChar[piece] << c << '|';
353 cout << dottedLine << "Fen is: " << to_fen() << "\nKey is: " << st->key << endl;
357 /// Position:hidden_checkers<>() returns a bitboard of all pinned (against the
358 /// king) pieces for the given color. Or, when template parameter FindPinned is
359 /// false, the function return the pieces of the given color candidate for a
360 /// discovery check against the enemy king.
361 template<bool FindPinned>
362 Bitboard Position::hidden_checkers() const {
364 // Pinned pieces protect our king, dicovery checks attack the enemy king
365 Bitboard b, result = 0;
366 Bitboard pinners = pieces(FindPinned ? ~sideToMove : sideToMove);
367 Square ksq = king_square(FindPinned ? sideToMove : ~sideToMove);
369 // Pinners are sliders, that give check when candidate pinned is removed
370 pinners &= (pieces(ROOK, QUEEN) & PseudoAttacks[ROOK][ksq])
371 | (pieces(BISHOP, QUEEN) & PseudoAttacks[BISHOP][ksq]);
375 b = squares_between(ksq, pop_1st_bit(&pinners)) & pieces();
377 if (b && single_bit(b) && (b & pieces(sideToMove)))
383 // Explicit template instantiations
384 template Bitboard Position::hidden_checkers<true>() const;
385 template Bitboard Position::hidden_checkers<false>() const;
388 /// Position::attackers_to() computes a bitboard of all pieces which attack a
389 /// given square. Slider attacks use occ bitboard as occupancy.
391 Bitboard Position::attackers_to(Square s, Bitboard occ) const {
393 return (attacks_from<PAWN>(s, BLACK) & pieces(PAWN, WHITE))
394 | (attacks_from<PAWN>(s, WHITE) & pieces(PAWN, BLACK))
395 | (attacks_from<KNIGHT>(s) & pieces(KNIGHT))
396 | (attacks_bb<ROOK>(s, occ) & pieces(ROOK, QUEEN))
397 | (attacks_bb<BISHOP>(s, occ) & pieces(BISHOP, QUEEN))
398 | (attacks_from<KING>(s) & pieces(KING));
402 /// Position::attacks_from() computes a bitboard of all attacks of a given piece
403 /// put in a given square. Slider attacks use occ bitboard as occupancy.
405 Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) {
411 case BISHOP: return attacks_bb<BISHOP>(s, occ);
412 case ROOK : return attacks_bb<ROOK>(s, occ);
413 case QUEEN : return attacks_bb<BISHOP>(s, occ) | attacks_bb<ROOK>(s, occ);
414 default : return StepAttacksBB[p][s];
419 /// Position::move_attacks_square() tests whether a move from the current
420 /// position attacks a given square.
422 bool Position::move_attacks_square(Move m, Square s) const {
428 Square from = from_sq(m);
429 Square to = to_sq(m);
430 Piece piece = piece_moved(m);
432 assert(!square_empty(from));
434 // Update occupancy as if the piece is moving
435 occ = pieces() ^ from ^ to;
437 // The piece moved in 'to' attacks the square 's' ?
438 if (attacks_from(piece, to, occ) & s)
441 // Scan for possible X-ray attackers behind the moved piece
442 xray = (attacks_bb<ROOK>(s, occ) & pieces(ROOK, QUEEN, color_of(piece)))
443 |(attacks_bb<BISHOP>(s, occ) & pieces(BISHOP, QUEEN, color_of(piece)));
445 // Verify attackers are triggered by our move and not already existing
446 return xray && (xray ^ (xray & attacks_from<QUEEN>(s)));
450 /// Position::pl_move_is_legal() tests whether a pseudo-legal move is legal
452 bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
455 assert(pinned == pinned_pieces());
457 Color us = sideToMove;
458 Square from = from_sq(m);
460 assert(color_of(piece_moved(m)) == us);
461 assert(piece_on(king_square(us)) == make_piece(us, KING));
463 // En passant captures are a tricky special case. Because they are rather
464 // uncommon, we do it simply by testing whether the king is attacked after
469 Square to = to_sq(m);
470 Square capsq = to + pawn_push(them);
471 Square ksq = king_square(us);
472 Bitboard b = (pieces() ^ from ^ capsq) | to;
474 assert(to == ep_square());
475 assert(piece_moved(m) == make_piece(us, PAWN));
476 assert(piece_on(capsq) == make_piece(them, PAWN));
477 assert(piece_on(to) == NO_PIECE);
479 return !(attacks_bb<ROOK>(ksq, b) & pieces(ROOK, QUEEN, them))
480 && !(attacks_bb<BISHOP>(ksq, b) & pieces(BISHOP, QUEEN, them));
483 // If the moving piece is a king, check whether the destination
484 // square is attacked by the opponent. Castling moves are checked
485 // for legality during move generation.
486 if (type_of(piece_on(from)) == KING)
487 return is_castle(m) || !(attackers_to(to_sq(m)) & pieces(~us));
489 // A non-king move is legal if and only if it is not pinned or it
490 // is moving along the ray towards or away from the king.
493 || squares_aligned(from, to_sq(m), king_square(us));
497 /// Position::move_is_legal() takes a random move and tests whether the move
498 /// is legal. This version is not very fast and should be used only in non
499 /// time-critical paths.
501 bool Position::move_is_legal(const Move m) const {
503 for (MoveList<MV_LEGAL> ml(*this); !ml.end(); ++ml)
511 /// Position::is_pseudo_legal() takes a random move and tests whether the move
512 /// is pseudo legal. It is used to validate moves from TT that can be corrupted
513 /// due to SMP concurrent access or hash position key aliasing.
515 bool Position::is_pseudo_legal(const Move m) const {
517 Color us = sideToMove;
518 Color them = ~sideToMove;
519 Square from = from_sq(m);
520 Square to = to_sq(m);
521 Piece pc = piece_moved(m);
523 // Use a slower but simpler function for uncommon cases
525 return move_is_legal(m);
527 // Is not a promotion, so promotion piece must be empty
528 if (promotion_type(m) - 2 != NO_PIECE_TYPE)
531 // If the from square is not occupied by a piece belonging to the side to
532 // move, the move is obviously not legal.
533 if (pc == NO_PIECE || color_of(pc) != us)
536 // The destination square cannot be occupied by a friendly piece
537 if (color_of(piece_on(to)) == us)
540 // Handle the special case of a pawn move
541 if (type_of(pc) == PAWN)
543 // Move direction must be compatible with pawn color
544 int direction = to - from;
545 if ((us == WHITE) != (direction > 0))
548 // We have already handled promotion moves, so destination
549 // cannot be on the 8/1th rank.
550 if (rank_of(to) == RANK_8 || rank_of(to) == RANK_1)
553 // Proceed according to the square delta between the origin and
554 // destination squares.
561 // Capture. The destination square must be occupied by an enemy
562 // piece (en passant captures was handled earlier).
563 if (color_of(piece_on(to)) != them)
566 // From and to files must be one file apart, avoids a7h5
567 if (abs(file_of(from) - file_of(to)) != 1)
573 // Pawn push. The destination square must be empty.
574 if (!square_empty(to))
579 // Double white pawn push. The destination square must be on the fourth
580 // rank, and both the destination square and the square between the
581 // source and destination squares must be empty.
582 if ( rank_of(to) != RANK_4
584 || !square_empty(from + DELTA_N))
589 // Double black pawn push. The destination square must be on the fifth
590 // rank, and both the destination square and the square between the
591 // source and destination squares must be empty.
592 if ( rank_of(to) != RANK_5
594 || !square_empty(from + DELTA_S))
602 else if (!(attacks_from(pc, from) & to))
605 // Evasions generator already takes care to avoid some kind of illegal moves
606 // and pl_move_is_legal() relies on this. So we have to take care that the
607 // same kind of moves are filtered out here.
610 if (type_of(pc) != KING)
612 Bitboard b = checkers();
613 Square checksq = pop_1st_bit(&b);
615 if (b) // double check ? In this case a king move is required
618 // Our move must be a blocking evasion or a capture of the checking piece
619 if (!((squares_between(checksq, king_square(us)) | checkers()) & to))
622 // In case of king moves under check we have to remove king so to catch
623 // as invalid moves like b1a1 when opposite queen is on c1.
624 else if (attackers_to(to, pieces() ^ from) & pieces(~us))
632 /// Position::move_gives_check() tests whether a pseudo-legal move gives a check
634 bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
637 assert(ci.dcCandidates == discovered_check_candidates());
638 assert(color_of(piece_moved(m)) == sideToMove);
640 Square from = from_sq(m);
641 Square to = to_sq(m);
642 PieceType pt = type_of(piece_on(from));
645 if (ci.checkSq[pt] & to)
649 if (ci.dcCandidates && (ci.dcCandidates & from))
651 // For pawn and king moves we need to verify also direction
652 if ( (pt != PAWN && pt != KING)
653 || !squares_aligned(from, to, king_square(~sideToMove)))
657 // Can we skip the ugly special cases ?
661 Color us = sideToMove;
662 Square ksq = king_square(~us);
664 // Promotion with check ?
666 return attacks_from(Piece(promotion_type(m)), to, pieces() ^ from) & ksq;
668 // En passant capture with check ? We have already handled the case
669 // of direct checks and ordinary discovered check, the only case we
670 // need to handle is the unusual case of a discovered check through
671 // the captured pawn.
674 Square capsq = make_square(file_of(to), rank_of(from));
675 Bitboard b = (pieces() ^ from ^ capsq) | to;
677 return (attacks_bb< ROOK>(ksq, b) & pieces( ROOK, QUEEN, us))
678 | (attacks_bb<BISHOP>(ksq, b) & pieces(BISHOP, QUEEN, us));
681 // Castling with check ?
685 Square rfrom = to; // 'King captures the rook' notation
686 Square kto = relative_square(us, rfrom > kfrom ? SQ_G1 : SQ_C1);
687 Square rto = relative_square(us, rfrom > kfrom ? SQ_F1 : SQ_D1);
688 Bitboard b = (pieces() ^ kfrom ^ rfrom) | rto | kto;
690 return attacks_bb<ROOK>(rto, b) & ksq;
697 /// Position::do_move() makes a move, and saves all information necessary
698 /// to a StateInfo object. The move is assumed to be legal. Pseudo-legal
699 /// moves should be filtered out before this function is called.
701 void Position::do_move(Move m, StateInfo& newSt) {
704 do_move(m, newSt, ci, move_gives_check(m, ci));
707 void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveIsCheck) {
710 assert(&newSt != st);
715 // Copy some fields of old state to our new StateInfo object except the ones
716 // which are recalculated from scratch anyway, then switch our state pointer
717 // to point to the new, ready to be updated, state.
718 struct ReducedStateInfo {
719 Key pawnKey, materialKey;
721 int castleRights, rule50, pliesFromNull;
726 memcpy(&newSt, st, sizeof(ReducedStateInfo));
731 // Update side to move
734 // Increment the 50 moves rule draw counter. Resetting it to zero in the
735 // case of a capture or a pawn move is taken care of later.
742 do_castle_move<true>(m);
746 Color us = sideToMove;
748 Square from = from_sq(m);
749 Square to = to_sq(m);
750 Piece piece = piece_on(from);
751 PieceType pt = type_of(piece);
752 PieceType capture = is_enpassant(m) ? PAWN : type_of(piece_on(to));
754 assert(color_of(piece) == us);
755 assert(color_of(piece_on(to)) != us);
756 assert(capture != KING);
762 // If the captured piece is a pawn, update pawn hash key, otherwise
763 // update non-pawn material.
768 capsq += pawn_push(them);
771 assert(to == st->epSquare);
772 assert(relative_rank(us, to) == RANK_6);
773 assert(piece_on(to) == NO_PIECE);
774 assert(piece_on(capsq) == make_piece(them, PAWN));
776 board[capsq] = NO_PIECE;
779 st->pawnKey ^= zobrist[them][PAWN][capsq];
782 st->npMaterial[them] -= PieceValueMidgame[capture];
784 // Remove the captured piece
785 byTypeBB[ALL_PIECES] ^= capsq;
786 byTypeBB[capture] ^= capsq;
787 byColorBB[them] ^= capsq;
789 // Update piece list, move the last piece at index[capsq] position and
792 // WARNING: This is a not revresible operation. When we will reinsert the
793 // captured piece in undo_move() we will put it at the end of the list and
794 // not in its original place, it means index[] and pieceList[] are not
795 // guaranteed to be invariant to a do_move() + undo_move() sequence.
796 Square lastSquare = pieceList[them][capture][--pieceCount[them][capture]];
797 index[lastSquare] = index[capsq];
798 pieceList[them][capture][index[lastSquare]] = lastSquare;
799 pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE;
802 k ^= zobrist[them][capture][capsq];
803 st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]];
805 // Update incremental scores
806 st->psqScore -= pieceSquareTable[make_piece(them, capture)][capsq];
808 // Reset rule 50 counter
813 k ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];
815 // Reset en passant square
816 if (st->epSquare != SQ_NONE)
818 k ^= zobEp[file_of(st->epSquare)];
819 st->epSquare = SQ_NONE;
822 // Update castle rights if needed
823 if (st->castleRights && (castleRightsMask[from] | castleRightsMask[to]))
825 int cr = castleRightsMask[from] | castleRightsMask[to];
826 k ^= zobCastle[st->castleRights & cr];
827 st->castleRights &= ~cr;
830 // Prefetch TT access as soon as we know key is updated
831 prefetch((char*)TT.first_entry(k));
834 Bitboard from_to_bb = SquareBB[from] | SquareBB[to];
835 byTypeBB[ALL_PIECES] ^= from_to_bb;
836 byTypeBB[pt] ^= from_to_bb;
837 byColorBB[us] ^= from_to_bb;
839 board[to] = board[from];
840 board[from] = NO_PIECE;
842 // Update piece lists, index[from] is not updated and becomes stale. This
843 // works as long as index[] is accessed just by known occupied squares.
844 index[to] = index[from];
845 pieceList[us][pt][index[to]] = to;
847 // If the moving piece is a pawn do some special extra work
850 // Set en-passant square, only if moved pawn can be captured
851 if ( (int(to) ^ int(from)) == 16
852 && (attacks_from<PAWN>(from + pawn_push(us), us) & pieces(PAWN, them)))
854 st->epSquare = Square((from + to) / 2);
855 k ^= zobEp[file_of(st->epSquare)];
860 PieceType promotion = promotion_type(m);
862 assert(relative_rank(us, to) == RANK_8);
863 assert(promotion >= KNIGHT && promotion <= QUEEN);
865 // Replace the pawn with the promoted piece
866 byTypeBB[PAWN] ^= to;
867 byTypeBB[promotion] |= to;
868 board[to] = make_piece(us, promotion);
870 // Update piece lists, move the last pawn at index[to] position
871 // and shrink the list. Add a new promotion piece to the list.
872 Square lastSquare = pieceList[us][PAWN][--pieceCount[us][PAWN]];
873 index[lastSquare] = index[to];
874 pieceList[us][PAWN][index[lastSquare]] = lastSquare;
875 pieceList[us][PAWN][pieceCount[us][PAWN]] = SQ_NONE;
876 index[to] = pieceCount[us][promotion];
877 pieceList[us][promotion][index[to]] = to;
880 k ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to];
881 st->pawnKey ^= zobrist[us][PAWN][to];
882 st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]++]
883 ^ zobrist[us][PAWN][pieceCount[us][PAWN]];
885 // Update incremental score
886 st->psqScore += pieceSquareTable[make_piece(us, promotion)][to]
887 - pieceSquareTable[make_piece(us, PAWN)][to];
890 st->npMaterial[us] += PieceValueMidgame[promotion];
893 // Update pawn hash key
894 st->pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to];
896 // Reset rule 50 draw counter
900 // Prefetch pawn and material hash tables
901 prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]);
902 prefetch((char*)thisThread->materialTable.entries[st->materialKey]);
904 // Update incremental scores
905 st->psqScore += psq_delta(piece, from, to);
908 st->capturedType = capture;
910 // Update the key with the final value
913 // Update checkers bitboard, piece must be already moved
919 st->checkersBB = attackers_to(king_square(them)) & pieces(us);
923 if (ci.checkSq[pt] & to)
924 st->checkersBB |= to;
927 if (ci.dcCandidates && (ci.dcCandidates & from))
930 st->checkersBB |= attacks_from<ROOK>(king_square(them)) & pieces(ROOK, QUEEN, us);
933 st->checkersBB |= attacks_from<BISHOP>(king_square(them)) & pieces(BISHOP, QUEEN, us);
939 sideToMove = ~sideToMove;
940 st->psqScore += (sideToMove == WHITE ? Tempo : -Tempo);
946 /// Position::undo_move() unmakes a move. When it returns, the position should
947 /// be restored to exactly the same state as before the move was made.
949 void Position::undo_move(Move m) {
953 sideToMove = ~sideToMove;
957 do_castle_move<false>(m);
961 Color us = sideToMove;
963 Square from = from_sq(m);
964 Square to = to_sq(m);
965 Piece piece = piece_on(to);
966 PieceType pt = type_of(piece);
967 PieceType capture = st->capturedType;
969 assert(square_empty(from));
970 assert(color_of(piece) == us);
971 assert(capture != KING);
975 PieceType promotion = promotion_type(m);
977 assert(promotion == pt);
978 assert(relative_rank(us, to) == RANK_8);
979 assert(promotion >= KNIGHT && promotion <= QUEEN);
981 // Replace the promoted piece with the pawn
982 byTypeBB[promotion] ^= to;
983 byTypeBB[PAWN] |= to;
984 board[to] = make_piece(us, PAWN);
986 // Update piece lists, move the last promoted piece at index[to] position
987 // and shrink the list. Add a new pawn to the list.
988 Square lastSquare = pieceList[us][promotion][--pieceCount[us][promotion]];
989 index[lastSquare] = index[to];
990 pieceList[us][promotion][index[lastSquare]] = lastSquare;
991 pieceList[us][promotion][pieceCount[us][promotion]] = SQ_NONE;
992 index[to] = pieceCount[us][PAWN]++;
993 pieceList[us][PAWN][index[to]] = to;
998 // Put the piece back at the source square
999 Bitboard from_to_bb = SquareBB[from] | SquareBB[to];
1000 byTypeBB[ALL_PIECES] ^= from_to_bb;
1001 byTypeBB[pt] ^= from_to_bb;
1002 byColorBB[us] ^= from_to_bb;
1004 board[from] = board[to];
1005 board[to] = NO_PIECE;
1007 // Update piece lists, index[to] is not updated and becomes stale. This
1008 // works as long as index[] is accessed just by known occupied squares.
1009 index[from] = index[to];
1010 pieceList[us][pt][index[from]] = from;
1016 if (is_enpassant(m))
1018 capsq -= pawn_push(us);
1021 assert(to == st->previous->epSquare);
1022 assert(relative_rank(us, to) == RANK_6);
1023 assert(piece_on(capsq) == NO_PIECE);
1026 // Restore the captured piece
1027 byTypeBB[ALL_PIECES] |= capsq;
1028 byTypeBB[capture] |= capsq;
1029 byColorBB[them] |= capsq;
1031 board[capsq] = make_piece(them, capture);
1033 // Update piece list, add a new captured piece in capsq square
1034 index[capsq] = pieceCount[them][capture]++;
1035 pieceList[them][capture][index[capsq]] = capsq;
1038 // Finally point our state pointer back to the previous state
1041 assert(pos_is_ok());
1045 /// Position::do_castle_move() is a private method used to do/undo a castling
1046 /// move. Note that castling moves are encoded as "king captures friendly rook"
1047 /// moves, for instance white short castling in a non-Chess960 game is encoded
1050 void Position::do_castle_move(Move m) {
1053 assert(is_castle(m));
1055 Square kto, kfrom, rfrom, rto, kAfter, rAfter;
1057 Color us = sideToMove;
1058 Square kBefore = from_sq(m);
1059 Square rBefore = to_sq(m);
1061 // Find after-castle squares for king and rook
1062 if (rBefore > kBefore) // O-O
1064 kAfter = relative_square(us, SQ_G1);
1065 rAfter = relative_square(us, SQ_F1);
1069 kAfter = relative_square(us, SQ_C1);
1070 rAfter = relative_square(us, SQ_D1);
1073 kfrom = Do ? kBefore : kAfter;
1074 rfrom = Do ? rBefore : rAfter;
1076 kto = Do ? kAfter : kBefore;
1077 rto = Do ? rAfter : rBefore;
1079 assert(piece_on(kfrom) == make_piece(us, KING));
1080 assert(piece_on(rfrom) == make_piece(us, ROOK));
1082 // Remove pieces from source squares
1083 byTypeBB[ALL_PIECES] ^= kfrom;
1084 byTypeBB[KING] ^= kfrom;
1085 byColorBB[us] ^= kfrom;
1086 byTypeBB[ALL_PIECES] ^= rfrom;
1087 byTypeBB[ROOK] ^= rfrom;
1088 byColorBB[us] ^= rfrom;
1090 // Put pieces on destination squares
1091 byTypeBB[ALL_PIECES] |= kto;
1092 byTypeBB[KING] |= kto;
1093 byColorBB[us] |= kto;
1094 byTypeBB[ALL_PIECES] |= rto;
1095 byTypeBB[ROOK] |= rto;
1096 byColorBB[us] |= rto;
1099 Piece king = make_piece(us, KING);
1100 Piece rook = make_piece(us, ROOK);
1101 board[kfrom] = board[rfrom] = NO_PIECE;
1105 // Update piece lists
1106 pieceList[us][KING][index[kfrom]] = kto;
1107 pieceList[us][ROOK][index[rfrom]] = rto;
1108 int tmp = index[rfrom]; // In Chess960 could be kto == rfrom
1109 index[kto] = index[kfrom];
1114 // Reset capture field
1115 st->capturedType = NO_PIECE_TYPE;
1117 // Update incremental scores
1118 st->psqScore += psq_delta(king, kfrom, kto);
1119 st->psqScore += psq_delta(rook, rfrom, rto);
1122 st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto];
1123 st->key ^= zobrist[us][ROOK][rfrom] ^ zobrist[us][ROOK][rto];
1125 // Clear en passant square
1126 if (st->epSquare != SQ_NONE)
1128 st->key ^= zobEp[file_of(st->epSquare)];
1129 st->epSquare = SQ_NONE;
1132 // Update castling rights
1133 st->key ^= zobCastle[st->castleRights & castleRightsMask[kfrom]];
1134 st->castleRights &= ~castleRightsMask[kfrom];
1136 // Update checkers BB
1137 st->checkersBB = attackers_to(king_square(~us)) & pieces(us);
1140 sideToMove = ~sideToMove;
1141 st->psqScore += (sideToMove == WHITE ? Tempo : -Tempo);
1144 // Undo: point our state pointer back to the previous state
1147 assert(pos_is_ok());
1151 /// Position::do_null_move() is used to do/undo a "null move": It flips the side
1152 /// to move and updates the hash key without executing any move on the board.
1154 void Position::do_null_move(StateInfo& backupSt) {
1156 assert(!in_check());
1158 // Back up the information necessary to undo the null move to the supplied
1159 // StateInfo object. Note that differently from normal case here backupSt
1160 // is actually used as a backup storage not as the new state. This reduces
1161 // the number of fields to be copied.
1162 StateInfo* src = Do ? st : &backupSt;
1163 StateInfo* dst = Do ? &backupSt : st;
1165 dst->key = src->key;
1166 dst->epSquare = src->epSquare;
1167 dst->psqScore = src->psqScore;
1168 dst->rule50 = src->rule50;
1169 dst->pliesFromNull = src->pliesFromNull;
1171 sideToMove = ~sideToMove;
1175 if (st->epSquare != SQ_NONE)
1176 st->key ^= zobEp[file_of(st->epSquare)];
1178 st->key ^= zobSideToMove;
1179 prefetch((char*)TT.first_entry(st->key));
1181 st->epSquare = SQ_NONE;
1183 st->pliesFromNull = 0;
1184 st->psqScore += (sideToMove == WHITE ? Tempo : -Tempo);
1187 assert(pos_is_ok());
1190 // Explicit template instantiations
1191 template void Position::do_null_move<false>(StateInfo& backupSt);
1192 template void Position::do_null_move<true>(StateInfo& backupSt);
1195 /// Position::see() is a static exchange evaluator: It tries to estimate the
1196 /// material gain or loss resulting from a move. There are three versions of
1197 /// this function: One which takes a destination square as input, one takes a
1198 /// move, and one which takes a 'from' and a 'to' square. The function does
1199 /// not yet understand promotions captures.
1201 int Position::see_sign(Move m) const {
1205 // Early return if SEE cannot be negative because captured piece value
1206 // is not less then capturing one. Note that king moves always return
1207 // here because king midgame value is set to 0.
1208 if (PieceValueMidgame[piece_on(to_sq(m))] >= PieceValueMidgame[piece_moved(m)])
1214 int Position::see(Move m) const {
1217 Bitboard occ, attackers, stmAttackers, b;
1218 int swapList[32], slIndex = 1;
1219 PieceType capturedType, pt;
1224 // As castle moves are implemented as capturing the rook, they have
1225 // SEE == RookValueMidgame most of the times (unless the rook is under
1232 capturedType = type_of(piece_on(to));
1235 // Handle en passant moves
1236 if (is_enpassant(m))
1238 Square capQq = to - pawn_push(sideToMove);
1240 assert(!capturedType);
1241 assert(type_of(piece_on(capQq)) == PAWN);
1243 // Remove the captured pawn
1245 capturedType = PAWN;
1248 // Find all attackers to the destination square, with the moving piece
1249 // removed, but possibly an X-ray attacker added behind it.
1251 attackers = attackers_to(to, occ);
1253 // If the opponent has no attackers we are finished
1254 stm = ~color_of(piece_on(from));
1255 stmAttackers = attackers & pieces(stm);
1257 return PieceValueMidgame[capturedType];
1259 // The destination square is defended, which makes things rather more
1260 // difficult to compute. We proceed by building up a "swap list" containing
1261 // the material gain or loss at each stop in a sequence of captures to the
1262 // destination square, where the sides alternately capture, and always
1263 // capture with the least valuable piece. After each capture, we look for
1264 // new X-ray attacks from behind the capturing piece.
1265 swapList[0] = PieceValueMidgame[capturedType];
1266 capturedType = type_of(piece_on(from));
1269 // Locate the least valuable attacker for the side to move. The loop
1270 // below looks like it is potentially infinite, but it isn't. We know
1271 // that the side to move still has at least one attacker left.
1272 for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
1275 // Remove the attacker we just found from the 'occupied' bitboard,
1276 // and scan for new X-ray attacks behind the attacker.
1277 b = stmAttackers & pieces(pt);
1278 occ ^= (b & (~b + 1));
1279 attackers |= (attacks_bb<ROOK>(to, occ) & pieces(ROOK, QUEEN))
1280 | (attacks_bb<BISHOP>(to, occ) & pieces(BISHOP, QUEEN));
1282 attackers &= occ; // Cut out pieces we've already done
1284 // Add the new entry to the swap list
1285 assert(slIndex < 32);
1286 swapList[slIndex] = -swapList[slIndex - 1] + PieceValueMidgame[capturedType];
1289 // Remember the value of the capturing piece, and change the side to
1290 // move before beginning the next iteration.
1293 stmAttackers = attackers & pieces(stm);
1295 // Stop before processing a king capture
1296 if (capturedType == KING && stmAttackers)
1298 assert(slIndex < 32);
1299 swapList[slIndex++] = QueenValueMidgame*10;
1302 } while (stmAttackers);
1304 // Having built the swap list, we negamax through it to find the best
1305 // achievable score from the point of view of the side to move.
1307 swapList[slIndex-1] = std::min(-swapList[slIndex], swapList[slIndex-1]);
1313 /// Position::clear() erases the position object to a pristine state, with an
1314 /// empty board, white to move, and no castling rights.
1316 void Position::clear() {
1318 memset(this, 0, sizeof(Position));
1319 startState.epSquare = SQ_NONE;
1322 for (int i = 0; i < 8; i++)
1323 for (int j = 0; j < 16; j++)
1324 pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE;
1326 for (Square sq = SQ_A1; sq <= SQ_H8; sq++)
1327 board[sq] = NO_PIECE;
1331 /// Position::put_piece() puts a piece on the given square of the board,
1332 /// updating the board array, pieces list, bitboards, and piece counts.
1334 void Position::put_piece(Piece p, Square s) {
1336 Color c = color_of(p);
1337 PieceType pt = type_of(p);
1340 index[s] = pieceCount[c][pt]++;
1341 pieceList[c][pt][index[s]] = s;
1343 byTypeBB[ALL_PIECES] |= s;
1349 /// Position::compute_key() computes the hash key of the position. The hash
1350 /// key is usually updated incrementally as moves are made and unmade, the
1351 /// compute_key() function is only used when a new position is set up, and
1352 /// to verify the correctness of the hash key when running in debug mode.
1354 Key Position::compute_key() const {
1356 Key result = zobCastle[st->castleRights];
1358 for (Square s = SQ_A1; s <= SQ_H8; s++)
1359 if (!square_empty(s))
1360 result ^= zobrist[color_of(piece_on(s))][type_of(piece_on(s))][s];
1362 if (ep_square() != SQ_NONE)
1363 result ^= zobEp[file_of(ep_square())];
1365 if (sideToMove == BLACK)
1366 result ^= zobSideToMove;
1372 /// Position::compute_pawn_key() computes the hash key of the position. The
1373 /// hash key is usually updated incrementally as moves are made and unmade,
1374 /// the compute_pawn_key() function is only used when a new position is set
1375 /// up, and to verify the correctness of the pawn hash key when running in
1378 Key Position::compute_pawn_key() const {
1383 for (Color c = WHITE; c <= BLACK; c++)
1385 b = pieces(PAWN, c);
1387 result ^= zobrist[c][PAWN][pop_1st_bit(&b)];
1393 /// Position::compute_material_key() computes the hash key of the position.
1394 /// The hash key is usually updated incrementally as moves are made and unmade,
1395 /// the compute_material_key() function is only used when a new position is set
1396 /// up, and to verify the correctness of the material hash key when running in
1399 Key Position::compute_material_key() const {
1403 for (Color c = WHITE; c <= BLACK; c++)
1404 for (PieceType pt = PAWN; pt <= QUEEN; pt++)
1405 for (int i = 0; i < piece_count(c, pt); i++)
1406 result ^= zobrist[c][pt][i];
1412 /// Position::compute_psq_score() computes the incremental scores for the middle
1413 /// game and the endgame. These functions are used to initialize the incremental
1414 /// scores when a new position is set up, and to verify that the scores are correctly
1415 /// updated by do_move and undo_move when the program is running in debug mode.
1416 Score Position::compute_psq_score() const {
1419 Score result = SCORE_ZERO;
1421 for (Color c = WHITE; c <= BLACK; c++)
1422 for (PieceType pt = PAWN; pt <= KING; pt++)
1426 result += pieceSquareTable[make_piece(c, pt)][pop_1st_bit(&b)];
1429 result += (sideToMove == WHITE ? Tempo / 2 : -Tempo / 2);
1434 /// Position::compute_non_pawn_material() computes the total non-pawn middle
1435 /// game material value for the given side. Material values are updated
1436 /// incrementally during the search, this function is only used while
1437 /// initializing a new Position object.
1439 Value Position::compute_non_pawn_material(Color c) const {
1441 Value result = VALUE_ZERO;
1443 for (PieceType pt = KNIGHT; pt <= QUEEN; pt++)
1444 result += piece_count(c, pt) * PieceValueMidgame[pt];
1450 /// Position::is_draw() tests whether the position is drawn by material,
1451 /// repetition, or the 50 moves rule. It does not detect stalemates, this
1452 /// must be done by the search.
1453 template<bool SkipRepetition>
1454 bool Position::is_draw() const {
1456 // Draw by material?
1458 && (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMidgame))
1461 // Draw by the 50 moves rule?
1462 if (st->rule50 > 99 && (!in_check() || MoveList<MV_LEGAL>(*this).size()))
1465 // Draw by repetition?
1466 if (!SkipRepetition)
1468 int i = 4, e = std::min(st->rule50, st->pliesFromNull);
1472 StateInfo* stp = st->previous->previous;
1475 stp = stp->previous->previous;
1477 if (stp->key == st->key)
1489 // Explicit template instantiations
1490 template bool Position::is_draw<false>() const;
1491 template bool Position::is_draw<true>() const;
1494 /// Position::init() is a static member function which initializes at startup
1495 /// the various arrays used to compute hash keys and the piece square tables.
1496 /// The latter is a two-step operation: First, the white halves of the tables
1497 /// are copied from PSQT[] tables. Second, the black halves of the tables are
1498 /// initialized by flipping and changing the sign of the white scores.
1500 void Position::init() {
1504 for (Color c = WHITE; c <= BLACK; c++)
1505 for (PieceType pt = PAWN; pt <= KING; pt++)
1506 for (Square s = SQ_A1; s <= SQ_H8; s++)
1507 zobrist[c][pt][s] = rk.rand<Key>();
1509 for (File f = FILE_A; f <= FILE_H; f++)
1510 zobEp[f] = rk.rand<Key>();
1512 for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++)
1517 Key k = zobCastle[1ULL << pop_1st_bit(&b)];
1518 zobCastle[cr] ^= k ? k : rk.rand<Key>();
1522 zobSideToMove = rk.rand<Key>();
1523 zobExclusion = rk.rand<Key>();
1525 for (Piece p = W_PAWN; p <= W_KING; p++)
1527 Score ps = make_score(PieceValueMidgame[p], PieceValueEndgame[p]);
1529 for (Square s = SQ_A1; s <= SQ_H8; s++)
1531 pieceSquareTable[p][s] = ps + PSQT[p][s];
1532 pieceSquareTable[p+8][~s] = -pieceSquareTable[p][s];
1538 /// Position::flip() flips position with the white and black sides reversed. This
1539 /// is only useful for debugging especially for finding evaluation symmetry bugs.
1541 void Position::flip() {
1543 // Make a copy of current position before to start changing
1544 const Position pos(*this, thisThread);
1547 thisThread = &pos.this_thread();
1550 for (Square s = SQ_A1; s <= SQ_H8; s++)
1551 if (!pos.square_empty(s))
1552 put_piece(Piece(pos.piece_on(s) ^ 8), ~s);
1555 sideToMove = ~pos.side_to_move();
1558 if (pos.can_castle(WHITE_OO))
1559 set_castle_right(BLACK, ~pos.castle_rook_square(WHITE_OO));
1560 if (pos.can_castle(WHITE_OOO))
1561 set_castle_right(BLACK, ~pos.castle_rook_square(WHITE_OOO));
1562 if (pos.can_castle(BLACK_OO))
1563 set_castle_right(WHITE, ~pos.castle_rook_square(BLACK_OO));
1564 if (pos.can_castle(BLACK_OOO))
1565 set_castle_right(WHITE, ~pos.castle_rook_square(BLACK_OOO));
1567 // En passant square
1568 if (pos.st->epSquare != SQ_NONE)
1569 st->epSquare = ~pos.st->epSquare;
1572 st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
1575 st->key = compute_key();
1576 st->pawnKey = compute_pawn_key();
1577 st->materialKey = compute_material_key();
1579 // Incremental scores
1580 st->psqScore = compute_psq_score();
1583 st->npMaterial[WHITE] = compute_non_pawn_material(WHITE);
1584 st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
1586 assert(pos_is_ok());
1590 /// Position::pos_is_ok() performs some consitency checks for the position object.
1591 /// This is meant to be helpful when debugging.
1593 bool Position::pos_is_ok(int* failedStep) const {
1595 // What features of the position should be verified?
1596 const bool debugAll = false;
1598 const bool debugBitboards = debugAll || false;
1599 const bool debugKingCount = debugAll || false;
1600 const bool debugKingCapture = debugAll || false;
1601 const bool debugCheckerCount = debugAll || false;
1602 const bool debugKey = debugAll || false;
1603 const bool debugMaterialKey = debugAll || false;
1604 const bool debugPawnKey = debugAll || false;
1605 const bool debugIncrementalEval = debugAll || false;
1606 const bool debugNonPawnMaterial = debugAll || false;
1607 const bool debugPieceCounts = debugAll || false;
1608 const bool debugPieceList = debugAll || false;
1609 const bool debugCastleSquares = debugAll || false;
1611 if (failedStep) *failedStep = 1;
1614 if (sideToMove != WHITE && sideToMove != BLACK)
1617 // Are the king squares in the position correct?
1618 if (failedStep) (*failedStep)++;
1619 if (piece_on(king_square(WHITE)) != W_KING)
1622 if (failedStep) (*failedStep)++;
1623 if (piece_on(king_square(BLACK)) != B_KING)
1626 // Do both sides have exactly one king?
1627 if (failedStep) (*failedStep)++;
1630 int kingCount[2] = {0, 0};
1631 for (Square s = SQ_A1; s <= SQ_H8; s++)
1632 if (type_of(piece_on(s)) == KING)
1633 kingCount[color_of(piece_on(s))]++;
1635 if (kingCount[0] != 1 || kingCount[1] != 1)
1639 // Can the side to move capture the opponent's king?
1640 if (failedStep) (*failedStep)++;
1641 if (debugKingCapture)
1643 Color us = sideToMove;
1645 Square ksq = king_square(them);
1646 if (attackers_to(ksq) & pieces(us))
1650 // Is there more than 2 checkers?
1651 if (failedStep) (*failedStep)++;
1652 if (debugCheckerCount && popcount<Full>(st->checkersBB) > 2)
1656 if (failedStep) (*failedStep)++;
1659 // The intersection of the white and black pieces must be empty
1660 if (pieces(WHITE) & pieces(BLACK))
1663 // The union of the white and black pieces must be equal to all
1665 if ((pieces(WHITE) | pieces(BLACK)) != pieces())
1668 // Separate piece type bitboards must have empty intersections
1669 for (PieceType p1 = PAWN; p1 <= KING; p1++)
1670 for (PieceType p2 = PAWN; p2 <= KING; p2++)
1671 if (p1 != p2 && (pieces(p1) & pieces(p2)))
1675 // En passant square OK?
1676 if (failedStep) (*failedStep)++;
1677 if (ep_square() != SQ_NONE)
1679 // The en passant square must be on rank 6, from the point of view of the
1681 if (relative_rank(sideToMove, ep_square()) != RANK_6)
1686 if (failedStep) (*failedStep)++;
1687 if (debugKey && st->key != compute_key())
1690 // Pawn hash key OK?
1691 if (failedStep) (*failedStep)++;
1692 if (debugPawnKey && st->pawnKey != compute_pawn_key())
1695 // Material hash key OK?
1696 if (failedStep) (*failedStep)++;
1697 if (debugMaterialKey && st->materialKey != compute_material_key())
1700 // Incremental eval OK?
1701 if (failedStep) (*failedStep)++;
1702 if (debugIncrementalEval && st->psqScore != compute_psq_score())
1705 // Non-pawn material OK?
1706 if (failedStep) (*failedStep)++;
1707 if (debugNonPawnMaterial)
1709 if (st->npMaterial[WHITE] != compute_non_pawn_material(WHITE))
1712 if (st->npMaterial[BLACK] != compute_non_pawn_material(BLACK))
1717 if (failedStep) (*failedStep)++;
1718 if (debugPieceCounts)
1719 for (Color c = WHITE; c <= BLACK; c++)
1720 for (PieceType pt = PAWN; pt <= KING; pt++)
1721 if (pieceCount[c][pt] != popcount<Full>(pieces(pt, c)))
1724 if (failedStep) (*failedStep)++;
1726 for (Color c = WHITE; c <= BLACK; c++)
1727 for (PieceType pt = PAWN; pt <= KING; pt++)
1728 for (int i = 0; i < pieceCount[c][pt]; i++)
1730 if (piece_on(piece_list(c, pt)[i]) != make_piece(c, pt))
1733 if (index[piece_list(c, pt)[i]] != i)
1737 if (failedStep) (*failedStep)++;
1738 if (debugCastleSquares)
1739 for (CastleRight f = WHITE_OO; f <= BLACK_OOO; f = CastleRight(f << 1))
1744 Piece rook = (f & (WHITE_OO | WHITE_OOO) ? W_ROOK : B_ROOK);
1746 if ( piece_on(castleRookSquare[f]) != rook
1747 || castleRightsMask[castleRookSquare[f]] != f)
1751 if (failedStep) *failedStep = 0;