00001 // cwchessboard -- A C++ chessboard tool set 00002 // 00003 //! @file MoveIterator.h This file contains the declaration of class MoveIterator. 00004 // 00005 // Copyright (C) 2008 - 2010, 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 MOVEITERATOR_H 00025 #define MOVEITERATOR_H 00026 00027 #ifndef USE_PCH 00028 #include <iterator> 00029 #endif 00030 00031 #include "Move.h" 00032 #include "BitBoard.h" 00033 #include "Piece.h" 00034 #ifdef GTKMM 00035 #include <glib/gmacros.h> 00036 #endif 00037 00038 #ifndef G_LIKELY 00039 #define G_LIKELY(condition) __builtin_expect(condition, true) 00040 #endif 00041 00042 namespace cwchess { 00043 00044 class ChessPosition; 00045 00046 /** @brief Non-mutable iterator over all moves of a given chess piece. 00047 * 00048 * This iterator generates the Move objects while advancing to the next 00049 * move, storing the result in a member variable. The lifetime of the reference 00050 * or pointer to the Move is therefore equal to the lifetime of the iterator: 00051 * calling the increment or decrement operators overwrites the previous move. 00052 * 00053 * Usage example: 00054 * 00055 * \code 00056 * for (MoveIterator move_iter = chess_position.move_begin(index); move_iter != chess_position.move_end(); ++move_iter) 00057 * { 00058 * Move const& move(*move_iter); 00059 * // Use 'move'. 00060 * } 00061 * \endcode 00062 * / 00063 class MoveIterator : public std::iterator<std::bidirectional_iterator_tag, Move> { 00064 protected: 00065 ChessPosition const* M_chess_position; //!< The underlaying chess position. 00066 BitBoard M_targets; //!< The targets that this piece can move to. 00067 Move M_current_move; //!< The actual move that is returned when dereferenced. 00068 00069 public: 00070 /** @name Constructors* / 00071 //@{ 00072 00073 // Default Constructible. 00074 /** @brief Construct a one-past-the-end MoveIterator. 00075 * 00076 * @sa ChessPosition::move_end() 00077 * / 00078 MoveIterator(void) : M_current_move(index_end, index_end, nothing) { } 00079 00080 // Assignable. 00081 //! @brief Copy-Constructor. 00082 MoveIterator(MoveIterator const& iter) : 00083 M_chess_position(iter.M_chess_position), M_targets(iter.M_targets), M_current_move(iter.M_current_move) { } 00084 00085 /** @brief Construct a fully initialized MoveIterator. 00086 * 00087 * @param chess_position : The ChessPosition that we're generating moves for. 00088 * @param index : The index of the piece that we're generating moves for. 00089 * 00090 * @sa ChessPosition::move_begin(Index const&) 00091 * / 00092 MoveIterator(ChessPosition const* chess_position, Index const& index); 00093 00094 //@} 00095 00096 /** @name Assignment operator* / 00097 //@{ 00098 00099 //! @brief Assignment operator. 00100 MoveIterator& operator=(MoveIterator const& iter) 00101 { M_chess_position = iter.M_chess_position; M_targets = iter.M_targets; M_current_move = iter.M_current_move; return* this; } 00102 00103 //@} 00104 00105 /** @name Comparision operators* / 00106 //@{ 00107 00108 // Equality Comparable. 00109 bool operator==(MoveIterator const& iter) const { return M_current_move == iter.M_current_move; } 00110 bool operator!=(MoveIterator const& iter) const { return M_current_move != iter.M_current_move; } 00111 00112 //@} 00113 00114 /** @name Accessors* / 00115 //@{ 00116 00117 // Dereferencable. 00118 Move const& operator*() const { return M_current_move; } 00119 Move const* operator->(void) const { return& M_current_move; } 00120 00121 //@} 00122 00123 /** @name Increment and decrement operators* / 00124 //@{ 00125 00126 // Bi-directional iterator. 00127 MoveIterator& operator++() 00128 { 00129 if (G_LIKELY(!M_current_move.is_promotion()) || next_promotion()) 00130 { 00131 Index current_index(M_current_move.to()); 00132 current_index.next_bit_in(M_targets()); 00133 M_current_move.set_to(current_index); 00134 } 00135 return* this; 00136 } 00137 00138 MoveIterator operator++(int) { MoveIterator result(*this); operator++(); return result; } 00139 00140 MoveIterator& operator--() 00141 { 00142 if (G_LIKELY(!M_current_move.is_promotion()) || prev_promotion()) 00143 { 00144 Index current_index(M_current_move.to()); 00145 current_index.prev_bit_in(M_targets()); 00146 M_current_move.set_to(current_index); 00147 } 00148 return* this; 00149 } 00150 00151 MoveIterator operator--(int) { MoveIterator result(*this); operator--(); return result; } 00152 00153 //@} 00154 00155 public_notdocumented: 00156 // Indexing. 00157 uint32_t index(void) const { return M_current_move.to()(); } 00158 00159 private: 00160 bool next_promotion(void); 00161 bool prev_promotion(void); 00162 00163 Index get_first_bitindex(void) const { Index result(index_pre_begin); result.next_bit_in(M_targets()); return result; } 00164 00165 Type initial_type(Index const& index) const; 00166 }; 00167 00168 } // namespace cwchess 00169 00170 #endif // MOVEITERATOR_H