00001 #ifndef _GENERATE_PIECE_MOVES_H
00002 #define _GENERATE_PIECE_MOVES_H
00003 #include "osl/move_generator/promoteType.h"
00004 #include "osl/move_action/concept.h"
00005 #include "osl/misc/loki.h"
00006 #include "osl/container/bitXmask.h"
00007 #include "osl/state/simpleState.h"
00008 #include <boost/static_assert.hpp>
00009
00010 namespace osl
00011 {
00012 namespace container
00013 {
00014 class MoveVector;
00015 }
00016 namespace move_generator
00017 {
00018 namespace bits
00019 {
00023 template <Player P,Ptype Type,PromoteType CanP,Direction Dir>
00024 struct PieceOnBoardLong
00025 {
00026 BOOST_STATIC_ASSERT(DirectionTraits<Dir>::isLong);
00027 template <class Action>
00028 static void generate(const SimpleState& state,
00029 Position pos, Action& action);
00030 };
00031
00035 template <Player P,Ptype T,PromoteType CanP,Direction Dir>
00036 struct PieceOnBoardShort
00037 {
00038 BOOST_STATIC_ASSERT(! DirectionTraits<Dir>::isLong);
00039 template <class Action>
00040 static void generate(const SimpleState& state,
00041 Position pos, Action& action)
00042 {
00043
00044 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00045 Position toPos=pos+offset;
00046 Piece p1=state.getPieceAt(toPos);
00047 if (p1.canMoveOn<P>())
00048 {
00049 if (CanP==CanPromoteType
00050 || (CanP==CheckPromoteType
00051 && DirectionTraits<Dir>::canPromoteTo
00052 && toPos.canPromote<P>()))
00053 {
00054 action.unknownMove(pos,toPos,p1,PtypeFuns<T>::promotePtype,true,P);
00055 if (PtypePlayerTraits<T,P>::canDropTo(toPos))
00056 action.unknownMove(pos,toPos,p1,T,false,P);
00057 }
00058 else
00059 {
00060 action.unknownMove(pos,toPos,p1,T,false,P);
00061 }
00062 }
00063 }
00064 };
00065
00070 template <Player P,Ptype T,PromoteType CanP,Direction Dir>
00071 struct PieceOnBoardDirUnsafe
00072 {
00073
00074 template <class Action>
00075 static void generate(const SimpleState& state,
00076 Position pos, Action& action,Int2Type<true>)
00077 {
00078 PieceOnBoardLong<P,T,CanP,Dir>::generate(state,pos,action);
00079 }
00080
00081 template <class Action>
00082 static void generate(const SimpleState& state,
00083 Position pos, Action& action,Int2Type<false>)
00084 {
00085 PieceOnBoardShort<P,T,CanP,Dir>::generate(state,pos,action);
00086 }
00087
00088 template <class Action>
00089 static void generate(const SimpleState& state,
00090 Position pos, Action& action)
00091 {
00092 generate(state,pos,action,
00093 Int2Type<DirectionTraits<Dir>::isLong>());
00094 }
00095 };
00096 }
00097
00098 template <Player P,Ptype T,Ptype MoveT,PromoteType CanP,Direction Dir>
00099 struct PieceOnBoardDir
00100 {
00101 private:
00102 template <class Action>
00103 static void generate(const SimpleState& state,
00104 Position pos, Action& action,Int2Type<true>)
00105 {
00106 bits::PieceOnBoardDirUnsafe<P,T,NoPromoteType,Dir>::
00107 generate(state,pos,action);
00108 }
00109
00110 template <class Action>
00111 static void generate(const SimpleState& state,Position pos, Action& action,Int2Type<false>)
00112 {
00113 bits::PieceOnBoardDirUnsafe<P,T,CanP,Dir>::
00114 generate(state,pos,action);
00115 }
00116
00117 template <class Action>
00118 static void generateIfValid(const SimpleState& state,
00119 Position pos, Action& action, Int2Type<true>)
00120 {
00121 generate(state,pos,action,
00122 Int2Type<(CanP == CheckPromoteType
00123 && !DirectionTraits<Dir>::canPromoteTo)>());
00124 }
00125 template <class Action>
00126 static void generateIfValid(const SimpleState&,
00127 Position, Action&, Int2Type<false>)
00128 {
00129 }
00130 public:
00131 template <class Action>
00132 static void generate(const SimpleState& state,
00133 Position pos, Action& action)
00134 {
00135 generateIfValid(state,pos,action,
00136 Int2Type<(PtypeTraits<MoveT>::moveMask
00137 & DirectionTraits<Dir>::mask) !=0>());
00138 }
00139 };
00140
00144 template <Player P,Ptype Type,Ptype MoveType,PromoteType CanP>
00145 struct PieceOnBoardTypePromotion
00146 {
00147 template <class Action>
00148 static void generate(const SimpleState& state,
00149 Position pos, Action& action);
00150 };
00151
00152
00156 template <Player P, Ptype T>
00157 struct PieceOnBoardType
00158 {
00159
00160 template <class Action>
00161 static void generate(const SimpleState& state,Piece p, Action& action,
00162 Int2Type<true>)
00163 {
00164 const Position pos=p.position();
00165 if (p.isPromotedNotKingGold())
00166 {
00167 PieceOnBoardTypePromotion<P,PtypeFuns<T>::promotePtype,PtypeTraits<PtypeFuns<T>::promotePtype>::moveType,NoPromoteType>::
00168 generate(state,pos,action);
00169 }
00170 else
00171 {
00172 if (pos.canPromote<P>())
00173 PieceOnBoardTypePromotion<P,T,T,CanPromoteType>::
00174 generate(state,pos,action);
00175 else
00176 PieceOnBoardTypePromotion<P,T,T,CheckPromoteType>::
00177 generate(state,pos,action);
00178 }
00179 }
00180 template <class Action>
00181 static void generate(const SimpleState& state,Piece p, Action& action,
00182 Int2Type<false>)
00183 {
00184 const Position pos=p.position();
00185 PieceOnBoardTypePromotion<P,T,T,NoPromoteType>
00186 ::generate(state,pos,action);
00187 }
00188
00189 template <class Action>
00190 static void generate(const SimpleState& state,Piece p, Action& action)
00191 {
00192 generate(state,p,action,Int2Type<PtypeTraits<T>::canPromote>());
00193 }
00194 };
00195
00199 template <Player P>
00200 struct PieceOnBoard
00201 {
00202
00203 template <class Action>
00204 static void generateMovesPawn(const SimpleState& state,Piece p, Action& action,BitXmask& pawnMask)
00205 {
00206 Position pos=p.position();
00207 if (p.isPromotedNotKingGold())
00208 {
00209 PieceOnBoardTypePromotion<P,PPAWN,GOLD,NoPromoteType>::
00210 generate(state,pos,action);
00211 }
00212 else
00213 {
00214 pawnMask.set(pos.x());
00215 if (pos.canPromote<P>())
00216 PieceOnBoardTypePromotion<P,PAWN,PAWN,CanPromoteType>::
00217 generate(state,pos,action);
00218 else
00219 PieceOnBoardTypePromotion<P,PAWN,PAWN,CheckPromoteType>::
00220 generate(state,pos,action);
00221 }
00222 }
00223
00227 template <class Action>
00228 static void generate(const SimpleState& state,Piece p, Action& action);
00229
00230 };
00231
00232 struct GeneratePieceOnBoard
00233 {
00234 static void generate(Player turn, const SimpleState& state, Piece target,
00235 container::MoveVector&);
00236 };
00237 }
00238 using move_generator::GeneratePieceOnBoard;
00239 }
00240
00241 #endif
00242
00243
00244
00245