00001 #ifndef _GENERATE_ESCAPE_MOVES_TCC
00002 #define _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,Position 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,Position 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, Position pos, Action &action)
00054 {
00055 const PieceMask pieces = state.getEffect(pos) & state.getOnBoardMask(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.getPieceOf(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,Position to,Position from,Action &action)
00103 {
00104 assert(from.isOnBoard());
00105 Offset offset=Board_Table.getShortOffset(Offset32(from,to));
00106 assert(!offset.zero());
00107 for(Position pos=to+offset;pos!=from;pos+=offset){
00108 assert(state.getPieceAt(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,Position from,Action &action)
00134 {
00135 Position to=p.position();
00136 Offset offset=Board_Table.getShortOffset(Offset32(from,to));
00137 assert(!offset.zero());
00138 for(Position pos=to+offset;pos!=from;pos+=offset){
00139 assert(state.getPieceAt(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 attackerPiece,Action& action)
00149 {
00150 if(attackerPiece==Piece::EMPTY()){
00152 generateEscape<P,Type>(state,p,action);
00153 }
00154 else if(Type == KING){
00155 Position attackFrom=attackerPiece.position();
00156
00157 generateCaptureKing<P>( state, p, attackFrom, action );
00159 generateEscape<P,Type>( state,p,action);
00161 generateBlockingKing<P,CheapOnly>(state,p,attackFrom,action);
00162 }
00163 else{
00164 Position attackFrom=attackerPiece.position();
00165 generateCapture<P>( state, p, attackFrom, action );
00167 generateEscape<P,Type>( state,p,action);
00169 generateBlocking<P,CheapOnly>(state,p,p.position(),attackFrom,action);
00170 }
00171 }
00172
00173 template<class Action>
00174 template<Player P,bool CheapOnly>
00175 void Escape<Action>::
00176 generateKingEscape(const NumEffectState& state,Action& action){
00177 Piece kingPiece=state.getPieceOf(KingTraits<P>::index);
00178 Piece attackerPiece;
00179 #ifndef NDEBUG
00180 const bool isAttacked=
00181 #endif
00182 state.template findCheckPiece<P>(attackerPiece);
00183 assert(isAttacked);
00184 generateMovesBy<P,KING,CheapOnly>(state,kingPiece,attackerPiece,action);
00185 }
00186
00187 template<class Action>
00188 template<Player P,Ptype TYPE,bool CheapOnly>
00189 void Escape<Action>::
00190 generateMovesBy(const NumEffectState& state,Piece p,Action& action)
00191 {
00192 Position target=p.position();
00193 Piece attackerPiece;
00194 bool isAttacked=
00195 state.template hasEffectBy<PlayerTraits<P>::opponent>(target,attackerPiece);
00196 assert(isAttacked);
00197 generateMovesBy<P,TYPE,CheapOnly>(state,p,attackerPiece,action);
00198 }
00199
00200 template<class Action>
00201 template<Player P,bool CheapOnly>
00202 void Escape<Action>::
00203 generateMoves(const NumEffectState& state,Piece piece,Piece attackerPiece,Action& action)
00204 {
00205 switch(piece.ptype()){
00206 case PAWN: generateMovesBy<P,PAWN,CheapOnly>(state,piece,attackerPiece,action); break;
00207 case LANCE: generateMovesBy<P,LANCE,CheapOnly>(state,piece,attackerPiece,action); break;
00208 case KNIGHT: generateMovesBy<P,KNIGHT,CheapOnly>(state,piece,attackerPiece,action); break;
00209 case SILVER: generateMovesBy<P,SILVER,CheapOnly>(state,piece,attackerPiece,action); break;
00210 case PPAWN: generateMovesBy<P,PPAWN,CheapOnly>(state,piece,attackerPiece,action); break;
00211 case PLANCE: generateMovesBy<P,PLANCE,CheapOnly>(state,piece,attackerPiece,action); break;
00212 case PKNIGHT: generateMovesBy<P,PKNIGHT,CheapOnly>(state,piece,attackerPiece,action); break;
00213 case PSILVER: generateMovesBy<P,PSILVER,CheapOnly>(state,piece,attackerPiece,action); break;
00214 case GOLD: generateMovesBy<P,GOLD,CheapOnly>(state,piece,attackerPiece,action); break;
00215 case BISHOP: generateMovesBy<P,BISHOP,CheapOnly>(state,piece,attackerPiece,action); break;
00216 case PBISHOP: generateMovesBy<P,PBISHOP,CheapOnly>(state,piece,attackerPiece,action); break;
00217 case ROOK: generateMovesBy<P,ROOK,CheapOnly>(state,piece,attackerPiece,action); break;
00218 case PROOK: generateMovesBy<P,PROOK,CheapOnly>(state,piece,attackerPiece,action); break;
00219 case KING: generateMovesBy<P,KING,CheapOnly>(state,piece,attackerPiece,action); break;
00220 default: assert(0);
00221
00222 }
00223 }
00224 template<class Action>
00225 template<Player P,bool shouldPromote,bool CheapOnly>
00226 void Escape<Action>::
00227 generate(const NumEffectState& state,Piece piece,Action& action)
00228 {
00229 assert(piece.owner() == P);
00230 Position target=piece.position();
00231 Piece attackerPiece;
00232 state.template hasEffectBy<PlayerTraits<P>::opponent>(target,attackerPiece);
00233 generateMoves<P,CheapOnly>(state,piece,attackerPiece,action);
00234 }
00235 }
00236
00237 }
00238
00239 #endif // _GENERATE_ESCAPE_MOVES_TCC
00240
00241
00242
00243
00244