]> git.sesse.net Git - stockfish/blob - src/position.h
Triviality in move_gives_check()
[stockfish] / src / position.h
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-2012 Marco Costalba, Joona Kiiski, Tord Romstad
5
6   Stockfish is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   Stockfish is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #if !defined(POSITION_H_INCLUDED)
21 #define POSITION_H_INCLUDED
22
23 #include <cassert>
24 #include <cstddef>
25
26 #include "bitboard.h"
27 #include "types.h"
28
29
30 /// The checkInfo struct is initialized at c'tor time and keeps info used
31 /// to detect if a move gives check.
32 class Position;
33 class Thread;
34
35 struct CheckInfo {
36
37   explicit CheckInfo(const Position&);
38
39   Bitboard dcCandidates;
40   Bitboard pinned;
41   Bitboard checkSq[PIECE_TYPE_NB];
42   Square ksq;
43 };
44
45
46 /// The StateInfo struct stores information we need to restore a Position
47 /// object to its previous state when we retract a move. Whenever a move
48 /// is made on the board (by calling Position::do_move), a StateInfo object
49 /// must be passed as a parameter.
50
51 struct StateInfo {
52   Key pawnKey, materialKey;
53   Value npMaterial[COLOR_NB];
54   int castleRights, rule50, pliesFromNull;
55   Score psqScore;
56   Square epSquare;
57
58   Key key;
59   Bitboard checkersBB;
60   PieceType capturedType;
61   StateInfo* previous;
62 };
63
64
65 /// When making a move the current StateInfo up to 'key' excluded is copied to
66 /// the new one. Here we calculate the quad words (64bits) needed to be copied.
67 const size_t StateCopySize64 = offsetof(StateInfo, key) / sizeof(uint64_t) + 1;
68
69
70 /// The position data structure. A position consists of the following data:
71 ///
72 ///    * For each piece type, a bitboard representing the squares occupied
73 ///      by pieces of that type.
74 ///    * For each color, a bitboard representing the squares occupied by
75 ///      pieces of that color.
76 ///    * A bitboard of all occupied squares.
77 ///    * A bitboard of all checking pieces.
78 ///    * A 64-entry array of pieces, indexed by the squares of the board.
79 ///    * The current side to move.
80 ///    * Information about the castling rights for both sides.
81 ///    * The initial files of the kings and both pairs of rooks. This is
82 ///      used to implement the Chess960 castling rules.
83 ///    * The en passant square (which is SQ_NONE if no en passant capture is
84 ///      possible).
85 ///    * The squares of the kings for both sides.
86 ///    * Hash keys for the position itself, the current pawn structure, and
87 ///      the current material situation.
88 ///    * Hash keys for all previous positions in the game for detecting
89 ///      repetition draws.
90 ///    * A counter for detecting 50 move rule draws.
91
92 class Position {
93 public:
94   Position() {}
95   Position(const Position& p, Thread* t) { *this = p; thisThread = t; }
96   Position(const std::string& f, bool c960, Thread* t) { set(f, c960, t); }
97   Position& operator=(const Position&);
98
99   // Text input/output
100   void set(const std::string& fen, bool isChess960, Thread* th);
101   const std::string fen() const;
102   const std::string pretty(Move m = MOVE_NONE) const;
103
104   // Position representation
105   Bitboard pieces() const;
106   Bitboard pieces(PieceType pt) const;
107   Bitboard pieces(PieceType pt1, PieceType pt2) const;
108   Bitboard pieces(Color c) const;
109   Bitboard pieces(Color c, PieceType pt) const;
110   Bitboard pieces(Color c, PieceType pt1, PieceType pt2) const;
111   Piece piece_on(Square s) const;
112   Square king_square(Color c) const;
113   Square ep_square() const;
114   bool is_empty(Square s) const;
115   const Square* piece_list(Color c, PieceType pt) const;
116   int piece_count(Color c, PieceType pt) const;
117
118   // Castling
119   int can_castle(CastleRight f) const;
120   int can_castle(Color c) const;
121   bool castle_impeded(Color c, CastlingSide s) const;
122   Square castle_rook_square(Color c, CastlingSide s) const;
123
124   // Checking
125   bool in_check() const;
126   Bitboard checkers() const;
127   Bitboard discovered_check_candidates() const;
128   Bitboard pinned_pieces() const;
129
130   // Attacks to/from a given square
131   Bitboard attackers_to(Square s) const;
132   Bitboard attackers_to(Square s, Bitboard occ) const;
133   Bitboard attacks_from(Piece p, Square s) const;
134   static Bitboard attacks_from(Piece p, Square s, Bitboard occ);
135   template<PieceType> Bitboard attacks_from(Square s) const;
136   template<PieceType> Bitboard attacks_from(Square s, Color c) const;
137
138   // Properties of moves
139   bool move_gives_check(Move m, const CheckInfo& ci) const;
140   bool move_is_legal(const Move m) const;
141   bool pl_move_is_legal(Move m, Bitboard pinned) const;
142   bool is_pseudo_legal(const Move m) const;
143   bool is_capture(Move m) const;
144   bool is_capture_or_promotion(Move m) const;
145   bool is_passed_pawn_push(Move m) const;
146   Piece piece_moved(Move m) const;
147   PieceType captured_piece_type() const;
148
149   // Piece specific
150   bool pawn_is_passed(Color c, Square s) const;
151   bool pawn_on_7th(Color c) const;
152   bool opposite_bishops() const;
153   bool bishop_pair(Color c) const;
154
155   // Doing and undoing moves
156   void do_move(Move m, StateInfo& st);
157   void do_move(Move m, StateInfo& st, const CheckInfo& ci, bool moveIsCheck);
158   void undo_move(Move m);
159   template<bool Do> void do_null_move(StateInfo& st);
160
161   // Static exchange evaluation
162   int see(Move m) const;
163   int see_sign(Move m) const;
164
165   // Accessing hash keys
166   Key key() const;
167   Key exclusion_key() const;
168   Key pawn_key() const;
169   Key material_key() const;
170
171   // Incremental piece-square evaluation
172   Score psq_score() const;
173   Score psq_delta(Piece p, Square from, Square to) const;
174   Value non_pawn_material(Color c) const;
175
176   // Other properties of the position
177   Color side_to_move() const;
178   int startpos_ply_counter() const;
179   bool is_chess960() const;
180   Thread* this_thread() const;
181   int64_t nodes_searched() const;
182   void set_nodes_searched(int64_t n);
183   template<bool CheckRepetition, bool CheckThreeFold> bool is_draw() const;
184
185   // Position consistency check, for debugging
186   bool pos_is_ok(int* failedStep = NULL) const;
187   void flip();
188
189 private:
190   // Initialization helpers (used while setting up a position)
191   void clear();
192   void put_piece(Piece p, Square s);
193   void set_castle_right(Color c, Square rfrom);
194
195   // Helper template functions
196   template<bool Do> void do_castle_move(Move m);
197   template<bool FindPinned> Bitboard hidden_checkers() const;
198
199   // Computing hash keys from scratch (for initialization and debugging)
200   Key compute_key() const;
201   Key compute_pawn_key() const;
202   Key compute_material_key() const;
203
204   // Computing incremental evaluation scores and material counts
205   Score compute_psq_score() const;
206   Value compute_non_pawn_material(Color c) const;
207
208   // Board and pieces
209   Piece board[SQUARE_NB];
210   Bitboard byTypeBB[PIECE_TYPE_NB];
211   Bitboard byColorBB[COLOR_NB];
212   int pieceCount[COLOR_NB][PIECE_TYPE_NB];
213   Square pieceList[COLOR_NB][PIECE_TYPE_NB][16];
214   int index[SQUARE_NB];
215
216   // Other info
217   int castleRightsMask[SQUARE_NB];
218   Square castleRookSquare[COLOR_NB][CASTLING_SIDE_NB];
219   Bitboard castlePath[COLOR_NB][CASTLING_SIDE_NB];
220   StateInfo startState;
221   int64_t nodes;
222   int startPosPly;
223   Color sideToMove;
224   Thread* thisThread;
225   StateInfo* st;
226   int chess960;
227 };
228
229 inline int64_t Position::nodes_searched() const {
230   return nodes;
231 }
232
233 inline void Position::set_nodes_searched(int64_t n) {
234   nodes = n;
235 }
236
237 inline Piece Position::piece_on(Square s) const {
238   return board[s];
239 }
240
241 inline Piece Position::piece_moved(Move m) const {
242   return board[from_sq(m)];
243 }
244
245 inline bool Position::is_empty(Square s) const {
246   return board[s] == NO_PIECE;
247 }
248
249 inline Color Position::side_to_move() const {
250   return sideToMove;
251 }
252
253 inline Bitboard Position::pieces() const {
254   return byTypeBB[ALL_PIECES];
255 }
256
257 inline Bitboard Position::pieces(PieceType pt) const {
258   return byTypeBB[pt];
259 }
260
261 inline Bitboard Position::pieces(PieceType pt1, PieceType pt2) const {
262   return byTypeBB[pt1] | byTypeBB[pt2];
263 }
264
265 inline Bitboard Position::pieces(Color c) const {
266   return byColorBB[c];
267 }
268
269 inline Bitboard Position::pieces(Color c, PieceType pt) const {
270   return byColorBB[c] & byTypeBB[pt];
271 }
272
273 inline Bitboard Position::pieces(Color c, PieceType pt1, PieceType pt2) const {
274   return byColorBB[c] & (byTypeBB[pt1] | byTypeBB[pt2]);
275 }
276
277 inline int Position::piece_count(Color c, PieceType pt) const {
278   return pieceCount[c][pt];
279 }
280
281 inline const Square* Position::piece_list(Color c, PieceType pt) const {
282   return pieceList[c][pt];
283 }
284
285 inline Square Position::ep_square() const {
286   return st->epSquare;
287 }
288
289 inline Square Position::king_square(Color c) const {
290   return pieceList[c][KING][0];
291 }
292
293 inline int Position::can_castle(CastleRight f) const {
294   return st->castleRights & f;
295 }
296
297 inline int Position::can_castle(Color c) const {
298   return st->castleRights & ((WHITE_OO | WHITE_OOO) << (2 * c));
299 }
300
301 inline bool Position::castle_impeded(Color c, CastlingSide s) const {
302   return byTypeBB[ALL_PIECES] & castlePath[c][s];
303 }
304
305 inline Square Position::castle_rook_square(Color c, CastlingSide s) const {
306   return castleRookSquare[c][s];
307 }
308
309 template<PieceType Pt>
310 inline Bitboard Position::attacks_from(Square s) const {
311
312   return  Pt == BISHOP || Pt == ROOK ? attacks_bb<Pt>(s, pieces())
313         : Pt == QUEEN  ? attacks_from<ROOK>(s) | attacks_from<BISHOP>(s)
314         : StepAttacksBB[Pt][s];
315 }
316
317 template<>
318 inline Bitboard Position::attacks_from<PAWN>(Square s, Color c) const {
319   return StepAttacksBB[make_piece(c, PAWN)][s];
320 }
321
322 inline Bitboard Position::attacks_from(Piece p, Square s) const {
323   return attacks_from(p, s, byTypeBB[ALL_PIECES]);
324 }
325
326 inline Bitboard Position::attackers_to(Square s) const {
327   return attackers_to(s, byTypeBB[ALL_PIECES]);
328 }
329
330 inline Bitboard Position::checkers() const {
331   return st->checkersBB;
332 }
333
334 inline bool Position::in_check() const {
335   return st->checkersBB != 0;
336 }
337
338 inline Bitboard Position::discovered_check_candidates() const {
339   return hidden_checkers<false>();
340 }
341
342 inline Bitboard Position::pinned_pieces() const {
343   return hidden_checkers<true>();
344 }
345
346 inline bool Position::pawn_is_passed(Color c, Square s) const {
347   return !(pieces(~c, PAWN) & passed_pawn_mask(c, s));
348 }
349
350 inline Key Position::key() const {
351   return st->key;
352 }
353
354 inline Key Position::exclusion_key() const {
355   return st->key ^ Zobrist::exclusion;
356 }
357
358 inline Key Position::pawn_key() const {
359   return st->pawnKey;
360 }
361
362 inline Key Position::material_key() const {
363   return st->materialKey;
364 }
365
366 inline Score Position::psq_delta(Piece p, Square from, Square to) const {
367   return pieceSquareTable[p][to] - pieceSquareTable[p][from];
368 }
369
370 inline Score Position::psq_score() const {
371   return st->psqScore;
372 }
373
374 inline Value Position::non_pawn_material(Color c) const {
375   return st->npMaterial[c];
376 }
377
378 inline bool Position::is_passed_pawn_push(Move m) const {
379
380   return   type_of(piece_moved(m)) == PAWN
381         && pawn_is_passed(sideToMove, to_sq(m));
382 }
383
384 inline int Position::startpos_ply_counter() const {
385   return startPosPly + st->pliesFromNull; // HACK
386 }
387
388 inline bool Position::opposite_bishops() const {
389
390   return   pieceCount[WHITE][BISHOP] == 1
391         && pieceCount[BLACK][BISHOP] == 1
392         && opposite_colors(pieceList[WHITE][BISHOP][0], pieceList[BLACK][BISHOP][0]);
393 }
394
395 inline bool Position::bishop_pair(Color c) const {
396
397   return   pieceCount[c][BISHOP] >= 2
398         && opposite_colors(pieceList[c][BISHOP][0], pieceList[c][BISHOP][1]);
399 }
400
401 inline bool Position::pawn_on_7th(Color c) const {
402   return pieces(c, PAWN) & rank_bb(relative_rank(c, RANK_7));
403 }
404
405 inline bool Position::is_chess960() const {
406   return chess960;
407 }
408
409 inline bool Position::is_capture_or_promotion(Move m) const {
410
411   assert(is_ok(m));
412   return type_of(m) ? type_of(m) != CASTLE : !is_empty(to_sq(m));
413 }
414
415 inline bool Position::is_capture(Move m) const {
416
417   // Note that castle is coded as "king captures the rook"
418   assert(is_ok(m));
419   return (!is_empty(to_sq(m)) && type_of(m) != CASTLE) || type_of(m) == ENPASSANT;
420 }
421
422 inline PieceType Position::captured_piece_type() const {
423   return st->capturedType;
424 }
425
426 inline Thread* Position::this_thread() const {
427   return thisThread;
428 }
429
430 #endif // !defined(POSITION_H_INCLUDED)