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
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
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(Position(7,1), Position(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 std::ostream& operator<<(std::ostream& os,LongEffect8 const& longEffect){
00172 os << "LongEffect(" << longEffect.getOffset() << ",[";
00173 for (int i=0;i<3;i++){
00174 if (longEffect.getMask(i)==0)break;
00175 os << std::setbase(16) << "0x" << longEffect.getMask(i) << std::setbase(10) << ",";
00176 }
00177 return os << "])";
00178 }
00179 }
00180 }
00181
00182
00183
00184