liberty8Table.cc
Go to the documentation of this file.
00001 #include "osl/effect/liberty8Table.h"
00002 #include "osl/boardTable.h"
00003 #include "osl/stl/vector.h"
00004 #include <iostream>
00005 #include <iomanip>
00006 #include <algorithm>
00007 
00008 namespace osl
00009 {
00010 namespace effect
00011 {
00015   static bool hasShortMove(Ptype ptype,int dx, int dy,int dx0, int dy0){
00016     if (dx<-8 || 8<dx || dy<-8 || 8<dy) return false;
00017     // 1マス離れたところにも利きを持ちうるか?
00018     const Offset32 long_offset = Offset32(dx,dy);
00019     const EffectContent effect
00020       =Ptype_Table.getEffect(newPtypeO(BLACK,ptype),
00021                              long_offset);
00022     const Offset offset=Board_Table.getShortOffset(long_offset);
00023     if (effect.hasUnblockableEffect()) {
00024       assert(! offset.zero());
00025       int dx1=dx+offset.dx();
00026       int dy1=dy+offset.dy();
00027       // shortにして良い
00028       if (abs(dx0-dx1)>1 || abs(dy0-dy1)>1) return true;
00029       //
00030       if (dx1<-8 || 8<dx1 || dy1<-8 || 8<dy1) return true;
00031       const EffectContent effect=Ptype_Table.getEffect(newPtypeO(BLACK,ptype),
00032                                                        Offset32(dx1,dy1));
00033       return ! effect.hasBlockableEffect();
00034     }
00035     else if (effect.hasBlockableEffect())
00036     {
00037       assert(! offset.zero());
00038       if (dx0==offset.dx() && dy0==offset.dy())
00039         return true;
00040     }
00041     return false;
00042   }
00048   static bool hasLongMove(Ptype ptype,int dx, int dy,int dx0,int dy0){
00049     if (dx<-8 || 8<dx || dy<-8 || 8<dy) return false;
00050     if (hasShortMove(ptype,dx,dy,dx0,dy0)) return false;
00051     EffectContent effect=Ptype_Table.getEffect(newPtypeO(BLACK,ptype),
00052                                                      Offset32(dx,dy));
00053     return effect.hasEffect();
00054   }
00060   static unsigned char shortMaskOf(Ptype ptype,int dx,int dy){
00061     unsigned int mask=0xff;
00065     if (dx==0 && dy==0)
00066       return mask;
00067     for (int i=0;i<8;i++){
00068       Direction dir=static_cast<Direction>(i);
00069       if (hasShortMove(ptype,dx+Board_Table.getDxForBlack(dir),
00070                       dy+Board_Table.getDyForBlack(dir),
00071                       dx,dy))
00072         mask&= ~(1<<i);
00073     }
00074     return mask;
00075   }
00081   static unsigned int directionOf(int dx, int dy){
00082     Direction dir=Board_Table.getLongDirection<BLACK>(Offset32(-dx,-dy));
00083     assert(isLong(dir));
00084     return 1<<(longToShort(dir));
00085   }
00091   LongEffect8 Liberty8Table::longEffectOf(Ptype ptype,int dx,int dy){
00092     assert(Ptype_Table.hasLongMove(ptype));
00093     LongEffect8 ret;
00097     if (dx==0 && dy==0)
00098       return ret;
00099     if ((ptype==PROOK || ptype==ROOK) && abs(dx)==1 && abs(dy)==1){
00100       LongEffect8 ret1;
00101       ret1.setOffset(Offset::ZERO());
00102       ret1.setMask(0,directionOf(0,dy));
00103       ret1.setMask(1,directionOf(-dx,dy));
00104       Offset32 offset32=Offset32(dx,dy);
00105       int index=offset32.index();
00106       longEffect2[index]=ret1;
00107 
00108       ret.setOffset(Offset(-dx,0));
00109       ret.setMask(0,directionOf(dx,0));
00110       ret.setMask(1,directionOf(dx,-dy));
00111       return ret;
00112     }
00113     typedef std::pair<Offset,unsigned char> OffsetMask;
00114     typedef std::pair<int,OffsetMask> LenOffsetMask;
00115     typedef vector<LenOffsetMask> LenOffsetMasks;
00116   
00117     LenOffsetMasks lenOffsetMasks;
00118     for (size_t i=0;i<8;i++){
00119       Direction dir=static_cast<Direction>(i);
00120       int dx1=Board_Table.getDxForBlack(dir);
00121       int dy1=Board_Table.getDyForBlack(dir);
00122       int dx2=dx+dx1;
00123       int dy2=dy+dy1;
00124       if (hasLongMove(ptype,dx2,dy2,dx,dy)){
00125         // マンハッタン距離
00126         int len=abs(dx2)+abs(dy2);
00127         Offset offset=Offset(dx1,dy1);
00128         unsigned char mask=(1<<i);
00129         lenOffsetMasks.push_back(LenOffsetMask(len,OffsetMask(offset,mask)));
00130       }
00131     }
00132     if (lenOffsetMasks.size()>0){
00133       std::sort(lenOffsetMasks.begin(),lenOffsetMasks.end());
00134       ret.setOffset(lenOffsetMasks[0].second.first);
00135       for (size_t i=0;i<lenOffsetMasks.size();i++){
00136         ret.setMask(i,lenOffsetMasks[i].second.second);
00137       }
00138     }
00139     return ret;
00140   }
00141   Liberty8Table::Liberty8Table(){
00142     {
00143 #ifndef NDEBUG
00144       const Offset32 long_offset = Offset32(-1,8);
00145       EffectContent const_effect=Ptype_Table.getEffect(newPtypeO(BLACK,ROOK),long_offset);
00146       assert(! const_effect.hasEffect());
00147 #endif
00148 
00149       assert(Ptype_Table.getEffect(newPtypeO(BLACK,PPAWN),
00150                                    Offset32(Square(7,1), Square(8,1)))
00151              == EffectContent::DIRECT());
00152     }
00153     for (int i=PTYPE_MAX;i>=PTYPE_PIECE_MIN;i--){
00154       Ptype ptype=static_cast<Ptype>(i);
00158       shortMask[i].fill();
00159       for (int dx= -8;dx<=8;dx++){
00160         for (int dy= -8;dy<=8;dy++){
00161           Offset32 offset32=Offset32(dx,dy);
00162           int index=offset32.index();
00163           shortMask[i][index]=shortMaskOf(ptype,dx,dy);
00164           if (Ptype_Table.hasLongMove(ptype)){
00165             longEffect[i][index]=longEffectOf(ptype,dx,dy);
00166           }
00167         }
00168       }
00169     }
00170   }
00171 #ifndef MINIMAL
00172   std::ostream& operator<<(std::ostream& os,LongEffect8 const& longEffect){
00173     os << "LongEffect(" << longEffect.getOffset() << ",[";
00174     for (int i=0;i<3;i++){
00175       if (longEffect.getMask(i)==0)break;
00176       os << std::setbase(16) << "0x" << longEffect.getMask(i) << std::setbase(10) << ",";
00177     }
00178     return os << "])";
00179   }
00180 #endif
00181 } // namespace effect
00182 } // namespace osl
00183 // ;;; Local Variables:
00184 // ;;; mode:c++
00185 // ;;; c-basic-offset:2
00186 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines