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