EnPassant.h
Go to the documentation of this file.
1 // cwchessboard -- A C++ chessboard tool set
2 //
3 //! @file EnPassant.h This file contains the declaration of class EnPassant.
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 ENPASSANT_H
25 #define ENPASSANT_H
26 
27 #ifndef USE_PCH
28 #endif
29 
30 #define DEBUG_ENPASSANT_EXISTS 0
31 
32 #if DEBUG_ENPASSANT_EXISTS
33 #include <cassert>
34 #endif
35 
36 namespace cwchess {
37 
38 /** @brief An object representing en passant information.
39 *
40  * This is an internal class, you should not normally need.
41 *
42  * If EnPassant::exists() returns true, then a pawn exists that can be taken en passant,
43  * or could be taken en passant if an enemy pawn was standing next to it.
44  * This means that in 'position setup mode', placing a pawn next to the en passant
45  * pawn (on index EnPassant::pawn_index()) will be able to take the en passant pawn.
46 *
47  * @sa ChessPosition::en_passant
48 * /
49 class EnPassant {
50  private:
51  //! @brief En passant information.
52  //
53  // PEIIIIII, where 'IIIIII' is the index of the square that a pawn just passed by moving two squares forward,
54  // and bit 'P' is a flag indicating that a pawn is not allowed to take en passant because it is pinned.
55  // If 'E' is set then all I must be 0 and the index is 'index_end'.
56  //
57  // If there exists no en passant pawn then 'P' must be 0.
58  uint8_t M_bits;
59 
60  public:
61 #ifndef DOXYGEN
62  //! @brief Construct an uninitialized EnPassant object.
63  EnPassant(void) { }
64 
65  //! @brief Construct EnPassant object with index \a index.
66  EnPassant(Index const& index) : M_bits(index()) { }
67 
68  //! @brief Assignment operator.
69  EnPassant& operator=(EnPassant const& en_passant) { M_bits = en_passant.M_bits; return* this; }
70 
71  //! @brief Clear the EnPassant object.
72  void clear(void) { M_bits = index_end.M_bits; }
73 
74  //! @brief Return the FEN field with en passant information.
75  std::string FEN4(void) const;
76 #endif
77 
78  //! @brief Return TRUE if the last move was a pawn advancing two squares.
79  bool exists(void) const { return M_bits != index_end.M_bits; }
80 
81  /** @name Accessors* /
82  //@{
83 
84  //! @brief Return the index of the square that was passed.
85  Index index(void) const
86  {
87 #if DEBUG_ENPASSANT_EXISTS
88  assert(exists());
89 #endif
90  IndexData result = { static_cast<uint8_t>(M_bits & 0x7f) };
91  return result;
92  }
93 
94  //! @brief Return the index of the pawn that just advanced two squares.
95  Index pawn_index(void) const
96  {
97 #if DEBUG_ENPASSANT_EXISTS
98  assert(exists());
99 #endif
100  IndexData result = { static_cast<uint8_t>((M_bits & 0x7f) ^ 8) };
101  return result;
102  }
103 
104  //! @brief Return the index of the square that pawn came from.
105  Index from_index(void) const
106  {
107 #if DEBUG_ENPASSANT_EXISTS
108  assert(exists());
109 #endif
110  IndexData result = { static_cast<uint8_t>((M_bits & 0x7f) ^ 24) };
111  return result;
112  }
113 
114  //! @brief Return TRUE if taking en passant is not allowed due to <em>horizontal</em> pinning.
115  bool pinned(void) const
116  {
117 #if DEBUG_ENPASSANT_EXISTS
118  assert(exists());
119 #endif
120  return (M_bits & 0x80);
121  }
122 
123  //@}
124 
125 #ifndef DOXYGEN
126  //! @brief Taking en passant is not allowed because it is pinned.
127  void pinned_set(void)
128  {
129 #if DEBUG_ENPASSANT_EXISTS
130  assert(exists());
131 #endif
132  M_bits |= 0x80;
133  }
134 
135  //! @brief Taking en passant is allowed again, because it is unpinned.
136  void pinned_reset(void) { M_bits& = 0x7f; }
137 #endif
138 
139 };
140 
141 } // namespace cwchess
142 
143 #endif // ENPASSANT_H
A namespace for all chess related objects that are not related to the GUI.
Definition: Array.h:39
Index from_index(void) const
Return the index of the square that pawn came from.
Definition: EnPassant.h:105
bool pinned(void) const
Return TRUE if taking en passant is not allowed due to horizontal pinning.
Definition: EnPassant.h:115
The POD base type of class Index.
Definition: Index.h:45
An object representing en passant information.
Definition: EnPassant.h:49
The index of a chess square.
Definition: Index.h:211
Index index(void) const
Return the index of the square that was passed.
Definition: EnPassant.h:85
Index pawn_index(void) const
Return the index of the pawn that just advanced two squares.
Definition: EnPassant.h:95
bool exists(void) const
Return TRUE if the last move was a pawn advancing two squares.
Definition: EnPassant.h:79
uint8_t M_bits
00RRRCCC, where RRR is the row and CCC the column.
Definition: Index.h:46
IndexData const index_end
A constant representing& #39;one past the end&#39;.
Definition: Index.h:186

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