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