"Fossies" - the Fresh Open Source Software Archive

Member "stockfish-11-linux/src/position.h" (18 Jan 2020, 13557 Bytes) of package /linux/privat/stockfish-11-linux.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "position.h": 9-linux_vs_10-linux.

    1 /*
    2   Stockfish, a UCI chess playing engine derived from Glaurung 2.1
    3   Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
    4   Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
    5   Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
    6 
    7   Stockfish is free software: you can redistribute it and/or modify
    8   it under the terms of the GNU General Public License as published by
    9   the Free Software Foundation, either version 3 of the License, or
   10   (at your option) any later version.
   11 
   12   Stockfish is distributed in the hope that it will be useful,
   13   but WITHOUT ANY WARRANTY; without even the implied warranty of
   14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15   GNU General Public License for more details.
   16 
   17   You should have received a copy of the GNU General Public License
   18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
   19 */
   20 
   21 #ifndef POSITION_H_INCLUDED
   22 #define POSITION_H_INCLUDED
   23 
   24 #include <cassert>
   25 #include <deque>
   26 #include <memory> // For std::unique_ptr
   27 #include <string>
   28 
   29 #include "bitboard.h"
   30 #include "types.h"
   31 
   32 
   33 /// StateInfo struct stores information needed to restore a Position object to
   34 /// its previous state when we retract a move. Whenever a move is made on the
   35 /// board (by calling Position::do_move), a StateInfo object must be passed.
   36 
   37 struct StateInfo {
   38 
   39   // Copied when making a move
   40   Key    pawnKey;
   41   Key    materialKey;
   42   Value  nonPawnMaterial[COLOR_NB];
   43   int    castlingRights;
   44   int    rule50;
   45   int    pliesFromNull;
   46   Square epSquare;
   47 
   48   // Not copied when making a move (will be recomputed anyhow)
   49   Key        key;
   50   Bitboard   checkersBB;
   51   Piece      capturedPiece;
   52   StateInfo* previous;
   53   Bitboard   blockersForKing[COLOR_NB];
   54   Bitboard   pinners[COLOR_NB];
   55   Bitboard   checkSquares[PIECE_TYPE_NB];
   56   int        repetition;
   57 };
   58 
   59 /// A list to keep track of the position states along the setup moves (from the
   60 /// start position to the position just before the search starts). Needed by
   61 /// 'draw by repetition' detection. Use a std::deque because pointers to
   62 /// elements are not invalidated upon list resizing.
   63 typedef std::unique_ptr<std::deque<StateInfo>> StateListPtr;
   64 
   65 
   66 /// Position class stores information regarding the board representation as
   67 /// pieces, side to move, hash keys, castling info, etc. Important methods are
   68 /// do_move() and undo_move(), used by the search to update node info when
   69 /// traversing the search tree.
   70 class Thread;
   71 
   72 class Position {
   73 public:
   74   static void init();
   75 
   76   Position() = default;
   77   Position(const Position&) = delete;
   78   Position& operator=(const Position&) = delete;
   79 
   80   // FEN string input/output
   81   Position& set(const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th);
   82   Position& set(const std::string& code, Color c, StateInfo* si);
   83   const std::string fen() const;
   84 
   85   // Position representation
   86   Bitboard pieces() const;
   87   Bitboard pieces(PieceType pt) const;
   88   Bitboard pieces(PieceType pt1, PieceType pt2) const;
   89   Bitboard pieces(Color c) const;
   90   Bitboard pieces(Color c, PieceType pt) const;
   91   Bitboard pieces(Color c, PieceType pt1, PieceType pt2) const;
   92   Piece piece_on(Square s) const;
   93   Square ep_square() const;
   94   bool empty(Square s) const;
   95   template<PieceType Pt> int count(Color c) const;
   96   template<PieceType Pt> int count() const;
   97   template<PieceType Pt> const Square* squares(Color c) const;
   98   template<PieceType Pt> Square square(Color c) const;
   99   bool is_on_semiopen_file(Color c, Square s) const;
  100 
  101   // Castling
  102   int castling_rights(Color c) const;
  103   bool can_castle(CastlingRights cr) const;
  104   bool castling_impeded(CastlingRights cr) const;
  105   Square castling_rook_square(CastlingRights cr) const;
  106 
  107   // Checking
  108   Bitboard checkers() const;
  109   Bitboard blockers_for_king(Color c) const;
  110   Bitboard check_squares(PieceType pt) const;
  111   bool is_discovery_check_on_king(Color c, Move m) const;
  112 
  113   // Attacks to/from a given square
  114   Bitboard attackers_to(Square s) const;
  115   Bitboard attackers_to(Square s, Bitboard occupied) const;
  116   Bitboard attacks_from(PieceType pt, Square s) const;
  117   template<PieceType> Bitboard attacks_from(Square s) const;
  118   template<PieceType> Bitboard attacks_from(Square s, Color c) const;
  119   Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const;
  120 
  121   // Properties of moves
  122   bool legal(Move m) const;
  123   bool pseudo_legal(const Move m) const;
  124   bool capture(Move m) const;
  125   bool capture_or_promotion(Move m) const;
  126   bool gives_check(Move m) const;
  127   bool advanced_pawn_push(Move m) const;
  128   Piece moved_piece(Move m) const;
  129   Piece captured_piece() const;
  130 
  131   // Piece specific
  132   bool pawn_passed(Color c, Square s) const;
  133   bool opposite_bishops() const;
  134   int  pawns_on_same_color_squares(Color c, Square s) const;
  135 
  136   // Doing and undoing moves
  137   void do_move(Move m, StateInfo& newSt);
  138   void do_move(Move m, StateInfo& newSt, bool givesCheck);
  139   void undo_move(Move m);
  140   void do_null_move(StateInfo& newSt);
  141   void undo_null_move();
  142 
  143   // Static Exchange Evaluation
  144   bool see_ge(Move m, Value threshold = VALUE_ZERO) const;
  145 
  146   // Accessing hash keys
  147   Key key() const;
  148   Key key_after(Move m) const;
  149   Key material_key() const;
  150   Key pawn_key() const;
  151 
  152   // Other properties of the position
  153   Color side_to_move() const;
  154   int game_ply() const;
  155   bool is_chess960() const;
  156   Thread* this_thread() const;
  157   bool is_draw(int ply) const;
  158   bool has_game_cycle(int ply) const;
  159   bool has_repeated() const;
  160   int rule50_count() const;
  161   Score psq_score() const;
  162   Value non_pawn_material(Color c) const;
  163   Value non_pawn_material() const;
  164 
  165   // Position consistency check, for debugging
  166   bool pos_is_ok() const;
  167   void flip();
  168 
  169 private:
  170   // Initialization helpers (used while setting up a position)
  171   void set_castling_right(Color c, Square rfrom);
  172   void set_state(StateInfo* si) const;
  173   void set_check_info(StateInfo* si) const;
  174 
  175   // Other helpers
  176   void put_piece(Piece pc, Square s);
  177   void remove_piece(Piece pc, Square s);
  178   void move_piece(Piece pc, Square from, Square to);
  179   template<bool Do>
  180   void do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto);
  181 
  182   // Data members
  183   Piece board[SQUARE_NB];
  184   Bitboard byTypeBB[PIECE_TYPE_NB];
  185   Bitboard byColorBB[COLOR_NB];
  186   int pieceCount[PIECE_NB];
  187   Square pieceList[PIECE_NB][16];
  188   int index[SQUARE_NB];
  189   int castlingRightsMask[SQUARE_NB];
  190   Square castlingRookSquare[CASTLING_RIGHT_NB];
  191   Bitboard castlingPath[CASTLING_RIGHT_NB];
  192   int gamePly;
  193   Color sideToMove;
  194   Score psq;
  195   Thread* thisThread;
  196   StateInfo* st;
  197   bool chess960;
  198 };
  199 
  200 namespace PSQT {
  201   extern Score psq[PIECE_NB][SQUARE_NB];
  202 }
  203 
  204 extern std::ostream& operator<<(std::ostream& os, const Position& pos);
  205 
  206 inline Color Position::side_to_move() const {
  207   return sideToMove;
  208 }
  209 
  210 inline bool Position::empty(Square s) const {
  211   return board[s] == NO_PIECE;
  212 }
  213 
  214 inline Piece Position::piece_on(Square s) const {
  215   return board[s];
  216 }
  217 
  218 inline Piece Position::moved_piece(Move m) const {
  219   return board[from_sq(m)];
  220 }
  221 
  222 inline Bitboard Position::pieces() const {
  223   return byTypeBB[ALL_PIECES];
  224 }
  225 
  226 inline Bitboard Position::pieces(PieceType pt) const {
  227   return byTypeBB[pt];
  228 }
  229 
  230 inline Bitboard Position::pieces(PieceType pt1, PieceType pt2) const {
  231   return byTypeBB[pt1] | byTypeBB[pt2];
  232 }
  233 
  234 inline Bitboard Position::pieces(Color c) const {
  235   return byColorBB[c];
  236 }
  237 
  238 inline Bitboard Position::pieces(Color c, PieceType pt) const {
  239   return byColorBB[c] & byTypeBB[pt];
  240 }
  241 
  242 inline Bitboard Position::pieces(Color c, PieceType pt1, PieceType pt2) const {
  243   return byColorBB[c] & (byTypeBB[pt1] | byTypeBB[pt2]);
  244 }
  245 
  246 template<PieceType Pt> inline int Position::count(Color c) const {
  247   return pieceCount[make_piece(c, Pt)];
  248 }
  249 
  250 template<PieceType Pt> inline int Position::count() const {
  251   return pieceCount[make_piece(WHITE, Pt)] + pieceCount[make_piece(BLACK, Pt)];
  252 }
  253 
  254 template<PieceType Pt> inline const Square* Position::squares(Color c) const {
  255   return pieceList[make_piece(c, Pt)];
  256 }
  257 
  258 template<PieceType Pt> inline Square Position::square(Color c) const {
  259   assert(pieceCount[make_piece(c, Pt)] == 1);
  260   return pieceList[make_piece(c, Pt)][0];
  261 }
  262 
  263 inline Square Position::ep_square() const {
  264   return st->epSquare;
  265 }
  266 
  267 inline bool Position::is_on_semiopen_file(Color c, Square s) const {
  268   return !(pieces(c, PAWN) & file_bb(s));
  269 }
  270 
  271 inline bool Position::can_castle(CastlingRights cr) const {
  272   return st->castlingRights & cr;
  273 }
  274 
  275 inline int Position::castling_rights(Color c) const {
  276   return st->castlingRights & (c == WHITE ? WHITE_CASTLING : BLACK_CASTLING);
  277 }
  278 
  279 inline bool Position::castling_impeded(CastlingRights cr) const {
  280   assert(cr == WHITE_OO || cr == WHITE_OOO || cr == BLACK_OO || cr == BLACK_OOO);
  281 
  282   return byTypeBB[ALL_PIECES] & castlingPath[cr];
  283 }
  284 
  285 inline Square Position::castling_rook_square(CastlingRights cr) const {
  286   assert(cr == WHITE_OO || cr == WHITE_OOO || cr == BLACK_OO || cr == BLACK_OOO);
  287 
  288   return castlingRookSquare[cr];
  289 }
  290 
  291 template<PieceType Pt>
  292 inline Bitboard Position::attacks_from(Square s) const {
  293   static_assert(Pt != PAWN, "Pawn attacks need color");
  294 
  295   return  Pt == BISHOP || Pt == ROOK ? attacks_bb<Pt>(s, byTypeBB[ALL_PIECES])
  296         : Pt == QUEEN  ? attacks_from<ROOK>(s) | attacks_from<BISHOP>(s)
  297         : PseudoAttacks[Pt][s];
  298 }
  299 
  300 template<>
  301 inline Bitboard Position::attacks_from<PAWN>(Square s, Color c) const {
  302   return PawnAttacks[c][s];
  303 }
  304 
  305 inline Bitboard Position::attacks_from(PieceType pt, Square s) const {
  306   return attacks_bb(pt, s, byTypeBB[ALL_PIECES]);
  307 }
  308 
  309 inline Bitboard Position::attackers_to(Square s) const {
  310   return attackers_to(s, byTypeBB[ALL_PIECES]);
  311 }
  312 
  313 inline Bitboard Position::checkers() const {
  314   return st->checkersBB;
  315 }
  316 
  317 inline Bitboard Position::blockers_for_king(Color c) const {
  318   return st->blockersForKing[c];
  319 }
  320 
  321 inline Bitboard Position::check_squares(PieceType pt) const {
  322   return st->checkSquares[pt];
  323 }
  324 
  325 inline bool Position::is_discovery_check_on_king(Color c, Move m) const {
  326   return st->blockersForKing[c] & from_sq(m);
  327 }
  328 
  329 inline bool Position::pawn_passed(Color c, Square s) const {
  330   return !(pieces(~c, PAWN) & passed_pawn_span(c, s));
  331 }
  332 
  333 inline bool Position::advanced_pawn_push(Move m) const {
  334   return   type_of(moved_piece(m)) == PAWN
  335         && relative_rank(sideToMove, to_sq(m)) > RANK_5;
  336 }
  337 
  338 inline int Position::pawns_on_same_color_squares(Color c, Square s) const {
  339   return popcount(pieces(c, PAWN) & ((DarkSquares & s) ? DarkSquares : ~DarkSquares));
  340 }
  341 
  342 inline Key Position::key() const {
  343   return st->key;
  344 }
  345 
  346 inline Key Position::pawn_key() const {
  347   return st->pawnKey;
  348 }
  349 
  350 inline Key Position::material_key() const {
  351   return st->materialKey;
  352 }
  353 
  354 inline Score Position::psq_score() const {
  355   return psq;
  356 }
  357 
  358 inline Value Position::non_pawn_material(Color c) const {
  359   return st->nonPawnMaterial[c];
  360 }
  361 
  362 inline Value Position::non_pawn_material() const {
  363   return st->nonPawnMaterial[WHITE] + st->nonPawnMaterial[BLACK];
  364 }
  365 
  366 inline int Position::game_ply() const {
  367   return gamePly;
  368 }
  369 
  370 inline int Position::rule50_count() const {
  371   return st->rule50;
  372 }
  373 
  374 inline bool Position::opposite_bishops() const {
  375   return   pieceCount[W_BISHOP] == 1
  376         && pieceCount[B_BISHOP] == 1
  377         && opposite_colors(square<BISHOP>(WHITE), square<BISHOP>(BLACK));
  378 }
  379 
  380 inline bool Position::is_chess960() const {
  381   return chess960;
  382 }
  383 
  384 inline bool Position::capture_or_promotion(Move m) const {
  385   assert(is_ok(m));
  386   return type_of(m) != NORMAL ? type_of(m) != CASTLING : !empty(to_sq(m));
  387 }
  388 
  389 inline bool Position::capture(Move m) const {
  390   assert(is_ok(m));
  391   // Castling is encoded as "king captures rook"
  392   return (!empty(to_sq(m)) && type_of(m) != CASTLING) || type_of(m) == ENPASSANT;
  393 }
  394 
  395 inline Piece Position::captured_piece() const {
  396   return st->capturedPiece;
  397 }
  398 
  399 inline Thread* Position::this_thread() const {
  400   return thisThread;
  401 }
  402 
  403 inline void Position::put_piece(Piece pc, Square s) {
  404 
  405   board[s] = pc;
  406   byTypeBB[ALL_PIECES] |= s;
  407   byTypeBB[type_of(pc)] |= s;
  408   byColorBB[color_of(pc)] |= s;
  409   index[s] = pieceCount[pc]++;
  410   pieceList[pc][index[s]] = s;
  411   pieceCount[make_piece(color_of(pc), ALL_PIECES)]++;
  412   psq += PSQT::psq[pc][s];
  413 }
  414 
  415 inline void Position::remove_piece(Piece pc, Square s) {
  416 
  417   // WARNING: This is not a reversible operation. If we remove a piece in
  418   // do_move() and then replace it in undo_move() we will put it at the end of
  419   // the list and not in its original place, it means index[] and pieceList[]
  420   // are not invariant to a do_move() + undo_move() sequence.
  421   byTypeBB[ALL_PIECES] ^= s;
  422   byTypeBB[type_of(pc)] ^= s;
  423   byColorBB[color_of(pc)] ^= s;
  424   /* board[s] = NO_PIECE;  Not needed, overwritten by the capturing one */
  425   Square lastSquare = pieceList[pc][--pieceCount[pc]];
  426   index[lastSquare] = index[s];
  427   pieceList[pc][index[lastSquare]] = lastSquare;
  428   pieceList[pc][pieceCount[pc]] = SQ_NONE;
  429   pieceCount[make_piece(color_of(pc), ALL_PIECES)]--;
  430   psq -= PSQT::psq[pc][s];
  431 }
  432 
  433 inline void Position::move_piece(Piece pc, Square from, Square to) {
  434 
  435   // index[from] is not updated and becomes stale. This works as long as index[]
  436   // is accessed just by known occupied squares.
  437   Bitboard fromTo = from | to;
  438   byTypeBB[ALL_PIECES] ^= fromTo;
  439   byTypeBB[type_of(pc)] ^= fromTo;
  440   byColorBB[color_of(pc)] ^= fromTo;
  441   board[from] = NO_PIECE;
  442   board[to] = pc;
  443   index[to] = index[from];
  444   pieceList[pc][index[to]] = to;
  445   psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];
  446 }
  447 
  448 inline void Position::do_move(Move m, StateInfo& newSt) {
  449   do_move(m, newSt, gives_check(m));
  450 }
  451 
  452 #endif // #ifndef POSITION_H_INCLUDED