promote_.tcc
Go to the documentation of this file.
1 #ifndef OSL_MOVE_GENERATOR_PROMOTE_TCC
2 #define OSL_MOVE_GENERATOR_PROMOTE_TCC
3 
4 #include "osl/move_generator/promote_.h"
5 #include "osl/basic_type.h"
6 #include "osl/bits/directionTraits.h"
7 #include "osl/bits/ptypeTraits.h"
8 namespace osl
9 {
10  namespace move_generator
11  {
12  namespace promote
13  {
14  template<Player P,Ptype T,bool noCapture,Direction Dir>
15  class AllPromoteDir
16  {
17  template <class Action>
18  static void generateIfValid(const NumEffectState& state,Piece piece, Action& action,
19  Int2Type<true> /*isLong*/, Int2Type<true>)
20  {
21  const Square from = piece.square();
22  const Direction black_direction = longToShort(DirectionPlayerTraits<Dir,P>::directionByBlack);
23  Square last = state.mobilityOf(black_direction, piece.number());
24  const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
25  assert(! last.isPieceStand());
26  assert(!offset.zero());
27  for (Square to=from+offset; to!=last; to+=offset) {
28  assert(state.pieceAt(to).isEmpty());
29  action.simpleMove(from,to,PtypeFuns<T>::promotePtype,true,P);
30  }
31  const Piece last_piece = state.pieceAt(last);
32  if (!noCapture && last_piece.canMoveOn<P>()){
33  action.unknownMove(from,last,last_piece,PtypeFuns<T>::promotePtype,true,P);
34  }
35  }
36  // short move
37  template <class Action>
38  static void generateIfValid(const NumEffectState& state,Piece p, Action& action,
39  Int2Type<false> /*isLong*/,Int2Type<true>){
40  Square pos=p.square();
41  const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
42  Square toPos=pos+offset;
43  Piece p1=state.pieceAt(toPos);
44  if (p1.isEmpty()){
45  action.simpleMove(pos,toPos,PtypeFuns<T>::promotePtype,true,P);
46  }
47  else if (!noCapture && p1.canMoveOn<P>()){
48  action.unknownMove(pos,toPos,p1,PtypeFuns<T>::promotePtype,true,P);
49  }
50  }
51  template <class Action>
52  static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<true>,Int2Type<false>){
53  }
54  template <class Action>
55  static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<false>,Int2Type<false>){
56  }
57  public:
58  template<class Action>
59  static void generate(NumEffectState const& state,Piece p,Action& action){
60  generateIfValid(state,p,action,
61  Int2Type<DirectionTraits<Dir>::isLong>(),
62  Int2Type<(PtypeTraits<T>::moveMask
63  & DirectionTraits<Dir>::mask) !=0>());
64  }
65  };
66  /**
67  * 指定した駒が常にpromote可能な場合にpromoteする動きを作る
68  */
69  template<Player P,Ptype T,bool noCapture>
70  class AllPromote{
71  public:
72  template<class Action>
73  static void generate(NumEffectState const& state,Piece p,Action& action){
74  AllPromoteDir<P,T,noCapture,UL>::generate(state,p,action);
75  AllPromoteDir<P,T,noCapture,U>::generate(state,p,action);
76  AllPromoteDir<P,T,noCapture,UR>::generate(state,p,action);
77  AllPromoteDir<P,T,noCapture,L>::generate(state,p,action);
78  AllPromoteDir<P,T,noCapture,R>::generate(state,p,action);
79  AllPromoteDir<P,T,noCapture,DL>::generate(state,p,action);
80  AllPromoteDir<P,T,noCapture,D>::generate(state,p,action);
81  AllPromoteDir<P,T,noCapture,DR>::generate(state,p,action);
82  AllPromoteDir<P,T,noCapture,UUL>::generate(state,p,action);
83  AllPromoteDir<P,T,noCapture,UUR>::generate(state,p,action);
84  AllPromoteDir<P,T,noCapture,LONG_UL>::generate(state,p,action);
85  AllPromoteDir<P,T,noCapture,LONG_U>::generate(state,p,action);
86  AllPromoteDir<P,T,noCapture,LONG_UR>::generate(state,p,action);
87  AllPromoteDir<P,T,noCapture,LONG_L>::generate(state,p,action);
88  AllPromoteDir<P,T,noCapture,LONG_R>::generate(state,p,action);
89  AllPromoteDir<P,T,noCapture,LONG_DL>::generate(state,p,action);
90  AllPromoteDir<P,T,noCapture,LONG_D>::generate(state,p,action);
91  AllPromoteDir<P,T,noCapture,LONG_DR>::generate(state,p,action);
92  }
93  };
94  template<Player P,Ptype T,bool noCapture,Direction Dir>
95  class MayPromoteDir
96  {
97  template <class Action>
98  static void generateIfValid(const NumEffectState& state,Piece piece, Action& action,
99  Int2Type<true> /*isLong*/, Int2Type<true>)
100  {
101  const Square from = piece.square();
102  const Direction black_direction = longToShort(DirectionPlayerTraits<Dir,P>::directionByBlack);
103  Square last = state.mobilityOf(black_direction, piece.number());
104  const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
105  assert(! last.isPieceStand());
106  assert(! offset.zero());
107 
108  const Piece last_piece = state.pieceAt(last);
109  if (!noCapture && last_piece.canMoveOn<P>()){
110  if (! last.canPromote<P>())
111  return;
112  action.unknownMove(from,last,last_piece,PtypeFuns<T>::promotePtype,true,P);
113  }
114  for (Square to=last-offset; to!=from; to-=offset) {
115  assert(state.pieceAt(to).isEmpty());
116  if (! to.canPromote<P>())
117  return;
118  action.simpleMove(from,to,PtypeFuns<T>::promotePtype,true,P);
119  }
120  }
121  // short move
122  template <class Action>
123  static void generateIfValid(const NumEffectState& state,Piece p, Action& action, Int2Type<false>,Int2Type<true>){
124  Square pos=p.square();
125  const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
126  Square toPos=pos+offset;
127  Piece p1=state.pieceAt(toPos);
128  if (p1.isEmpty()){
129  action.simpleMove(pos,toPos,PtypeFuns<T>::promotePtype,true,P);
130  }
131  else if (!noCapture && p1.canMoveOn<P>()){
132  action.unknownMove(pos,toPos,p1,PtypeFuns<T>::promotePtype,true,P);
133  }
134  }
135  template <class Action>
136  static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<true>,Int2Type<false>){
137  }
138  template <class Action>
139  static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<false>,Int2Type<false>){
140  }
141  public:
142  template<class Action>
143  static void generate(NumEffectState const& state,Piece p,Action& action){
144  generateIfValid(state,p,action,
145  Int2Type<DirectionTraits<Dir>::isLong>(),
146  Int2Type<(PtypeTraits<T>::moveMask
147  & DirectionTraits<Dir>::mask) !=0>());
148  }
149  };
150  /**
151  * 指定した駒が移動先によってはpromoteできる場合
152  */
153  template<Player P,Ptype T,bool noCapture>
154  class MayPromote{
155  public:
156  template<class Action>
157  static void generate(NumEffectState const& state,Piece p,Action& action){
158  MayPromoteDir<P,T,noCapture,UL>::generate(state,p,action);
159  MayPromoteDir<P,T,noCapture,U>::generate(state,p,action);
160  MayPromoteDir<P,T,noCapture,UR>::generate(state,p,action);
161  MayPromoteDir<P,T,noCapture,UUL>::generate(state,p,action);
162  MayPromoteDir<P,T,noCapture,UUR>::generate(state,p,action);
163  MayPromoteDir<P,T,noCapture,LONG_UL>::generate(state,p,action);
164  MayPromoteDir<P,T,noCapture,LONG_U>::generate(state,p,action);
165  MayPromoteDir<P,T,noCapture,LONG_UR>::generate(state,p,action);
166  }
167  };
168 
169  template<typename Action,Player P,Ptype T,bool noCapture>
170  struct EachOnBoard
171  {
172  const NumEffectState& state;
173  Action& action;
174  EachOnBoard(const NumEffectState& state,Action& action):state(state),action(action){}
175  void operator()(Piece p){
176  assert(! p.isPromoted());
177  if (PtypePlayerTraits<T,P>::mayPromote(p.square())){
178  if (p.square().template canPromote<P>()){
179  AllPromote<P,T,noCapture>::generate(state,p,action);
180  }
181  else{
182  MayPromote<P,T,noCapture>::generate(state,p,action);
183  }
184  }
185  }
186  };
187  }
188 
189  template<Player P, bool noCapture>
190  template <class Action, Ptype T>
191  void Promote<P,noCapture>::
192  generateMovesPtype(const NumEffectState& state, Action& action){
193  typedef promote::EachOnBoard<Action,P,T,noCapture> each_t;
194  each_t eachOnBoard(state,action);
195  state.template forEachOnBoardPtypeStrict<P,T,each_t>(eachOnBoard);
196  }
197 
198  template<Player P,bool noCapture>
199  template <class Action>
200  void Promote<P,noCapture>::
201  generateMoves(const NumEffectState& state, Action& action){
202  // promoteの価値の高い順に生成してみる
203  // PAWNは600-100=500
204  generateMovesPtype<Action,PAWN>(state,action);
205  // ROOKは1300-950=350
206  generateMovesPtype<Action,ROOK>(state,action);
207  // BISHOPは1150-800=350
208  generateMovesPtype<Action,BISHOP>(state,action);
209  // LANCEは600-400=200
210  generateMovesPtype<Action,LANCE>(state,action);
211  // KNIGHTは600-400=200
212  generateMovesPtype<Action,KNIGHT>(state,action);
213  // SILVERは600-550=50
214  generateMovesPtype<Action,SILVER>(state,action);
215  // GOLD,KINGはpromoteしないので除く
216  }
217  }
218 }
219 #endif /* OSL_MOVE_GENERATOR_PROMOTE_TCC */
220 // ;;; Local Variables:
221 // ;;; mode:c++
222 // ;;; c-basic-offset:2
223 // ;;; End: