00001 // cwchessboard -- A C++ chessboard tool set 00002 // 00003 //! @file PieceIterator.h This file contains the definition of class PieceIterator. 00004 // 00005 // Copyright (C) 2008, by 00006 // 00007 // Carlo Wood, Run on IRC <carlo@alinoe.com> 00008 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 00009 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 00010 // 00011 // This program is free software: you can redistribute it and/or modify 00012 // it under the terms of the GNU General Public License as published by 00013 // the Free Software Foundation, either version 2 of the License, or 00014 // (at your option) any later version. 00015 // 00016 // This program is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU General Public License 00022 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 00024 #ifndef PIECEITERATOR_H 00025 #define PIECEITERATOR_H 00026 00027 #ifndef USE_PCH 00028 #include <iterator> 00029 #endif 00030 00031 #include "Piece.h" 00032 00033 namespace cwchess { 00034 00035 class ChessPosition; 00036 00037 /** @brief Non-mutable iterator over selective chess pieces in a chess position. 00038 * 00039 * This iterator iterates over bits in a given BitBoard, passed during creation, 00040 * and returns the Piece at the given position when dereferenced. 00041 * / 00042 class PieceIterator : public std::iterator<std::bidirectional_iterator_tag, Piece> { 00043 protected: 00044 ChessPosition const* M_chess_position; //!< The underlaying chess position. 00045 BitBoard M_pieces; //!< The pieces that the iterator will iterate over. 00046 Index M_current_index; //!< The index to the current piece, or 64 if this iterator points one passed the end. 00047 00048 public: 00049 /** @name Constructors* / 00050 //@{ 00051 00052 // Default Constructible. 00053 /** @brief Construct the corresponding one-passed-the-end iterator. 00054 * 00055 * @sa ChessPosition::piece_end(void) 00056 * / 00057 PieceIterator(void) : M_chess_position(NULL), M_current_index(index_end) { } 00058 00059 /** @brief Construct the corresponding one-before-the-beginning iterator. 00060 * / 00061 PieceIterator(int) : M_chess_position(NULL), M_current_index(index_pre_begin) { } 00062 00063 // Assignable. 00064 //! @brief Copy-constructor. 00065 PieceIterator(PieceIterator const& iter) : 00066 M_chess_position(iter.M_chess_position), M_pieces(iter.M_pieces), M_current_index(iter.M_current_index) { } 00067 00068 /** @brief Construct a fully initialized PieceIterator. 00069 * 00070 * @param chess_position : The ChessPosition that we will retrieve the Pieces from. It is only used when the iterator is dereferenced. 00071 * @param pieces : A BitBoard with bits set for each square that the iterator should visit. 00072 * 00073 * This iterator is initialized to point at the beginning (the least significant bit). 00074 * A typical loop would look as follows: 00075 * 00076 * \code 00077 * PieceIterator const piece_end; 00078 * for (PieceIterator piece_iter(chess_position, bitboard); piece_iter != piece_end; ++piece_iter) 00079 * { 00080 * // Use piece_iter.index(), the square that the piece is standing on, or 00081 * // access the Piece directly through piece_iter->. 00082 * } 00083 * \endcode 00084 * 00085 * which will run over all bits set in bitboard. 00086 * 00087 * @sa ChessPosition::piece_begin, ChessPosition::all 00088 * / 00089 PieceIterator(ChessPosition const* chess_position, BitBoard pieces) : 00090 M_chess_position(chess_position), M_pieces(pieces), M_current_index(get_first_bitindex()) { } 00091 00092 /** @brief Construct a fully initialized PieceIterator. 00093 * 00094 * @param chess_position : The ChessPosition that we will retrieve the Pieces from. 00095 * @param pieces : The pieces, a BitBoard with bits set for each square that the iterator should visit. 00096 * 00097 * This iterator is initialized to point at the end rather than the beginning. 00098 * A typical loop would look as follows: 00099 * 00100 * \code 00101 * PieceIterator const piece_end(0); 00102 * for (PieceIterator piece_iter(chess_position, bitboard, 0); piece_iter != piece_end; --piece_iter) 00103 * { 00104 * // Use piece_iter.index(), the square that the piece is standing on, or 00105 * // access the Piece directly through piece_iter->. 00106 * } 00107 * \endcode 00108 * / 00109 PieceIterator(ChessPosition const* chess_position, BitBoard pieces, int) : 00110 M_chess_position(chess_position), M_pieces(pieces), M_current_index(get_last_bitindex()) { } 00111 00112 //@} 00113 00114 /** @name Assignment operator* / 00115 //@{ 00116 00117 // Assignable. 00118 //! @brief Assign from another PieceIterator. 00119 PieceIterator& operator=(PieceIterator const& iter) 00120 { M_chess_position = iter.M_chess_position; M_pieces = iter.M_pieces; M_current_index = iter.M_current_index; return* this; } 00121 00122 //@} 00123 00124 /** @name Comparison operators* / 00125 //@{ 00126 00127 // Equality Comparable. 00128 //! Return TRUE if the current index of this PieceIterator and \a iter are equal. 00129 bool operator==(PieceIterator const& iter) const { return M_current_index == iter.M_current_index; } 00130 00131 //! Return TRUE if the current index of this PieceIterator and \a iter differ. 00132 bool operator!=(PieceIterator const& iter) const { return M_current_index != iter.M_current_index; } 00133 00134 //@} 00135 00136 /** @name Accessors* / 00137 //@{ 00138 00139 // Dereferencable. 00140 //! Return the Piece that stands on the current index. 00141 Piece operator*() const; 00142 00143 //! Return a pointer to the Piece standing on the current index. 00144 Piece const* operator->(void) const; 00145 00146 //! Return the current index. 00147 Index const& index(void) const { return M_current_index; } 00148 00149 //@} 00150 00151 /** @name Increment and decrement operators* / 00152 //@{ 00153 00154 // Bi-directional iterator. 00155 PieceIterator& operator++() { M_current_index.next_bit_in(M_pieces()); return* this; } 00156 PieceIterator operator++(int) { PieceIterator result(*this); operator++(); return result; } 00157 PieceIterator& operator--() { M_current_index.prev_bit_in(M_pieces()); return* this; } 00158 PieceIterator operator--(int) { PieceIterator result(*this); operator--(); return result; } 00159 00160 //@} 00161 00162 private: 00163 Index get_first_bitindex(void) const { Index result(index_pre_begin); result.next_bit_in(M_pieces()); return result; } 00164 Index get_last_bitindex(void) const { Index result(index_end); result.prev_bit_in(M_pieces()); return result; } 00165 }; 00166 00167 } // namespace cwchess 00168 00169 #endif // PIECEITERATOR_H