00001 #ifndef OSL_PIECE_ON_BOARD_H
00002 #define OSL_PIECE_ON_BOARD_H
00003 #include "osl/move_action/concept.h"
00004 #include "osl/container/moveVector.h"
00005 #include "osl/state/numEffectState.h"
00006 #include <boost/static_assert.hpp>
00007
00008 namespace osl
00009 {
00010 namespace container
00011 {
00012 class MoveVector;
00013 }
00014 namespace move_generator
00015 {
00019 template<class Action,bool noCapturePromote=false>
00020 struct PieceOnBoard
00021 {
00025 template<Player P>
00026 static void generatePieceUnsafe(const NumEffectState& state,Piece p, Square target, Piece p1,Action& action)
00027 {
00028 assert(state.hasEffectByPiece(p, target));
00029 Ptype ptype=p.ptype();
00030 Square from=p.square();
00031 if(canPromote(ptype)){
00032 if(target.canPromote<P>()){
00033 action.unknownMove(from,target,p1,promote(ptype),true,P);
00034 int y=(P==BLACK ? target.y() : 10-target.y());
00035 if(!Ptype_Table.isBetterToPromote(ptype) &&
00036 (((ptype==LANCE || ptype==PAWN) ? y==3 : true )) &&
00037 Ptype_Table.canDropTo(P,ptype,target))
00038 action.unknownMove(from,target,p1,ptype,false,P);
00039 }
00040 else if(from.canPromote<P>()){
00041 action.unknownMove(from,target,p1,promote(ptype),true,P);
00042 if(!Ptype_Table.isBetterToPromote(ptype))
00043 action.unknownMove(from,target,p1,ptype,false,P);
00044 }
00045 else
00046 action.unknownMove(from,target,p1,ptype,false,P);
00047 }
00048 else{
00049 action.unknownMove(from,target,p1,ptype,false,P);
00050 }
00051 }
00052 template<Player P>
00053 static void generatePiece(const NumEffectState& state,Piece p, Square target, Piece p1,Action& action)
00054 {
00055 if(p.ptype()==KING){
00056
00057 const Player altP=PlayerTraits<P>::opponent;
00058
00059
00060 if(state.hasEffectAt<altP>(target)) return;
00061 }
00062 if(state.pinOrOpen(P).test(p.number())){
00063 Direction d=state.pinnedDir<P>(p);
00064 Direction d1=Board_Table.getShort8Unsafe<P>(p.square(),target);
00065 if(primDir(d)!=primDirUnsafe(d1)) return;
00066 }
00067 generatePieceUnsafe<P>(state,p,target,p1,action);
00068 }
00073 template<Player P,Ptype T>
00074 static void generatePiecePtypeUnsafe(const NumEffectState& state,Piece p, Square target, Piece p1,Action& action)
00075 {
00076 assert(state.hasEffectByPiece(p, target));
00077 assert(p.ptype()==T);
00078
00079 Square from=p.square();
00080 if(canPromote(T) & (target.canPromote<P>() || from.canPromote<P>())){
00081 action.unknownMove(from,target,p1,promote(T),true,P);
00082 if(((T==PAWN || T==LANCE) &&
00083 (P==BLACK ? target.y()==1 : target.y()==9))||
00084 (T==KNIGHT && (P==BLACK ? target.y()<=2 : target.y()>=8)))
00085 return;
00086 if((T==ROOK || T==BISHOP || T==PAWN ||
00087 (T==LANCE && (P==BLACK ? target.y()==2 : target.y()==8))))
00088 return;
00089 }
00090 action.unknownMove(from,target,p1,T,false,P);
00091 }
00092 template<Player P,Ptype T>
00093 static void generatePiecePtype(const NumEffectState& state,Piece p, Square target, Piece p1,Action& action)
00094 {
00095 if(T==KING){
00096 assert(!state.hasEffectAt(alt(P),p.square()));
00097 if(state.hasEffectAt(alt(P),target)) return;
00098 }
00099 else if(state.pin(P).test(p.number())){
00100 Direction d=state.pinnedDir<P>(p);
00101 Direction d1=Board_Table.getShort8Unsafe<P>(p.square(),target);
00102 if(primDir(d)!=primDirUnsafe(d1)) return;
00103 }
00104 generatePiecePtypeUnsafe<P,T>(state,p,target,p1,action);
00105 }
00114 template <Player P,Ptype T,bool useDirMask>
00115 static void generatePtype(const NumEffectState& state,Piece p, Action& action,int dirMask=0);
00116
00117 template <Player P,Ptype T>
00118 static void generatePtype(const NumEffectState& state,Piece p, Action& action)
00119 {
00120 int dummy=0;
00121 generatePtype<P,T,false>(state,p,action,dummy);
00122 }
00131 template <Player P,Ptype T,bool useDirMask>
00132 static void generatePtypeUnsafe(const NumEffectState& state,Piece p, Action& action,int dirMask);
00133 template <Player P,Ptype T>
00134 static void generatePtypeUnsafe(const NumEffectState& state,Piece p, Action& action)
00135 {
00136 int dummy=0;
00137 generatePtypeUnsafe<P,T,false>(state,p,action,dummy);
00138 }
00139
00147 template <Player P,bool useDirMask>
00148 static void generate(const NumEffectState& state,Piece p, Action& action,int dirMask=0);
00149 };
00150
00151 struct GeneratePieceOnBoard
00152 {
00153 static void generate(Player turn, const NumEffectState& state, Piece target,
00154 container::MoveVector&);
00155 };
00156 }
00157 using move_generator::GeneratePieceOnBoard;
00158 }
00159
00160 #endif
00161
00162
00163
00164