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