00001 #ifndef OSL_GENERATE_ESCAPE_MOVES_TCC
00002 #define OSL_GENERATE_ESCAPE_MOVES_TCC
00003
00004 #include "osl/move_generator/escape_.h"
00005 #include "osl/move_generator/capture_.h"
00006 #include "osl/move_generator/move_action.h"
00007
00008 namespace osl
00009 {
00010 namespace move_generator
00011 {
00012 namespace escape
00013 {
00018 template<Player P,class Action,Ptype Type>
00019 bool generateDrop(const NumEffectState& state,Square to,Action& action){
00020 if(state.template hasPieceOnStand<Type>(P)){
00021 if((Type!=PAWN || !state.isPawnMaskSet(P,to.x())) &&
00022 PtypePlayerTraits<Type,P>::canDropTo(to)){
00023 action.dropMove(to,Type,P);
00024 return true;
00025 }
00026 }
00027 return false;
00028 }
00029
00030
00031
00032
00033 template<Player P,class Action,bool CheapOnly>
00034 void generateDropAll(const NumEffectState& state,Square to,Action& action)
00035 {
00036 bool gen = generateDrop<P,Action,PAWN>(state,to,action); if (CheapOnly && gen) return;
00037 gen = generateDrop<P,Action,LANCE>(state,to,action); if (CheapOnly && gen) return;
00038 gen = generateDrop<P,Action,KNIGHT>(state,to,action); if (CheapOnly && gen) return;
00039 gen = generateDrop<P,Action,SILVER>(state,to,action); if (CheapOnly && gen) return;
00040 gen = generateDrop<P,Action,GOLD>(state,to,action); if (CheapOnly && gen) return;
00041 gen = generateDrop<P,Action,BISHOP>(state,to,action); if (CheapOnly && gen) return;
00042 generateDrop<P,Action,ROOK>(state,to,action);
00043 }
00044
00050 template<Player P,class Action,bool CheapOnly>
00051 void
00052 blockByMoveOne(const NumEffectState& state, Square pos, Action &action)
00053 {
00054 const PieceMask pieces = state.effectSetAt(pos) & state.piecesOnBoard(P);
00055 int offset = 0;
00056 mask_t m = pieces.selectBit<PAWN>();
00057 if (m.none()) {
00058 m = pieces.selectBit<LANCE>();
00059 offset = PtypeFuns<LANCE>::indexNum*32;
00060 if (m.none()) {
00061 m = pieces.selectBit<KNIGHT>();
00062 offset = PtypeFuns<KNIGHT>::indexNum*32;
00063 if (m.none()) {
00064 m = pieces.selectBit<SILVER>();
00065 offset = PtypeFuns<SILVER>::indexNum*32;
00066 if (m.none()) {
00067 m = pieces.selectBit<GOLD>();
00068 offset = PtypeFuns<GOLD>::indexNum*32;
00069 if (m.none()) {
00070 m = pieces.selectBit<BISHOP>();
00071 offset = PtypeFuns<BISHOP>::indexNum*32;
00072 if (m.none()) {
00073 m = pieces.selectBit<ROOK>();
00074 offset = PtypeFuns<ROOK>::indexNum*32;
00075 if (m.none())
00076 return;
00077 }
00078 }
00079 }
00080 }
00081 }
00082 }
00083 const Piece p = state.pieceOf(m.takeOneBit() + offset);
00084 PieceOnBoard<Action>::template generatePiece<P>(state,p,pos,Piece::EMPTY(),action);
00085 }
00086 }
00087 using escape::generateDropAll;
00088 using escape::blockByMoveOne;
00089
00098 template<class Action>
00099 template<Player P,bool CheapOnly>
00100 void Escape<Action>::
00101 generateBlocking(const NumEffectState& state,Piece p,Square to,Square from,Action &action)
00102 {
00103 assert(from.isOnBoard());
00104 Offset offset=Board_Table.getShortOffset(Offset32(from,to));
00105 assert(!offset.zero());
00106 for(Square pos=to+offset;pos!=from;pos+=offset){
00107 assert(state.pieceAt(pos).isEmpty());
00108 if (! CheapOnly) {
00109 Capture<Action>::template escapeByCapture<P>(state,pos,p,action);
00110
00111 generateDropAll<P,Action,false>(state,pos,action);
00112 }
00113 else {
00114
00115 const int e = state.countEffect(P, pos);
00116 if (e >= 2)
00117 blockByMoveOne<P,Action,CheapOnly>(state, pos, action);
00118
00119 if (e)
00120 generateDropAll<P,Action,true>(state,pos,action);
00121 }
00122 }
00123 }
00129 template<class Action>
00130 template<Player P,bool CheapOnly>
00131 void Escape<Action>::
00132 generateBlockingKing(const NumEffectState& state,Piece p,Square from,Action &action)
00133 {
00134 Square to=p.square();
00135 Offset offset=Board_Table.getShortOffset(Offset32(from,to));
00136 assert(!offset.zero());
00137 for(Square pos=to+offset;pos!=from;pos+=offset){
00138 assert(state.pieceAt(pos).isEmpty());
00139 Capture<Action>::template escapeByCapture<P>(state,pos,p,action);
00140
00141 generateDropAll<P,Action,CheapOnly>(state,pos,action);
00142 }
00143 }
00144 template<class Action>
00145 template<Player P,Ptype Type,bool CheapOnly>
00146 void Escape<Action>::
00147 generateMovesBy(const NumEffectState& state,Piece p,Piece const attacker,Action& action)
00148 {
00149 if(attacker==Piece::EMPTY()){
00151 generateEscape<P,Type>(state,p,action);
00152 }
00153 else if(Type == KING){
00154 #ifndef NDEBUG
00155 {
00156 Piece attack_by_position;
00157 state.template findCheckPiece<P>(attack_by_position);
00158 assert(attacker == attack_by_position);
00159 }
00160 #endif
00161 Square attackFrom=attacker.square();
00162
00163 generateCaptureKing<P>( state, p, attackFrom, action );
00165 generateEscape<P,Type>( state,p,action);
00167 generateBlockingKing<P,CheapOnly>(state,p,attackFrom,action);
00168 }
00169 else{
00170 Square attackFrom=attacker.square();
00171 generateCapture<P>( state, p, attackFrom, action );
00173 generateEscape<P,Type>( state,p,action);
00175 generateBlocking<P,CheapOnly>(state,p,p.square(),attackFrom,action);
00176 }
00177 }
00178
00179 template<class Action>
00180 template<Player P,bool CheapOnly>
00181 void Escape<Action>::
00182 generateKingEscape(const NumEffectState& state,Action& action){
00183 Piece kingPiece=state.pieceOf(KingTraits<P>::index);
00184 Piece attacker;
00185 #ifndef NDEBUG
00186 const bool is_attacked=
00187 #endif
00188 state.template findCheckPiece<P>(attacker);
00189 assert(is_attacked);
00190 generateMovesBy<P,KING,CheapOnly>(state,kingPiece,attacker,action);
00191 }
00192
00193 template<class Action>
00194 template<Player P,Ptype TYPE,bool CheapOnly>
00195 void Escape<Action>::
00196 generateMovesBy(const NumEffectState& state,Piece p,Action& action)
00197 {
00198 Square target=p.square();
00199 Piece attacker;
00200 #ifndef NDEBUG
00201 const bool is_attacked=
00202 #endif
00203 state.template hasEffectAt<alt(P)>(target,attacker);
00204 assert(is_attacked);
00205 generateMovesBy<P,TYPE,CheapOnly>(state,p,attacker,action);
00206 }
00207
00208 template<class Action>
00209 template<Player P,bool CheapOnly>
00210 void Escape<Action>::
00211 generateMoves(const NumEffectState& state,Piece piece,Piece attacker,Action& action)
00212 {
00213 switch(piece.ptype()){
00214 case PAWN: generateMovesBy<P,PAWN,CheapOnly>(state,piece,attacker,action); break;
00215 case LANCE: generateMovesBy<P,LANCE,CheapOnly>(state,piece,attacker,action); break;
00216 case KNIGHT: generateMovesBy<P,KNIGHT,CheapOnly>(state,piece,attacker,action); break;
00217 case SILVER: generateMovesBy<P,SILVER,CheapOnly>(state,piece,attacker,action); break;
00218 case PPAWN: generateMovesBy<P,PPAWN,CheapOnly>(state,piece,attacker,action); break;
00219 case PLANCE: generateMovesBy<P,PLANCE,CheapOnly>(state,piece,attacker,action); break;
00220 case PKNIGHT: generateMovesBy<P,PKNIGHT,CheapOnly>(state,piece,attacker,action); break;
00221 case PSILVER: generateMovesBy<P,PSILVER,CheapOnly>(state,piece,attacker,action); break;
00222 case GOLD: generateMovesBy<P,GOLD,CheapOnly>(state,piece,attacker,action); break;
00223 case BISHOP: generateMovesBy<P,BISHOP,CheapOnly>(state,piece,attacker,action); break;
00224 case PBISHOP: generateMovesBy<P,PBISHOP,CheapOnly>(state,piece,attacker,action); break;
00225 case ROOK: generateMovesBy<P,ROOK,CheapOnly>(state,piece,attacker,action); break;
00226 case PROOK: generateMovesBy<P,PROOK,CheapOnly>(state,piece,attacker,action); break;
00227 case KING: generateMovesBy<P,KING,CheapOnly>(state,piece,attacker,action); break;
00228 default: assert(0);
00229
00230 }
00231 }
00232 template<class Action>
00233 template<Player P,bool shouldPromote,bool CheapOnly>
00234 void Escape<Action>::
00235 generate(const NumEffectState& state,Piece piece,Action& action)
00236 {
00237 assert(piece.owner() == P);
00238 Square target=piece.square();
00239 Piece attacker;
00240 state.template hasEffectAt<alt(P)>(target,attacker);
00241 generateMoves<P,CheapOnly>(state,piece,attacker,action);
00242 }
00243 }
00244
00245 }
00246
00247 #endif // OSL_GENERATE_ESCAPE_MOVES_TCC
00248
00249
00250
00251
00252