1#ifndef OSL_GENERATE_ESCAPE_MOVES_TCC
2#define OSL_GENERATE_ESCAPE_MOVES_TCC
4#include "osl/move_generator/escape_.h"
5#include "osl/move_generator/capture_.h"
6#include "osl/move_generator/move_action.h"
10 namespace move_generator
18 template<Player P,class Action,Ptype Type>
19 bool generateDrop(const NumEffectState& state,Square to,Action& action){
20 if(state.template hasPieceOnStand<Type>(P)){
21 if((Type!=PAWN || !state.isPawnMaskSet(P,to.x())) &&
22 PtypePlayerTraits<Type,P>::canDropTo(to)){
23 action.dropMove(to,Type,P);
31 * CheapOnlyの時は最も価値の低い駒を打つ手のみ生成する.
33 template<Player P,class Action,bool CheapOnly>
34 void generateDropAll(const NumEffectState& state,Square to,Action& action)
36 bool gen = generateDrop<P,Action,PAWN>(state,to,action); if (CheapOnly && gen) return;
37 gen = generateDrop<P,Action,LANCE>(state,to,action); if (CheapOnly && gen) return;
38 gen = generateDrop<P,Action,KNIGHT>(state,to,action); if (CheapOnly && gen) return;
39 gen = generateDrop<P,Action,SILVER>(state,to,action); if (CheapOnly && gen) return;
40 gen = generateDrop<P,Action,GOLD>(state,to,action); if (CheapOnly && gen) return;
41 gen = generateDrop<P,Action,BISHOP>(state,to,action); if (CheapOnly && gen) return;
42 generateDrop<P,Action,ROOK>(state,to,action);
48 * TODO: あんまりなif文 PAWN,LANCE mask, それ以外maskでOK
50 template<Player P,class Action,bool CheapOnly>
52 blockByMoveOne(const NumEffectState& state, Square pos, Action &action)
54 const PieceMask pieces = state.effectSetAt(pos) & state.piecesOnBoard(P);
56 mask_t m = pieces.selectBit<PAWN>();
58 m = pieces.selectBit<LANCE>();
59 offset = PtypeFuns<LANCE>::indexNum*32;
61 m = pieces.selectBit<KNIGHT>();
62 offset = PtypeFuns<KNIGHT>::indexNum*32;
64 m = pieces.selectBit<SILVER>();
65 offset = PtypeFuns<SILVER>::indexNum*32;
67 m = pieces.selectBit<GOLD>();
68 offset = PtypeFuns<GOLD>::indexNum*32;
70 m = pieces.selectBit<BISHOP>();
71 offset = PtypeFuns<BISHOP>::indexNum*32;
73 m = pieces.selectBit<ROOK>();
74 offset = PtypeFuns<ROOK>::indexNum*32;
83 const Piece p = state.pieceOf(m.takeOneBit() + offset);
84 PieceOnBoard<Action>::template generatePiece<P>(state,p,pos,Piece::EMPTY(),action);
86 } // end of namespace escape
87 using escape::generateDropAll;
88 using escape::blockByMoveOne;
91 * Square toにある玉以外の駒にfromにある駒から王手がかかっている時に,長い利きの途中に入る手を
98 template<class Action>
99 template<Player P,bool CheapOnly>
100 void Escape<Action>::
101 generateBlocking(const NumEffectState& state,Piece p,Square to,Square from,Action &action)
103 assert(from.isOnBoard());
104 Offset offset=Board_Table.getShortOffset(Offset32(from,to));
105 assert(!offset.zero());
106 for(Square pos=to+offset;pos!=from;pos+=offset){
107 assert(state.pieceAt(pos).isEmpty());
109 Capture<Action>::template escapeByCapture<P>(state,pos,p,action);
111 generateDropAll<P,Action,false>(state,pos,action);
115 const int e = state.countEffect(P, pos);
117 blockByMoveOne<P,Action,CheapOnly>(state, pos, action);
120 generateDropAll<P,Action,true>(state,pos,action);
125 * 玉pにfromにある駒から王手がかかっている時に,長い利きの途中に入る手を
129 template<class Action>
130 template<Player P,bool CheapOnly>
131 void Escape<Action>::
132 generateBlockingKing(const NumEffectState& state,Piece p,Square from,Action &action)
134 Square to=p.square();
135 Offset offset=Board_Table.getShortOffset(Offset32(from,to));
136 assert(!offset.zero());
137 for(Square pos=to+offset;pos!=from;pos+=offset){
138 assert(state.pieceAt(pos).isEmpty());
139 Capture<Action>::template escapeByCapture<P>(state,pos,p,action);
141 generateDropAll<P,Action,CheapOnly>(state,pos,action);
144 template<class Action>
145 template<Player P,Ptype Type,bool CheapOnly>
146 void Escape<Action>::
147 generateMovesBy(const NumEffectState& state,Piece p,Piece const attacker,Action& action)
149 if(attacker==Piece::EMPTY()){
151 generateEscape<P,Type>(state,p,action);
153 else if(Type == KING){
156 Piece attack_by_position;
157 state.template findCheckPiece<P>(attack_by_position);
158 assert(attacker == attack_by_position);
161 Square attackFrom=attacker.square();
163 generateCaptureKing<P>( state, p, attackFrom, action );
165 generateEscape<P,Type>( state,p,action);
167 generateBlockingKing<P,CheapOnly>(state,p,attackFrom,action);
170 Square attackFrom=attacker.square();
171 generateCapture<P>( state, p, attackFrom, action );
173 generateEscape<P,Type>( state,p,action);
175 generateBlocking<P,CheapOnly>(state,p,p.square(),attackFrom,action);
179 template<class Action>
180 template<Player P,bool CheapOnly>
181 void Escape<Action>::
182 generateKingEscape(const NumEffectState& state,Action& action){
183 Piece kingPiece=state.pieceOf(KingTraits<P>::index);
186 const bool is_attacked=
188 state.template findCheckPiece<P>(attacker);
189 assert(is_attacked); // 相手からの利きがないのに呼ぶな
190 generateMovesBy<P,KING,CheapOnly>(state,kingPiece,attacker,action);
193 template<class Action>
194 template<Player P,Ptype TYPE,bool CheapOnly>
195 void Escape<Action>::
196 generateMovesBy(const NumEffectState& state,Piece p,Action& action)
198 Square target=p.square();
201 const bool is_attacked=
203 state.template hasEffectAt<alt(P)>(target,attacker);
204 assert(is_attacked); // 相手からの利きがないのに呼ぶな
205 generateMovesBy<P,TYPE,CheapOnly>(state,p,attacker,action);
208 template<class Action>
209 template<Player P,bool CheapOnly>
210 void Escape<Action>::
211 generateMoves(const NumEffectState& state,Piece piece,Piece attacker,Action& action)
213 switch(piece.ptype()){
214 case PAWN: generateMovesBy<P,PAWN,CheapOnly>(state,piece,attacker,action); break;
215 case LANCE: generateMovesBy<P,LANCE,CheapOnly>(state,piece,attacker,action); break;
216 case KNIGHT: generateMovesBy<P,KNIGHT,CheapOnly>(state,piece,attacker,action); break;
217 case SILVER: generateMovesBy<P,SILVER,CheapOnly>(state,piece,attacker,action); break;
218 case PPAWN: generateMovesBy<P,PPAWN,CheapOnly>(state,piece,attacker,action); break;
219 case PLANCE: generateMovesBy<P,PLANCE,CheapOnly>(state,piece,attacker,action); break;
220 case PKNIGHT: generateMovesBy<P,PKNIGHT,CheapOnly>(state,piece,attacker,action); break;
221 case PSILVER: generateMovesBy<P,PSILVER,CheapOnly>(state,piece,attacker,action); break;
222 case GOLD: generateMovesBy<P,GOLD,CheapOnly>(state,piece,attacker,action); break;
223 case BISHOP: generateMovesBy<P,BISHOP,CheapOnly>(state,piece,attacker,action); break;
224 case PBISHOP: generateMovesBy<P,PBISHOP,CheapOnly>(state,piece,attacker,action); break;
225 case ROOK: generateMovesBy<P,ROOK,CheapOnly>(state,piece,attacker,action); break;
226 case PROOK: generateMovesBy<P,PROOK,CheapOnly>(state,piece,attacker,action); break;
227 case KING: generateMovesBy<P,KING,CheapOnly>(state,piece,attacker,action); break;
232 template<class Action>
233 template<Player P,bool shouldPromote,bool CheapOnly>
234 void Escape<Action>::
235 generate(const NumEffectState& state,Piece piece,Action& action)
237 assert(piece.owner() == P);
238 Square target=piece.square();
240 state.template hasEffectAt<alt(P)>(target,attacker);
241 generateMoves<P,CheapOnly>(state,piece,attacker,action);
243 } // namespace move_generator
247#endif // OSL_GENERATE_ESCAPE_MOVES_TCC
248// ;;; Local Variables:
250// ;;; c-basic-offset:2