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