ChessPosition.h
Go to the documentation of this file.
1 // cwchessboard -- A C++ chessboard tool set
2 //
3 //! @file ChessPosition.h This file contains the declaration of class ChessPosition.
4 //
5 // Copyright (C) 2008, by
6 //
7 // Carlo Wood, Run on IRC <carlo@alinoe.com>
8 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
9 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 
24 #ifndef CHESSPOSITION_H
25 #define CHESSPOSITION_H
26 
27 #ifndef USE_PCH
28 #endif
29 
30 #include "BitBoard.h"
31 #include "Piece.h"
32 #include "PieceIterator.h"
33 #include "MoveIterator.h"
34 #include "Array.h"
35 #include "CastleFlags.h"
36 #include "EnPassant.h"
37 #include "CountBoard.h"
38 
39 namespace cwchess {
40 
41 /** @brief A chess position.
42 *
43  * This class represents a chess position.
44  * It has all information regarding a single position,
45  * including the full move count (because that is needed
46  * for the FEN code), the half move clock (to determine
47  * whether a derived position becomes a draw due to the
48  * 50 moves rule), en passant and castling information.
49 * /
51  private:
52  ArrayCode<BitBoard> M_bitboards; //!< Bitboards reflecting the current position.
53  ArrayIndex<Piece> M_pieces; //!< A piece per square. The index of the array is an Index.
54  ArrayColor<BitBoard> M_attackers; //!< Bitboards for squares of enemy pieces on the same line as the king and all squares in between.
55  ArrayColor<BitBoard> M_pinning; //!< Squares between attacker and king for actually pinned pieces (including attacker).
56  ArrayColor<CountBoard> M_defended; //!< The number times a square is defended.
57  ArrayColor<uint8_t> M_king_battery_attack_count; //!< The number of times that a king is 'attacked' by pieces behind another attacker.
58  uint16_t M_full_move_number; //!< The number of the full move. It starts at 1, and is incremented after Black's move.
59  uint8_t M_half_move_clock; //!< Number of half moves since the last pawn advance or capture.
60  CastleFlags M_castle_flags; //!< Whether black and white may castle long or short.
61  Color M_to_move; //!< The active color.
62  EnPassant M_en_passant; //!< A pawn that can be taken en passant, or zeroed if none such pawn exists.
63  bool M_double_check; //!< Cached value of wether or not M_to_move is in double check.
64 
65  public:
66 
67  /** @name Constructor* /
68  //@{
69 
70  //! @brief Construct an uninitialized position.
71  //
72  // Because ChessPosition::clear doesn't set M_to_move, the only
73  // member variable initialized here is M_to_move because it needs
74  // to be set to something before we can call ChessPosition::place,
75  // or uninitialized memory would be used.
76  ChessPosition(void) : M_to_move(white) { }
77 
78  //@}
79 
80  /** @name Position setup* /
81  //@{
82 
83  /** @brief Clear the board.
84  *
85  * This does not change whose move it is.
86  * The half move clock and full move number are reset (to zero and one respectively).
87  * /
88  void clear(void);
89 
90  /** @brief Set up the initial position.* /
91  void initial_position(void);
92 
93  /** @brief Skip a move.
94  *
95  * This resets the right to capture en passant.
96  * Skipping a move is counted as move.
97  *
98  * @returns TRUE if the result is a draw due to the 50 moves rule.
99  * /
100  bool skip_move(void);
101 
102  /** @brief Explicitly set whose turn it is.
103  *
104  * This does not change the half move clock or full move number, nor does it change the en passant information.
105  * The reason for that is that this call is probably done as part of a position setup and calls that explicitely
106  * set en passant information and the move counters might already have been called. However, calling this
107  * an odd number of times after en passant information was set therefore leaves the position is an erroneous state.
108  *
109  * If you just want to change who is to move from a given position, then use %skip_move.
110  *
111  * @param color : The color that has to move next from this position.
112  * /
113  void to_move(Color const& color);
114 
115  /** @brief Explicitly set the number of half moves since the last pawn move or capture.
116  *
117  * This does not change the full move number, en passant information or whose turn it is.
118  * /
119  void set_half_move_clock(int count) { M_half_move_clock = count; }
120 
121  /** @brief Explicitly set the move number.
122  *
123  * This does not change the half move clock, en passant information or whose turn it is.
124  * /
125  void set_full_move_number(int move) { M_full_move_number = move; }
126 
127  /** @brief Explicity set the en passant information.
128  *
129  * This also sets whose turn it is. No error checking is done on whether there is
130  * actually a pawn that could have just moved two squares.
131  *
132  * @param index : The square that a pawn just passed by advancing two square.
133  *
134  * @returns TRUE if there are indeed one or two pawns that can take en passant.
135  * /
136  bool set_en_passant(Index const& index);
137 
138  /** @brief Swap colors.
139  *
140  * This changes the color of each piece,
141  * toggles whose turn it is and mirrors the position vertically.
142  * The resulting position is technically identical to the original position,
143  * but with different colors for each piece.
144  *
145  * In order to make the position technically equivalent, the half
146  * move clock is unchanged; however, the full move number is reset
147  * (to one) because it would impossible to really have the same
148  * history: it is not possible that black started the game.
149  * /
150  void swap_colors(void);
151 
152  /** @brief Place a piece on the board.
153  *
154  * Place a \a piece on the board.
155  * If there is already a piece there, it is replaced.
156  * It is also possible to place 'nothing', in which case any piece that was there is removed.
157  *
158  * If the king or a rook is placed, then the castling flags are updated to
159  * allow castling by default. If this is not what you want, then call %moved
160  * to signal that castling is not allowed <em>after</em> placing both, the king
161  * and the rook(s).
162  *
163  * If a pawn is marked as En Passant then that is persistent: it will stay
164  * that way (placing a piece is not the same as making a move). However, if
165  * the pawn that can be taken en passant is moved, replaced (by again a pawn)
166  * or when a piece is put behind it, so that it's impossible that it was
167  * the last move (no logic will check other reasons, like being in check),
168  * then its En Passant status is reset. For example, if there is a white
169  * pawn on f4 that can be taken en passant by a black pawn on g4, and the
170  * pawn on g4 is removed or replaced then that doesn't change the status
171  * of the pawn on f4. If (later) a black pawn in placed on g4, then that
172  * pawn will be able to take the white pawn on f4, provided that nothing
173  * has been placed, even temporarily, on f3 or f2, and the pawn on f4 was
174  * never replaced.
175  *
176  * At the moment the only placement that is refused is placing pawns on rank 1 or 8.
177  *
178  * @param code : The piece to be placed on the board.
179  * @param index : Where to place the piece.
180  *
181  * @returns TRUE if the piece was placed, FALSE if it was refused.
182  * /
183  bool place(Code const& code, Index const& index);
184 
185  /** @brief Specifically specify that a king or rook has already moved.
186  *
187  * Calling this function is only necessary if king and rook are both
188  * on the initial squares. Placing the rook or king after calling
189  * this function will reset the castling flags (to allow castling);
190  * therefore first place the pieces and then, if necessary, call
191  * this function.
192  *
193  * @param index : The (initial position of the) rook or king.
194  * /
195  void set_has_moved(Index const& index) { M_castle_flags.piece_moved_from(piece_at(index), index); }
196 
197  /** @brief Specifically specify that a king or rook didn't move yet.
198  *
199  * This function only has effect if the king or rook is on its initial square.
200  *
201  * @param index : The (initial position of the) rook or king.
202  * /
203  void clear_has_moved(Index const& index) { M_castle_flags.update_placed(piece_at(index).code(), index); }
204 
205  /** @brief Read a FEN code.
206  *
207  * @param FEN : A Forsyth-Edwards Notation.
208  *
209  * If the FEN code is non-parsable, the function return FALSE and
210  * the position is in an undefined state. Therefore you might
211  * want to use the function as follows:
212  *
213  * <pre>
214  * ChessPosition tmp(current_chess_position);
215  * if (tmp.load_FEN(fen))
216  * current_chess_position = tmp;
217  * else
218  * {
219  * // report error
220  * }
221  * </pre>
222  *
223  * @returns TRUE if loading was successful.
224  * /
225  bool load_FEN(std::string const& FEN);
226 
227  //@}
228 
229 #ifndef DOXYGEN
230  // Needs access to M_pieces.
231  friend class PieceIterator;
232 #endif
233 
234  /** @name Accessors* /
235  //@{
236 
237  /** @brief Return the Piece on the square \a index.* /
238  Piece piece_at(Index const& index) const { return M_pieces[index]; }
239 
240  /** @brief Return the Piece on the square \a col, \a row.* /
241  Piece piece_at(int col, int row) const { return M_pieces[Index(col, row)]; }
242 
243  /** @brief Return whose turn it is.* /
244  Color to_move(void) const { return M_to_move; }
245 
246  /** @brief Return the half move clock.* /
247  unsigned int half_move_clock(void) const { return M_half_move_clock; }
248 
249  /** @brief Return the full move number.* /
250  unsigned int full_move_number(void) const { return M_full_move_number; }
251 
252  /** @brief Return the castle flag object.* /
253  CastleFlags const& castle_flags(void) const { return M_castle_flags; }
254 
255  /** @brief Return the en passant object.* /
256  EnPassant const& en_passant(void) const { return M_en_passant; }
257 
258  /** @brief Return a BitBoard with bits set for all \a code, where \a code may not be 'nothing'.* /
259  BitBoard const& all(Code const& code) const { return M_bitboards[code]; }
260 
261  /** @brief Return a BitBoard with bits set for all pieces of color \a color.* /
262  BitBoard const& all(Color const& color) const { return M_bitboards[color]; }
263 
264  //@}
265 
266 public_notdocumented:
267  // Added for debugging purposes.
268  ArrayColor<CountBoard> const& get_defended(void) const { return M_defended; }
269  BitBoard attackers(Color const& color) const { return M_attackers[color]; }
270  BitBoard pinned(Color const& color) const { return M_pinning[color]; }
271 
272 public:
273  /** @name Visitors* /
274  //@{
275 
276  /** @brief Return the FEN code for this position.* /
277  std::string FEN(void) const;
278 
279  /** @brief Return the offset into the candidates_table for type \a type.
280  *
281  * The type may not be a pawn (there is no candidates_table entry for a pawn).
282  * /
283  int candidates_table_offset(Type const& type) const
284  {
285  int n = type();
286  n -= (n > 4) ? 3 : 2;
287  n <<= 6;
288  return n;
289  }
290 
291  /** @brief Return a BitBoard with bits set for all squares that are candidates to move to.
292  *
293  * In the case of the pawn, the returned BitBoard is exact.
294  * In the case of the king, the castling squares are not included.
295  * In all other cases the returned squares assume an empty board.
296  *
297  * This function may not be called for an empty square.
298  * /
299  BitBoard candidates(Index const& index) const
300  {
301  Piece const& piece(M_pieces[index]);
302  if (piece == black_pawn)
303  {
304  BitBoardData data;
305  mask_t flags = piece.flags()();
306  data.M_bitmask = (flags << 50) | (flags << 40);
307  data.M_bitmask& = CW_MASK_T_CONST(0xe0400000000000);
308  data.M_bitmask >>= 62 - index();
309  return BitBoard(data);
310  }
311  else if (piece == white_pawn)
312  {
313  BitBoardData data;
314  mask_t flags = piece.flags()();
315  data.M_bitmask = flags | (flags << 6);
316  data.M_bitmask& = 0x1038;
317  data.M_bitmask <<= index() + 4;
318  return BitBoard(data);
319  }
320  return BitBoard(candidates_table[candidates_table_offset(piece.type()) + index()]);
321  }
322 
323  /** @brief Return a BitBoard with bits set for each square that a piece can reach in one move.
324  *
325  * The parameter \a attacked_squares only influences pawns and the king.
326  * If set, the squares returned for a pawn are always the two attacked
327  * squares (independent of other pieces); and the king does not return
328  * any castling squares. The definition would be: squares that the
329  * opponent may not move to with his king.
330  *
331  * @param index : The position of the piece under investigation.
332  * @param attacked_squares : If true, rather return if squares are attacked than whether the piece can move there.
333  * /
334  BitBoard reachables(Index const& index, bool attacked_squares = false) const;
335 
336  /** @brief Return a BitBoard with bits set for each square that a piece defends, or would defend if an exchange was going on there.
337  *
338  * This function returns the squares that the enemy king is not allowed to go to
339  * as a result of this piece. However, the attacks are considered to go through
340  * slider pieces of the same type. For example, if you ask about the defendables
341  * of a white rook on e1, and there is already a white rook (or queen) on e2,
342  * then the square e3 (and beyond) is returned nevertheless.
343  *
344  * It is not necessary for the piece to actually stand on the board yet.
345  *
346  * @param code : The piece.
347  * @param index : The place that the piece is considered to be standing on.
348  * @param battery : Internal output variable (ignore it).
349  * /
350  BitBoard defendables(Code const& code, Index const& index, bool& battery) const;
351 
352  /** @brief Return the index of the king with color \a color.* /
353  Index index_of_king(Color const& color) const { CodeData data = { static_cast<uint8_t>(king_bits | color()) }; return mask2index(M_bitboards[data]()); }
354 
355  /** @brief Return true if the king is in check.* /
356  bool check(void) const { return M_bitboards[Code(M_to_move, king)].test(M_defended[M_to_move.opposite()].any()); }
357 
358  /** @brief Return true if the king of color \a color is in check.* /
359  bool check(Color const& color) const { return M_bitboards[Code(color, king)].test(M_defended[color.opposite()].any()); }
360 
361  /** @brief Return true if the king of color \a color is in double check.* /
362  bool double_check(Color const& color) const
363  { Color opposite_color(color.opposite());
364  CodeData data = { static_cast<uint8_t>(king_bits | color()) };
365  return M_defended[opposite_color].count(M_bitboards[data]) - M_king_battery_attack_count[opposite_color] > 1; }
366 
367  /** @brief Return true if the king or rook on \a index has moved or not.
368  *
369  * Calling this function for another piece than a king or rook returns false.
370  * /
371  bool has_moved(Index const& index) { return M_castle_flags.has_moved(M_pieces[index].code(), index); }
372 
373  /** @brief Return a BitBoard with bits set for each square the piece at index can legally go to.
374  *
375  * @param index : The square that the piece stands on that is to be considered.
376  * /
377  BitBoard moves(Index const& index) const;
378 
379  /** @brief Return true if the move is a legal move.* /
380  bool legal(Move const& move) const;
381 
382  //@}
383 
384  /** @name Iterators* /
385  //@{
386 
387  /** @brief Return an iterator to the first piece of color \a color.
388  *
389  * The iterator will iterate over all pieces with color \a color.
390  * /
391  PieceIterator piece_begin(Color const& color) const { return PieceIterator(this, M_bitboards[color]); }
392 
393  /** @brief Return an iterator one beyond the last piece.* /
394  PieceIterator piece_end(void) const { return PieceIterator(); }
395 
396  /** @brief Return an iterator to the first piece with code \a code.
397  *
398  * The iterator will iterate over all pieces with code \a code; \a code may not be empty.
399  * /
400  PieceIterator piece_begin(Code const& code) const { return PieceIterator(this, M_bitboards[code]); }
401 
402  /** @brief Return an iterator to the first move of the piece at index \a index.* /
403  MoveIterator move_begin(Index const& index) const { return MoveIterator(this, index); }
404 
405  /** @brief Return an iterator one beyond the last move.* /
406  MoveIterator move_end(void) const { return MoveIterator(); }
407 
408  //@}
409 
410  /** @name Game play* /
411  //@{
412 
413  /** @brief Execute move \a move.* /
414  bool execute(Move const& move);
415 
416  //@}
417 
418  protected:
419  void reset_en_passant(void) { if (M_en_passant.exists()) clear_en_passant(); }
420 
421  private:
422  // Reset the right to take en passant.
423  void clear_en_passant(void);
424 
425  // Increment M_half_move_clock (or reset if \a pawn_advance_or_capture is true) and M_full_move_number if appropriate.
426  bool increment_counters(bool pawn_advance_or_capture);
427 
428  // Update the fl_pawn_can_take_* pawn flags for a piece of color \a color that was removed from (col, row).
429  void update_removed(uint8_t col, uint8_t row, Color const& color);
430 
431  // Update the fl_pawn_can_take_* pawn flags for a piece of color \a color that was placed at (col, row).
432  void update_placed(uint8_t col, uint8_t row, Color const& color);
433 
434  // Update pinning flags.
435  void update_pinning(Code const& code, Index const& index, mask_t mask, Direction const& direction, BitBoard const& line);
436 
437  // Calculate a bitboard with all pieces minus all bishop movers and first hit pawn, plus blocking bits after those first pawns.
438  BitBoard all_pieces_minus_bishop_movers(Color const& color, Index const& index) const;
439 
440  // Calculate the squares that would be blocked by a piece with code \a code at \a index and than add or subtract them from M_defended.
441  // Also update M_king_battery_attack_count.
442  void update_blocked_defendables(Code const& code, Index const& index, bool add);
443 
444  private:
445  static BitBoardData candidates_table[5 * 64];
446 };
447 
448 } // namespace cwchess
449 
450 #ifndef DOXYGEN // Hide this from doxygen in order to make some graph less wide.
451 #include "PieceIterator.inl"
452 #include "MoveIterator.inl"
453 #endif
454 
455 #endif // CHESSPOSITION_H
bool double_check(Color const& color) const
Return true if the king of color color is in double check.
CodeData const black_pawn
A constant representing a black pawn.
Definition: Code.h:66
The POD base type of class Code.
Definition: Code.h:49
A namespace for all chess related objects that are not related to the GUI.
Definition: Array.h:39
mask_t M_bitmask
A one-bit-per-square chessboard mask.
Definition: BitBoard.h:93
bool load_FEN(std::string const& FEN)
Read a FEN code.
MoveIterator move_end(void) const
Return an iterator one beyond the last move.
void clear_has_moved(Index const& index)
Specifically specify that a king or rook didn&#39;t move yet.
void set_has_moved(Index const& index)
Specifically specify that a king or rook has already moved.
Color opposite(void) const
Return a Color object with the opposite color of this object.
Definition: Color.h:133
bool execute(Move const& move)
Execute move move.
Index mask2index(mask_t mask)
Convert a single bit mask into it&#39;s Index.
Definition: BitBoard.h:69
Piece piece_at(int col, int row) const
Return the Piece on the square col, row.
BitBoard const & all(Code const& code) const
Return a BitBoard with bits set for all code, where code may not be& #39;nothing&#39;.
ColorData const white
A constant representing the color white.
Definition: Color.h:55
A chess move in a particular chess position.
Definition: Move.h:44
This file contains the declaration of class CastleFlags.
MoveIterator move_begin(Index const& index) const
Return an iterator to the first move of the piece at index index.
BitBoard candidates(Index const& index) const
Return a BitBoard with bits set for all squares that are candidates to move to.
TypeData const king
A constant representing a king.
Definition: Type.h:69
bool has_moved(Code const& code, Index const& index)
Return TRUE if code at index is marked as having moved.
Definition: CastleFlags.cc:60
unsigned int half_move_clock(void) const
Return the half move clock.
The POD base type of class BitBoard.
Definition: BitBoard.h:87
int candidates_table_offset(Type const& type) const
Return the offset into the candidates_table for type type.
Non-mutable iterator over all moves of a given chess piece.
Definition: MoveIterator.h:58
Index index_of_king(Color const& color) const
Return the index of the king with color color.
bool set_en_passant(Index const& index)
Explicity set the en passant information.
bool check(void) const
Return true if the king is in check.
Type type(void) const
The type of this piece.
Definition: Piece.h:115
void clear(void)
Clear the board.
unsigned int full_move_number(void) const
Return the full move number.
A chess piece type.
Definition: Type.h:87
An object representing en passant information.
Definition: EnPassant.h:49
This file contains the definition of class Array.
A one-boolean-per-square chessboard.
Definition: BitBoard.h:266
The index of a chess square.
Definition: Index.h:211
CastleFlags const & castle_flags(void) const
Return the castle flag object.
bool legal(Move const& move) const
Return true if the move is a legal move.
PieceIterator piece_end(void) const
Return an iterator one beyond the last piece.
bool has_moved(Index const& index)
Return true if the king or rook on index has moved or not.
bool check(Color const& color) const
Return true if the king of color color is in check.
A class to keep track of castling rights.
Definition: CastleFlags.h:63
A particular piece on the board.
Definition: Piece.h:45
This file contains the declaration of class EnPassant.
This file contains the inline definitions of class MoveIterator.
uint64_t mask_t
The type of an internal BitBoard mask.
Definition: BitBoard.h:48
ChessPosition(void)
Construct an uninitialized position.
Definition: ChessPosition.h:76
This file contains the inline definitions of class PieceIterator.
Piece piece_at(Index const& index) const
Return the Piece on the square index.
void set_half_move_clock(int count)
Explicitly set the number of half moves since the last pawn move or capture.
uint8_t const king_bits
The underlaying integral value of type& #39;king&#39;.
Definition: Type.h:56
bool skip_move(void)
Skip a move.
EnPassant const & en_passant(void) const
Return the en passant object.
PieceIterator piece_begin(Color const& color) const
Return an iterator to the first piece of color color.
PieceIterator piece_begin(Code const& code) const
Return an iterator to the first piece with code code.
This file contains the declaration of class BitBoard.
This file contains the definition of class PieceIterator.
A chess position.
Definition: ChessPosition.h:50
BitBoard reachables(Index const& index, bool attacked_squares=false) const
Return a BitBoard with bits set for each square that a piece can reach in one move.
A chess piece type including color.
Definition: Code.h:92
std::string FEN(void) const
Return the FEN code for this position.
This file contains the declaration of class CountBoard.
void set_full_move_number(int move)
Explicitly set the move number.
Flags flags(void) const
The flags of this piece.
Definition: Piece.h:118
CodeData const white_pawn
A constant representing a white pawn.
Definition: Code.h:54
bool exists(void) const
Return TRUE if the last move was a pawn advancing two squares.
Definition: EnPassant.h:79
void swap_colors(void)
Swap colors.
A color (black or white).
Definition: Color.h:67
BitBoard defendables(Code const& code, Index const& index, bool& battery) const
Return a BitBoard with bits set for each square that a piece defends, or would defend if an exchange ...
BitBoard moves(Index const& index) const
Return a BitBoard with bits set for each square the piece at index can legally go to...
This file contains the declaration of class MoveIterator.
Non-mutable iterator over selective chess pieces in a chess position.
Definition: PieceIterator.h:42
void initial_position(void)
Set up the initial position.
Color to_move(void) const
Return whose turn it is.
bool place(Code const& code, Index const& index)
Place a piece on the board.
BitBoard const & all(Color const& color) const
Return a BitBoard with bits set for all pieces of color color.
This file contains the declaration of class Piece.

Copyright © 2006 - 2010 Carlo Wood.  All rights reserved.