00001 #include "osl/move_generator/addEffect8Table.h"
00002 #include "osl/ptypeTable.h"
00003
00004 namespace osl
00005 {
00006 namespace move_generator
00007 {
00008 namespace addeffect8{
00009 bool sameDirection(int dx0, int dy0, int dx1, int dy1)
00010 {
00011 return dx0*dy1==dx1*dy0;
00012 }
00016 bool hasUnblockableEffect(Ptype ptype,int dx,int dy)
00017 {
00018 if(std::abs(dx)>8 || std::abs(dy)>8) return false;
00019 const EffectContent effect
00020 =Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy));
00021 return effect.hasUnblockableEffect();
00022 }
00023 bool hasShortEffect(Ptype ptype,int dx,int dy)
00024 {
00025 if(std::abs(dx)>8 || std::abs(dy)>8) return false;
00026 const EffectContent effect
00027 =Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy));
00028 return effect.hasEffect() && effect.offset().zero();
00029 }
00030 bool hasEffect(Ptype ptype,int dx,int dy)
00031 {
00032 if(std::abs(dx)>8 || std::abs(dy)>8) return false;
00033 return Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy)).hasEffect();
00034 }
00035 }
00036 }
00037 }
00038
00039 void
00040 osl::move_generator::addeffect8::AddEffect8Table::initDropPosition()
00041 {
00042 for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
00043 Ptype ptype=static_cast<Ptype>(i);
00044 if(ptype==KING) continue;
00045 if(Ptype_Table.hasLongMove(ptype)) continue;
00046 for(int x=1;x<=9;x++)
00047 for(int y=1;y<=9;y++){
00048 Position pos(x,y);
00049 int index=0;
00050 for(int x1=1;x1<=9;x1++)
00051 for(int y1=1;y1<=9;y1++){
00052 Position pos1(x1,y1);
00053 if(pos==pos1)continue;
00054
00055 if(hasUnblockableEffect(ptype,x-x1,y-y1)) continue;
00056 for(int dx0=-1;dx0<=1;dx0++)
00057 for(int dy0=-1;dy0<=1;dy0++){
00058 int x2=x+dx0,y2=y+dy0;
00059 Position pos2(x2,y2);
00060 if(!pos2.isOnBoard()) continue;
00061 if(hasUnblockableEffect(ptype,x2-x1,y2-y1))
00062 goto found;
00063 }
00064 continue;
00065 found:
00066 dropPosition[ptype](pos.index(),index++)=pos1;
00067 }
00068 }
00069 }
00070 }
00071
00072 void
00073 osl::move_generator::addeffect8::AddEffect8Table::initLongDropPosition()
00074 {
00075 for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
00076 Ptype ptype=static_cast<Ptype>(i);
00077 if(!Ptype_Table.hasLongMove(ptype)) continue;
00078 assert(ptype==ROOK || ptype==BISHOP || ptype==LANCE);
00079 for(int x=1;x<=9;x++)
00080 for(int y=1;y<=9;y++){
00081 const Position pos(x,y);
00082 int sIndex=0,dIndex=0,index1=0,index2=0;
00083 for(int x1=1;x1<=9;x1++)
00084 for(int y1=1;y1<=9;y1++){
00085 Position pos1(x1,y1);
00086 if(pos==pos1)continue;
00087
00088 if(hasEffect(ptype,x-x1,y-y1)){
00089 if(!hasUnblockableEffect(ptype,x-x1,y-y1)) continue;
00090 Position pos2(x+(x1-x)*2,y+(y1-y)*2);
00091 if(!pos2.isOnBoard()) continue;
00092 longDropDirect[ptype](pos.index(),dIndex++)=Offset(x1-x,y1-y);
00093 continue;
00094 }
00095 int count=0;
00096 CArray<int,2> dxs, dys;
00097 for(int dx0=-1;dx0<=1;dx0++)
00098 for(int dy0=-1;dy0<=1;dy0++){
00099 int x2=x+dx0,y2=y+dy0;
00100 Position pos2(x2,y2);
00101 if(pos2==pos) continue;
00102 if(!pos2.isOnBoard()) continue;
00103 if(hasUnblockableEffect(ptype,x2-x1,y2-y1)){
00104 dxs[count]=x1-x2;
00105 dys[count++]=y1-y2;
00106 }
00107 }
00108 if(count>0){
00109 if(abs(x-x1)<=1 && abs(y-y1)<=1)
00110 dropPosition[ptype](pos.index(),sIndex++)=pos1;
00111 else if(count==1){
00112 longDropPosition[ptype](pos.index(),index1++)=
00113 PO(pos1,Offset(dxs[0],dys[0]));
00114 }
00115 else if(count==2){
00116 longDrop2Position[ptype](pos.index(),index2++)=
00117 POO(pos1,OffsetPair(Offset(dxs[0],dys[0]),
00118 Offset(dxs[1],dys[1])));
00119 }
00120 }
00121 }
00122 }
00123 }
00124 }
00125
00126 void
00127 osl::move_generator::addeffect8::AddEffect8Table::initMoveOffset()
00128 {
00129 for(int i=PTYPE_PIECE_MIN;i<=PTYPE_MAX;i++){
00130 Ptype ptype=static_cast<Ptype>(i);
00131 for(int dx=-8;dx<=8;dx++)
00132 for(int dy=-8;dy<=8;dy++){
00133 if(dx==0 && dy==0) continue;
00134 Offset32 o32(dx,dy);
00135
00136 if(hasUnblockableEffect(ptype,-dx,-dy)) continue;
00137
00138 for(int dx1=-1;dx1<=1;dx1++){
00139 for(int dy1=-1;dy1<=1;dy1++){
00140 if(dx1==0 && dy1==0) continue;
00141 if(hasEffect(ptype,dx1-dx,dy1-dy) &&
00142 !hasUnblockableEffect(ptype,dx1-dx,dy1-dy)){
00143 int div=std::max(std::abs(dx1-dx),std::abs(dy1-dy));
00144
00145 if(abs(dx1+(dx-dx1)/div)>1 ||
00146 abs(dy1+(dy-dy1)/div)>1){
00147 betweenOffset[ptype][o32.index()]=
00148 OffsetPair(Offset(dx1,dy1),
00149 Offset((dx1-dx)/div,(dy1-dy)/div));
00150 }
00151 }
00152 }
00153 }
00154 int sIndex=0,lIndex=0,spIndex=0;
00155 for(int dx0=-8;dx0<=8;dx0++)
00156 for(int dy0=-8;dy0<=8;dy0++){
00157 if(dx0==0 && dy0==0) continue;
00158
00159 if(!hasEffect(ptype,dx0-dx,dy0-dy)) continue;
00160 int effectDx=9,effectDy=9;
00161 bool unblockableEffect=false;
00162 bool effect=false;
00163 bool promotedUnblockableEffect=false;
00164 for(int dx1=-1;dx1<=1;dx1++){
00165 for(int dy1=-1;dy1<=1;dy1++){
00166 if(dx1==0 && dy1==0) continue;
00167 if(hasUnblockableEffect(ptype,dx1-dx0,dy1-dy0)){
00168
00169 if(!hasUnblockableEffect(ptype,dx1-dx,dy1-dy) &&
00170 (!hasEffect(ptype,dx1-dx,dy1-dy) ||
00171 !sameDirection(dx1-dx0,dy1-dy0,dx1-dx,dy1-dy) ||
00172 (abs(dx0)<=1 && abs(dy0)<=1)
00173 )){
00174 unblockableEffect=true;
00175 effect=true;
00176 }
00177 }
00178 else if(hasEffect(ptype,dx1-dx0,dy1-dy0) &&
00179 !hasEffect(ptype,dx1-dx,dy1-dy)){
00180 if(std::abs(effectDx)>=std::abs(dx1-dx0) &&
00181 std::abs(effectDy)>=std::abs(dy1-dy0)){
00182 effectDx=dx1-dx0; effectDy=dy1-dy0;
00183 effect=true;
00184 }
00185 else{
00186 effect=true;
00187 }
00188 }
00189 if(canPromote(ptype) &&
00190 hasUnblockableEffect(osl::promote(ptype),dx1-dx0,dy1-dy0) &&
00191 !hasUnblockableEffect(ptype,dx1-dx,dy1-dy)
00192 ){
00193 promotedUnblockableEffect=true;
00194 }
00195 }
00196 }
00197 if(unblockableEffect
00198
00199 ){
00200 shortMoveOffset[ptype](o32.index(),sIndex++)=Offset(dx0,dy0);
00201 }
00202 else if(effect){
00203
00204 longMoveOffset[ptype](o32.index(),lIndex++)=
00205 OffsetPair(Offset(dx0,dy0),Offset(dx0+effectDx,dy0+effectDy));
00206 }
00207 if(promotedUnblockableEffect
00208
00209 ){
00210 shortPromoteMoveOffset[ptype](o32.index(),spIndex++)=
00211 Offset(dx0,dy0);
00212 }
00213 }
00214 }
00215 }
00216 }
00217 osl::move_generator::addeffect8::AddEffect8Table::AddEffect8Table()
00218 {
00219 initDropPosition();
00220 initLongDropPosition();
00221 initMoveOffset();
00222 }
00223
00224
00225
00226
00227