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