My Project
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"
8namespace 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: