addEffect8Table.cc
Go to the documentation of this file.
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
00010 #ifdef __GNUC__
00011   __attribute__ ((const))
00012 #endif
00013   sameDirection(int dx0, int dy0, int dx1, int dy1)
00014   {
00015     return dx0*dy1==dx1*dy0;
00016   }
00020   bool
00021 #ifdef __GNUC__
00022         __attribute__ ((pure))
00023 #endif
00024   hasUnblockableEffect(Ptype ptype,int dx,int dy)
00025   {
00026     if(std::abs(dx)>8 || std::abs(dy)>8) return false;
00027     const EffectContent effect
00028       =Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy));
00029     return effect.hasUnblockableEffect();
00030   }
00031   bool
00032 #ifdef __GNUC__
00033         __attribute__ ((pure))
00034 #endif
00035   hasShortEffect(Ptype ptype,int dx,int dy)
00036   {
00037     if(std::abs(dx)>8 || std::abs(dy)>8) return false;
00038     const EffectContent effect
00039       =Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy));
00040     return effect.hasEffect() && effect.offset().zero();
00041   }
00042   bool
00043 #ifdef __GNUC__
00044   __attribute__ ((pure))
00045 #endif
00046   hasEffect(Ptype ptype,int dx,int dy)
00047   {
00048     if(std::abs(dx)>8 || std::abs(dy)>8) return false;
00049     return Ptype_Table.getEffect(newPtypeO(BLACK,ptype),Offset32(dx,dy)).hasEffect();
00050   }
00051 }
00052   } // move_generator
00053 }
00054 
00055 void
00056 osl::move_generator::addeffect8::AddEffect8Table::initDropSquare()
00057 {
00058   for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
00059     Ptype ptype=static_cast<Ptype>(i);
00060     if(ptype==KING) continue;
00061     if(Ptype_Table.hasLongMove(ptype)) continue;
00062     for(int x=1;x<=9;x++)
00063       for(int y=1;y<=9;y++){
00064         Square pos(x,y);
00065         int index=0;
00066         for(int x1=1;x1<=9;x1++)
00067           for(int y1=1;y1<=9;y1++){
00068             Square pos1(x1,y1);
00069             if(pos==pos1)continue;
00070             // 直接利きがある時は除く
00071             if(hasUnblockableEffect(ptype,x-x1,y-y1)) continue;
00072             for(int dx0=-1;dx0<=1;dx0++)
00073               for(int dy0=-1;dy0<=1;dy0++){
00074                 int x2=x+dx0,y2=y+dy0;
00075                 Square pos2(x2,y2);
00076                 if(!pos2.isOnBoard()) continue;
00077                 if(hasUnblockableEffect(ptype,x2-x1,y2-y1))
00078                   goto found;
00079               }
00080             continue;
00081           found:
00082             dropSquare[ptype](pos.index(),index++)=pos1;
00083           }
00084       }
00085   }
00086 }
00087 
00088 void
00089 osl::move_generator::addeffect8::AddEffect8Table::initLongDropSquare()
00090 {
00091   for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
00092     Ptype ptype=static_cast<Ptype>(i);
00093     if(!Ptype_Table.hasLongMove(ptype)) continue;
00094     assert(ptype==ROOK || ptype==BISHOP || ptype==LANCE);
00095     for(int x=1;x<=9;x++)
00096       for(int y=1;y<=9;y++){
00097         const Square pos(x,y);
00098         int sIndex=0,dIndex=0,index1=0,index2=0;
00099         for(int x1=1;x1<=9;x1++)
00100           for(int y1=1;y1<=9;y1++){
00101             Square pos1(x1,y1);
00102             if(pos==pos1)continue;
00103             // 直接利きがある時はdirectにチャレンジ
00104             if(hasEffect(ptype,x-x1,y-y1)){
00105               if(!hasUnblockableEffect(ptype,x-x1,y-y1)) continue;
00106               Square pos2(x+(x1-x)*2,y+(y1-y)*2);
00107               if(!pos2.isOnBoard()) continue;
00108               longDropDirect[ptype](pos.index(),dIndex++)=Offset(x1-x,y1-y);
00109               continue;
00110             }
00111             int count=0;
00112             CArray<int,2> dxs, dys;
00113             for(int dx0=-1;dx0<=1;dx0++)
00114               for(int dy0=-1;dy0<=1;dy0++){
00115                 int x2=x+dx0,y2=y+dy0;
00116                 Square pos2(x2,y2);
00117                 if(pos2==pos) continue;
00118                 if(!pos2.isOnBoard()) continue;
00119                 if(hasUnblockableEffect(ptype,x2-x1,y2-y1)){
00120                   dxs[count]=x1-x2;
00121                   dys[count++]=y1-y2;
00122                 }
00123               }
00124             if(count>0){
00125               if(abs(x-x1)<=1 && abs(y-y1)<=1)
00126                 dropSquare[ptype](pos.index(),sIndex++)=pos1;
00127               else if(count==1){
00128                 longDropSquare[ptype](pos.index(),index1++)=
00129                   PO(pos1,Offset(dxs[0],dys[0]));
00130               }
00131               else if(count==2){
00132                 longDrop2Square[ptype](pos.index(),index2++)=
00133                   POO(pos1,OffsetPair(Offset(dxs[0],dys[0]),
00134                                       Offset(dxs[1],dys[1])));
00135               }
00136             }
00137           }
00138       }
00139   }
00140 }
00141 
00142 void
00143 osl::move_generator::addeffect8::AddEffect8Table::initMoveOffset()
00144 {
00145   for(int i=PTYPE_PIECE_MIN;i<=PTYPE_MAX;i++){
00146     Ptype ptype=static_cast<Ptype>(i);
00147     for(int dx=-8;dx<=8;dx++)
00148       for(int dy=-8;dy<=8;dy++){
00149         if(dx==0 && dy==0) continue;
00150         Offset32 o32(dx,dy); // targetから見た駒の位置
00151         // 最初から王手になっている場合は除く
00152         if(hasUnblockableEffect(ptype,-dx,-dy)) continue;
00153         // 最初から8近傍にあたる長い利きを持つ場合
00154         for(int dx1=-1;dx1<=1;dx1++){
00155           for(int dy1=-1;dy1<=1;dy1++){
00156             if(dx1==0 && dy1==0) continue;
00157             if(hasEffect(ptype,dx1-dx,dy1-dy) &&
00158                !hasUnblockableEffect(ptype,dx1-dx,dy1-dy)){
00159               int div=std::max(std::abs(dx1-dx),std::abs(dy1-dy));
00160               // 8近傍の端の場合しか興味がない.
00161               if(abs(dx1+(dx-dx1)/div)>1 ||
00162                  abs(dy1+(dy-dy1)/div)>1){
00163                 betweenOffset[ptype][o32.index()]=
00164                   OffsetPair(Offset(dx1,dy1),
00165                              Offset((dx1-dx)/div,(dy1-dy)/div));
00166               }
00167             }
00168           }
00169         }
00170         int sIndex=0,lIndex=0,spIndex=0;
00171         for(int dx0=-8;dx0<=8;dx0++)
00172           for(int dy0=-8;dy0<=8;dy0++){
00173             if(dx0==0 && dy0==0) continue;
00174             // 移動できない場合は問題外
00175             if(!hasEffect(ptype,dx0-dx,dy0-dy)) continue;
00176             int effectDx=9,effectDy=9;
00177             bool unblockableEffect=false;
00178             bool effect=false;
00179             bool promotedUnblockableEffect=false;
00180             for(int dx1=-1;dx1<=1;dx1++){
00181               for(int dy1=-1;dy1<=1;dy1++){
00182                 if(dx1==0 && dy1==0) continue;
00183                 if(hasUnblockableEffect(ptype,dx1-dx0,dy1-dy0)){
00184                   // 元々利きがあったなら数えない
00185                   if(!hasUnblockableEffect(ptype,dx1-dx,dy1-dy) &&
00186                      (!hasEffect(ptype,dx1-dx,dy1-dy) ||
00187                       !sameDirection(dx1-dx0,dy1-dy0,dx1-dx,dy1-dy) ||
00188                       (abs(dx0)<=1 && abs(dy0)<=1)
00189                       )){
00190                     unblockableEffect=true;
00191                     effect=true;
00192                   }
00193                 }
00194                 else if(hasEffect(ptype,dx1-dx0,dy1-dy0) &&
00195                         !hasEffect(ptype,dx1-dx,dy1-dy)){
00196                   if(std::abs(effectDx)>=std::abs(dx1-dx0) &&
00197                      std::abs(effectDy)>=std::abs(dy1-dy0)){
00198                     effectDx=dx1-dx0; effectDy=dy1-dy0;
00199                     effect=true;
00200                   }
00201                   else{
00202                     effect=true;
00203                   }
00204                 }
00205                 if(canPromote(ptype) && 
00206                    hasUnblockableEffect(osl::promote(ptype),dx1-dx0,dy1-dy0) &&
00207                    !hasUnblockableEffect(ptype,dx1-dx,dy1-dy)
00208                    ){
00209                   promotedUnblockableEffect=true;
00210                 }
00211               }
00212             }
00213             if(unblockableEffect 
00214                //              && !hasUnblockableEffect(ptype,-dx0,-dy0)
00215                ){
00216               shortMoveOffset[ptype](o32.index(),sIndex++)=Offset(dx0,dy0);
00217             }
00218             else if(effect){
00219               // 同じ方向の時は,betweenにする
00220               longMoveOffset[ptype](o32.index(),lIndex++)=
00221                 OffsetPair(Offset(dx0,dy0),Offset(dx0+effectDx,dy0+effectDy));
00222             }
00223             if(promotedUnblockableEffect 
00224                //              &&!hasUnblockableEffect(promote(ptype),-dx0,-dy0)
00225                ){
00226               shortPromoteMoveOffset[ptype](o32.index(),spIndex++)=
00227                 Offset(dx0,dy0);
00228             }
00229           }
00230       }
00231   }
00232 }
00233 osl::move_generator::addeffect8::AddEffect8Table::AddEffect8Table()
00234 {
00235   initDropSquare();
00236   initLongDropSquare();
00237   initMoveOffset();
00238 }
00239 // ;;; Local Variables:
00240 // ;;; mode:c++
00241 // ;;; c-basic-offset:2
00242 // ;;; End:
00243 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines