addEffect8Table.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
addEffect8Table.cc
Go to the documentation of this file.
1 #include "osl/move_generator/addEffect8Table.h"
2 #include "osl/ptypeTable.h"
3
4 namespace osl
5 {
6 namespace move_generator
7 {
8 namespace addeffect8{
9 bool
10 #ifdef __GNUC__
11 __attribute__ ((const))
12 #endif
13 sameDirection(int dx0, int dy0, int dx1, int dy1)
14 {
15 return dx0*dy1==dx1*dy0;
16 }
20 bool
21 #ifdef __GNUC__
22 __attribute__ ((pure))
23 #endif
24 hasUnblockableEffect(Ptype ptype,int dx,int dy)
25 {
26 if(std::abs(dx)>8 || std::abs(dy)>8) return false;
27 const EffectContent effect
28 =Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy));
29 return effect.hasUnblockableEffect();
30 }
31 bool
32 #ifdef __GNUC__
33 __attribute__ ((pure))
34 #endif
35 hasShortEffect(Ptype ptype,int dx,int dy)
36 {
37 if(std::abs(dx)>8 || std::abs(dy)>8) return false;
38 const EffectContent effect
39 =Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy));
40 return effect.hasEffect() && effect.offset().zero();
41 }
42 bool
43 #ifdef __GNUC__
44 __attribute__ ((pure))
45 #endif
46 hasEffect(Ptype ptype,int dx,int dy)
47 {
48 if(std::abs(dx)>8 || std::abs(dy)>8) return false;
49 return Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy)).hasEffect();
50 }
51 }
52 } // move_generator
53 }
54
55 void
56 osl::move_generator::addeffect8::AddEffect8Table::initDropSquare()
57 {
58 for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
59 Ptype ptype=static_cast<Ptype>(i);
60 if(ptype==KING) continue;
61 if(Ptype_Table.hasLongMove(ptype)) continue;
62 for(int x=1;x<=9;x++)
63 for(int y=1;y<=9;y++){
64 Square pos(x,y);
65 int index=0;
66 for(int x1=1;x1<=9;x1++)
67 for(int y1=1;y1<=9;y1++){
68 Square pos1(x1,y1);
69 if(pos==pos1)continue;
70 // 直接利きがある時は除く
71 if(hasUnblockableEffect(ptype,x-x1,y-y1)) continue;
72 for(int dx0=-1;dx0<=1;dx0++)
73 for(int dy0=-1;dy0<=1;dy0++){
74 int x2=x+dx0,y2=y+dy0;
75 Square pos2(x2,y2);
76 if(!pos2.isOnBoard()) continue;
77 if(hasUnblockableEffect(ptype,x2-x1,y2-y1))
78 goto found;
79 }
80 continue;
81 found:
82 dropSquare[ptype](pos.index(),index++)=pos1;
83 }
84 }
85 }
86 }
87
88 void
89 osl::move_generator::addeffect8::AddEffect8Table::initLongDropSquare()
90 {
91 for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
92 Ptype ptype=static_cast<Ptype>(i);
93 if(!Ptype_Table.hasLongMove(ptype)) continue;
94 assert(ptype==ROOK || ptype==BISHOP || ptype==LANCE);
95 for(int x=1;x<=9;x++)
96 for(int y=1;y<=9;y++){
97 const Square pos(x,y);
98 int sIndex=0,dIndex=0,index1=0,index2=0;
99 for(int x1=1;x1<=9;x1++)
100 for(int y1=1;y1<=9;y1++){
101 Square pos1(x1,y1);
102 if(pos==pos1)continue;
103 // 直接利きがある時はdirectにチャレンジ
104 if(hasEffect(ptype,x-x1,y-y1)){
105 if(!hasUnblockableEffect(ptype,x-x1,y-y1)) continue;
106 Square pos2(x+(x1-x)*2,y+(y1-y)*2);
107 if(!pos2.isOnBoard()) continue;
108 longDropDirect[ptype](pos.index(),dIndex++)=Offset(x1-x,y1-y);
109 continue;
110 }
111 int count=0;
112 CArray<int,2> dxs, dys;
113 for(int dx0=-1;dx0<=1;dx0++)
114 for(int dy0=-1;dy0<=1;dy0++){
115 int x2=x+dx0,y2=y+dy0;
116 Square pos2(x2,y2);
117 if(pos2==pos) continue;
118 if(!pos2.isOnBoard()) continue;
119 if(hasUnblockableEffect(ptype,x2-x1,y2-y1)){
120 dxs[count]=x1-x2;
121 dys[count++]=y1-y2;
122 }
123 }
124 if(count>0){
125 if(abs(x-x1)<=1 && abs(y-y1)<=1)
126 dropSquare[ptype](pos.index(),sIndex++)=pos1;
127 else if(count==1){
128 longDropSquare[ptype](pos.index(),index1++)=
129 PO(pos1,Offset(dxs[0],dys[0]));
130 }
131 else if(count==2){
132 longDrop2Square[ptype](pos.index(),index2++)=
133 POO(pos1,OffsetPair(Offset(dxs[0],dys[0]),
134 Offset(dxs[1],dys[1])));
135 }
136 }
137 }
138 }
139 }
140 }
141
142 void
143 osl::move_generator::addeffect8::AddEffect8Table::initMoveOffset()
144 {
145 for(int i=PTYPE_PIECE_MIN;i<=PTYPE_MAX;i++){
146 Ptype ptype=static_cast<Ptype>(i);
147 for(int dx=-8;dx<=8;dx++)
148 for(int dy=-8;dy<=8;dy++){
149 if(dx==0 && dy==0) continue;
150 Offset32 o32(dx,dy); // targetから見た駒の位置
151 // 最初から王手になっている場合は除く
152 if(hasUnblockableEffect(ptype,-dx,-dy)) continue;
153 // 最初から8近傍にあたる長い利きを持つ場合
154 for(int dx1=-1;dx1<=1;dx1++){
155 for(int dy1=-1;dy1<=1;dy1++){
156 if(dx1==0 && dy1==0) continue;
157 if(hasEffect(ptype,dx1-dx,dy1-dy) &&
158 !hasUnblockableEffect(ptype,dx1-dx,dy1-dy)){
159 int div=std::max(std::abs(dx1-dx),std::abs(dy1-dy));
160 // 8近傍の端の場合しか興味がない．
161 if(abs(dx1+(dx-dx1)/div)>1 ||
162 abs(dy1+(dy-dy1)/div)>1){
163 betweenOffset[ptype][o32.index()]=
164 OffsetPair(Offset(dx1,dy1),
165 Offset((dx1-dx)/div,(dy1-dy)/div));
166 }
167 }
168 }
169 }
170 int sIndex=0,lIndex=0,spIndex=0;
171 for(int dx0=-8;dx0<=8;dx0++)
172 for(int dy0=-8;dy0<=8;dy0++){
173 if(dx0==0 && dy0==0) continue;
174 // 移動できない場合は問題外
175 if(!hasEffect(ptype,dx0-dx,dy0-dy)) continue;
176 int effectDx=9,effectDy=9;
177 bool unblockableEffect=false;
178 bool effect=false;
179 bool promotedUnblockableEffect=false;
180 for(int dx1=-1;dx1<=1;dx1++){
181 for(int dy1=-1;dy1<=1;dy1++){
182 if(dx1==0 && dy1==0) continue;
183 if(hasUnblockableEffect(ptype,dx1-dx0,dy1-dy0)){
184 // 元々利きがあったなら数えない
185 if(!hasUnblockableEffect(ptype,dx1-dx,dy1-dy) &&
186 (!hasEffect(ptype,dx1-dx,dy1-dy) ||
187 !sameDirection(dx1-dx0,dy1-dy0,dx1-dx,dy1-dy) ||
188 (abs(dx0)<=1 && abs(dy0)<=1)
189 )){
190 unblockableEffect=true;
191 effect=true;
192 }
193 }
194 else if(hasEffect(ptype,dx1-dx0,dy1-dy0) &&
195 !hasEffect(ptype,dx1-dx,dy1-dy)){
196 if(std::abs(effectDx)>=std::abs(dx1-dx0) &&
197 std::abs(effectDy)>=std::abs(dy1-dy0)){
198 effectDx=dx1-dx0; effectDy=dy1-dy0;
199 effect=true;
200 }
201 else{
202 effect=true;
203 }
204 }
205 if(canPromote(ptype) &&
206 hasUnblockableEffect(osl::promote(ptype),dx1-dx0,dy1-dy0) &&
207 !hasUnblockableEffect(ptype,dx1-dx,dy1-dy)
208 ){
209 promotedUnblockableEffect=true;
210 }
211 }
212 }
213 if(unblockableEffect
214 // && !hasUnblockableEffect(ptype,-dx0,-dy0)
215 ){
216 shortMoveOffset[ptype](o32.index(),sIndex++)=Offset(dx0,dy0);
217 }
218 else if(effect){
219 // 同じ方向の時は，betweenにする
220 longMoveOffset[ptype](o32.index(),lIndex++)=
221 OffsetPair(Offset(dx0,dy0),Offset(dx0+effectDx,dy0+effectDy));
222 }
223 if(promotedUnblockableEffect
224 // &&!hasUnblockableEffect(promote(ptype),-dx0,-dy0)
225 ){
226 shortPromoteMoveOffset[ptype](o32.index(),spIndex++)=
227 Offset(dx0,dy0);
228 }
229 }
230 }
231 }
232 }
233 osl::move_generator::addeffect8::AddEffect8Table::AddEffect8Table()
234 {
235 initDropSquare();
236 initLongDropSquare();
237 initMoveOffset();
238 }
239 // ;;; Local Variables:
240 // ;;; mode:c++
241 // ;;; c-basic-offset:2
242 // ;;; End:
243