ptypeTraits.h
Go to the documentation of this file.
00001 /* ptypeTraits.h
00002  */
00003 #ifndef OSL_PTYPETRAITS_H
00004 #define OSL_PTYPETRAITS_H
00005 
00006 #include "osl/misc/mask.h"
00007 #include "osl/misc/loki.h"
00008 #include "osl/ptype.h"
00009 #include "osl/directionTraits.h"
00010 #include "osl/square.h"
00011 
00012 namespace osl
00013 {
00014   template<Ptype T>
00015   struct PtypeTraits;
00016   
00017   template <>
00018   struct PtypeTraits<PTYPE_EMPTY>
00019   {
00020     static const bool isBasic=false;
00021     static const bool canPromote=false;
00023     static const bool betterToPromote=false;
00024     static const char *name() { return "PTYPE_EMPTY";}
00025     static const char *csaName() { return "..";}
00026     static const int moveMask=0;
00027   };
00028   
00029   template <>
00030   struct PtypeTraits<PTYPE_EDGE>
00031   {
00032     static const bool isBasic=false;
00033     static const bool canPromote=false;
00034     static const bool betterToPromote=false;
00035     static const char *name() { return "PTYPE_EDGE";}
00036     static const char *csaName() { return "XX";}
00037     static const int moveMask=0;
00038   };
00039   
00040   template <>
00041   struct PtypeTraits<GOLD>
00042   {
00043     static const bool isBasic=true;
00044     static const bool canPromote=false;
00045     static const bool betterToPromote=false;
00046     static const Ptype moveType=GOLD;
00047     static const char *name() { return "GOLD";}
00048     static const char *csaName() { return "KI";}
00049     static const int indexMin=26;
00050     static const int indexLimit=30;
00051     static const int dropBlackFromY=1;
00052     static const int dropBlackToY=9;
00053     static const Ptype basicType=GOLD;
00054     static const int moveMask=
00055     DirectionTraits<UL>::mask|DirectionTraits<U>::mask
00056     |DirectionTraits<UR>::mask|DirectionTraits<L>::mask
00057     |DirectionTraits<R>::mask|DirectionTraits<D>::mask;
00058   };
00059   
00060   template <>
00061   struct PtypeTraits<PAWN>
00062   {
00063     static const bool isBasic=true;
00064     static const bool canPromote=true;
00065     static const bool betterToPromote=true;
00066     static const Ptype moveType=PAWN;
00067     static const Ptype basicType=PAWN;
00068     static const char *name() { return "PAWN";}
00069     static const char *csaName() { return "FU";}
00070     static const int indexMin=0;
00071     static const int indexLimit=18;
00072     static const int dropBlackFromY=2;
00073     static const int dropBlackToY=9;
00074     static const int mayPromoteToY=4;
00075     static const int moveMask=DirectionTraits<U>::mask;
00076   };
00077   
00078   template <>
00079   struct PtypeTraits<PPAWN>
00080   {
00081     static const bool isBasic=false;
00082     static const bool canPromote=false;
00083     // 疑問 falseの方がよいのでは?
00084     static const bool betterToPromote=true;
00085     static const Ptype moveType=GOLD;
00086     static const char *name() { return "PPAWN";}
00087     static const char *csaName() { return "TO";}
00088     static const int moveMask=PtypeTraits<GOLD>::moveMask;
00089     static const Ptype basicType=PAWN;
00090     static const int indexMin=PtypeTraits<basicType>::indexMin;
00091   };
00092   
00093   template <>
00094   struct PtypeTraits<LANCE>
00095   {
00096     static const bool isBasic=true;
00097     static const bool canPromote=true;
00098     static const bool betterToPromote=false;
00099     static const Ptype moveType=LANCE;
00100     static const Ptype basicType=LANCE;
00101     static const char *name() { return "LANCE";}
00102     static const char *csaName() { return "KY";}
00103     static const int indexMin=32;
00104     static const int indexLimit=36;
00105     static const int dropBlackFromY=2;
00106     static const int dropBlackToY=9;
00107     static const int mayPromoteToY=9;
00108     static const int moveMask=DirectionTraits<LONG_U>::mask;
00109   };
00110   
00111   template <>
00112   struct PtypeTraits<PLANCE>
00113   {
00114     static const bool isBasic=false;
00115     static const bool canPromote=false;
00116     static const bool betterToPromote=false;
00117     static const Ptype moveType=GOLD;
00118     static const char *name() { return "PLANCE";}
00119     static const char *csaName() { return "NY";}
00120     static const int moveMask=PtypeTraits<GOLD>::moveMask;
00121     static const Ptype basicType=LANCE;
00122     static const int indexMin=PtypeTraits<basicType>::indexMin;
00123   };
00124   
00125   template <>
00126   struct PtypeTraits<KNIGHT>
00127   {
00128     static const bool isBasic=true;
00129     static const bool canPromote=true;
00130     static const bool betterToPromote=false;
00131     static const Ptype moveType=KNIGHT;
00132     static const Ptype basicType=KNIGHT;
00133     static const char *name() { return "KNIGHT";}
00134     static const char *csaName() { return "KE";}
00135     static const int indexMin=18;
00136     static const int indexLimit=22;
00137     static const int dropBlackFromY=3;
00138     static const int dropBlackToY=9;
00139     static const int mayPromoteToY=5;
00140     static const int moveMask=DirectionTraits<UUL>::mask|DirectionTraits<UUR>::mask;
00141   };
00142   
00143   template <>
00144   struct PtypeTraits<PKNIGHT>
00145   {
00146     static const bool isBasic=false;
00147     static const bool canPromote=false;
00148     static const bool betterToPromote=false;
00149     static const Ptype moveType=GOLD;
00150     static const char *name() { return "PKNIGHT";}
00151     static const char *csaName() { return "NK";}
00152     static const int moveMask=PtypeTraits<GOLD>::moveMask;
00153     static const Ptype basicType=KNIGHT;
00154     static const int indexMin=PtypeTraits<basicType>::indexMin;
00155   };
00156   
00157   template <>
00158   struct PtypeTraits<SILVER>
00159   {
00160     static const bool isBasic=true;
00161     static const bool canPromote=true;
00162     static const bool betterToPromote=false;
00163     static const Ptype moveType=SILVER;
00164     static const Ptype basicType=SILVER;
00165     static const char *name() { return "SILVER";}
00166     static const char *csaName() { return "GI";}
00167     static const int indexMin=22;
00168     static const int indexLimit=26;
00169     static const int dropBlackFromY=1;
00170     static const int dropBlackToY=9;
00171     static const int mayPromoteToY=4;
00172     static const int moveMask=
00173     DirectionTraits<UL>::mask|DirectionTraits<U>::mask
00174     |DirectionTraits<UR>::mask|DirectionTraits<DL>::mask
00175     |DirectionTraits<DR>::mask;
00176   };
00177   
00178   template <>
00179   struct PtypeTraits<PSILVER>
00180   {
00181     static const bool isBasic=false;
00182     static const bool canPromote=false;
00183     static const bool betterToPromote=false;
00184     static const Ptype moveType=GOLD;
00185     static const char *name() { return "PSILVER";}
00186     static const char *csaName() { return "NG";}
00187     static const int moveMask=PtypeTraits<GOLD>::moveMask;
00188     static const Ptype basicType=SILVER;
00189     static const int indexMin=PtypeTraits<basicType>::indexMin;
00190   };
00191   
00192   template <>
00193   struct PtypeTraits<BISHOP>
00194   {
00195     static const bool isBasic=true;
00196     static const bool canPromote=true;
00197     static const bool betterToPromote=true;
00198     static const Ptype moveType=BISHOP;
00199     static const Ptype basicType=BISHOP;
00200     static const char *name() { return "BISHOP";}
00201     static const char *csaName() { return "KA";}
00202     static const int indexMin=36;
00203     static const int indexLimit=38;
00204     static const int dropBlackFromY=1;
00205     static const int dropBlackToY=9;
00206     static const int mayPromoteToY=9;
00207     static const int moveMask=
00208     DirectionTraits<LONG_UL>::mask|DirectionTraits<LONG_UR>::mask
00209     |DirectionTraits<LONG_DL>::mask|DirectionTraits<LONG_DR>::mask;
00210   };
00211   
00212   template <>
00213   struct PtypeTraits<PBISHOP>
00214   {
00215     static const bool isBasic=false;
00216     static const bool canPromote=false;
00217     // 疑問 falseの方がよいのでは?
00218     static const bool betterToPromote=true;
00219     static const Ptype moveType=PBISHOP;
00220     static const char *name() { return "PBISHOP";}
00221     static const char *csaName() { return "UM";}
00222     static const int moveMask=
00223     DirectionTraits<LONG_UL>::mask|DirectionTraits<LONG_UR>::mask
00224     |DirectionTraits<LONG_DL>::mask|DirectionTraits<LONG_DR>::mask
00225     |DirectionTraits<U>::mask|DirectionTraits<L>::mask
00226     |DirectionTraits<R>::mask|DirectionTraits<D>::mask;
00227     static const Ptype basicType=BISHOP;
00228     static const int indexMin=PtypeTraits<basicType>::indexMin;
00229   };
00230   
00231   template <>
00232   struct PtypeTraits<ROOK>
00233   {
00234     static const bool isBasic=true;
00235     static const bool canPromote=true;
00236     static const bool betterToPromote=true;
00237     static const Ptype moveType=ROOK;
00238     static const Ptype basicType=ROOK;
00239     static const char *name() { return "ROOK";}
00240     static const char *csaName() { return "HI";}
00241     static const int indexMin=38;
00242     static const int indexLimit=40;
00243     static const int dropBlackFromY=1;
00244     static const int dropBlackToY=9;
00245     static const int mayPromoteToY=9;
00246     static const int moveMask=
00247     DirectionTraits<LONG_U>::mask|DirectionTraits<LONG_L>::mask
00248     |DirectionTraits<LONG_R>::mask|DirectionTraits<LONG_D>::mask;
00249   };
00250   
00251   template <>
00252   struct PtypeTraits<PROOK>
00253   {
00254     static const bool isBasic=false;
00255     static const bool canPromote=false;
00256     // 疑問 falseの方がよいのでは?
00257     static const bool betterToPromote=true;
00258     static const Ptype moveType=PROOK;
00259     static const char *name() { return "PROOK";}
00260     static const char *csaName() { return "RY";}
00261     static const int moveMask=
00262     DirectionTraits<LONG_U>::mask|DirectionTraits<LONG_L>::mask
00263     |DirectionTraits<LONG_R>::mask|DirectionTraits<LONG_D>::mask
00264     |DirectionTraits<UL>::mask|DirectionTraits<UR>::mask
00265     |DirectionTraits<DL>::mask|DirectionTraits<DR>::mask;
00266     static const Ptype basicType=ROOK;
00267     static const int indexMin=PtypeTraits<basicType>::indexMin;
00268   };
00269   
00270   
00271   template <>
00272   struct PtypeTraits<KING>
00273   {
00274     static const bool isBasic=true;
00275     static const bool canPromote=false;
00276     static const bool betterToPromote=false;
00277     static const Ptype moveType=KING;
00278     static const Ptype basicType=KING;
00279     static const char *name() { return "KING";}
00280     static const char *csaName() { return "OU";}
00281     static const int indexMin=30;
00282     static const int indexLimit=32;
00283     static const int dropBlackFromY=1;
00284     static const int dropBlackToY=9;
00285     static const int moveMask=
00286     DirectionTraits<U>::mask|DirectionTraits<L>::mask
00287     |DirectionTraits<R>::mask|DirectionTraits<D>::mask
00288     |DirectionTraits<UL>::mask|DirectionTraits<UR>::mask
00289     |DirectionTraits<DL>::mask|DirectionTraits<DR>::mask;
00290   };
00291 
00292   template<Ptype T,bool IsBasic>
00293   struct PtypeFunsSub;
00294   
00295   template<Ptype T>
00296   struct PtypeFunsSub<T,true>
00297   {
00298 #if OSL_WORDSIZE == 64
00299     static const mask_int_t indexMask=static_cast<mask_int_t>((-1LL<<(PtypeTraits<T>::indexMin))^(-1LL<<(PtypeTraits<T>::indexLimit)));
00300 #elif OSL_WORDSIZE == 32
00301     static const mask_int_t indexMask=static_cast<mask_int_t>((-1<<(PtypeTraits<T>::indexMin&31))^((-1<<(((PtypeTraits<T>::indexLimit-1)&31)))<<1));
00302 #endif
00303     static const Ptype promotePtype=static_cast<Ptype>(static_cast<int>(T)-8);
00304     static const Ptype basicType = T;
00305   };
00306   
00307   template<Ptype T>
00308   struct PtypeFunsSub<T,false>
00309   {
00310     static const mask_int_t indexMask=static_cast<mask_int_t>(0);
00311     //    static const Ptype promotePtype=PTYPE_EMPTY;
00312     static const Ptype promotePtype=T;
00313     static const Ptype basicType = PtypeTraits<T>::basicType;
00314   };
00315   
00316   template<Ptype T>
00317   struct PtypeFuns
00318   {
00319 #if OSL_WORDSIZE == 64
00320     static const unsigned int indexNum=0;
00321 #elif OSL_WORDSIZE == 32
00322     static const unsigned int indexNum=(PtypeTraits<T>::indexMin >> 5);
00323 #endif
00324     static const bool hasLongMove=(PtypeTraits<T>::indexMin>=32);
00325     static const mask_int_t indexMask=PtypeFunsSub<T,PtypeTraits<T>::isBasic>::indexMask;
00326     static const Ptype promotePtype=PtypeFunsSub<T,PtypeTraits<T>::canPromote>::promotePtype;
00327     static const Ptype basicType=PtypeFunsSub<T,PtypeTraits<T>::isBasic>::basicType;
00328   };
00329 
00334   enum MoveConstraint { 
00336     CannotMove,
00338     OnlyPromoted,
00340     OnlyBasic,
00342     NoConstraint,
00343   };
00344 
00345   template<Ptype T,Direction D>
00346   struct PtypeDirectionTraits
00347   {
00348     static const bool hasMove=(PtypeTraits<T>::moveMask & DirectionTraits<D>::mask)!=0;
00349     static const bool canMove=
00350     (PtypeTraits<T>::moveMask & DirectionTraits<D>::mask)!=0 ||
00351     (PtypeTraits<T>::moveMask & 
00352      DirectionTraits<DirectionTraits<D>::longDir>::mask)!=0;
00353     static const MoveConstraint moveConstraint =
00354     (PtypeDirectionTraits<T,D>::canMove 
00355      ? (PtypeDirectionTraits<PtypeFuns<T>::promotePtype,D>::canMove 
00356         ? NoConstraint : OnlyBasic ) 
00357      : (PtypeDirectionTraits<PtypeFuns<T>::promotePtype,D>::canMove 
00358         ? OnlyPromoted : CannotMove));
00359   };
00360   
00361   
00362   template<Player T>
00363   struct KingTraits
00364   {
00365     static const int index=PtypeTraits<KING>::indexMin+PlayerTraits<T>::index;
00366   };
00367 
00368   template<Ptype T,Player P>
00369   struct PtypePlayerTraits
00370   {
00371     static bool canDropTo(Square /*pos*/,Int2Type<false>)
00372     {
00373       assert(0);
00374       return false;
00375     }
00376     static bool canDropTo(Square pos,Int2Type<true>)
00377     {
00378       if (PtypeTraits<T>::dropBlackFromY == 1)
00379         return true; 
00380 
00381       if (P==BLACK)
00382         return pos.y() >= PtypeTraits<T>::dropBlackFromY;
00383       else
00384         return pos.y() <= Square::reverseY(PtypeTraits<T>::dropBlackFromY);
00385     }
00386     static bool canDropTo(Square pos)
00387     {
00388       return canDropTo(pos,Int2Type<PtypeTraits<T>::isBasic>());
00389     }
00394     static bool mayPromote(Square pos,Int2Type<true>)
00395     {
00396       if (PtypeTraits<T>::mayPromoteToY == 9)
00397         return true; 
00398 
00399       if (P==BLACK)
00400         return pos.y() <= PtypeTraits<T>::mayPromoteToY;
00401       else
00402         return pos.y() >= Square::reverseY(PtypeTraits<T>::mayPromoteToY);
00403     }
00404     static bool mayPromote(Square pos)
00405     {
00406       return mayPromote(pos,Int2Type<PtypeTraits<T>::isBasic &&
00407                         PtypeTraits<T>::canPromote>());
00408     }
00412     static bool mustPromote(Square pos)
00413     {
00414       if(P==BLACK){
00415         if(T==PAWN || T==LANCE) return pos.yEq<2>();
00416         else if(T==KNIGHT) return pos.yLe<4>();
00417         else return false;
00418       }
00419       else{
00420         if(T==PAWN || T==LANCE) return pos.yEq<8>();
00421         else if(T==KNIGHT) return pos.yGe<6>();
00422         else return false;
00423       }
00424     }
00428     static bool canPromote(Square pos)
00429     {
00430       if(P==BLACK){
00431         if(T==PAWN || T==LANCE) return pos.yLe<4>();
00432         else if(T==KNIGHT) return pos.yLe<5>();
00433         else return pos.yLe<3>();
00434       }
00435       else{
00436         if(T==PAWN || T==LANCE) return pos.yGe<6>();
00437         else if(T==KNIGHT) return pos.yGe<5>();
00438         else return pos.yGe<7>();
00439       }
00440     }
00445     static bool checkPromote(Square pos)
00446     {
00447       if(P==BLACK){
00448         if(T==SILVER) return pos.yEq<4>();
00449         else if(T==LANCE || T==ROOK || T==BISHOP)
00450           return true;
00451         else return false;
00452       }
00453       else{
00454         if(T==SILVER) return pos.yEq<6>();
00455         else if(T==LANCE || T==ROOK || T==BISHOP)
00456           return true;
00457         else return false;
00458       }
00459     }
00463     static bool noPromote(Square pos)
00464     {
00465       if(P==BLACK){
00466         if(T==PAWN || T==SILVER) return pos.yGe<5>();
00467         else if(T==KNIGHT) return pos.yGe<6>();
00468         else if(T==LANCE || T==ROOK || T==BISHOP) return false;
00469         else return true;
00470       }
00471       else{
00472         if(T==PAWN || T==SILVER) return pos.yLe<5>();
00473         else if(T==KNIGHT) return pos.yLe<4>();
00474         else if(T==LANCE || T==ROOK || T==BISHOP) return false;
00475         else return true;
00476       }
00477     }
00478   };
00479   
00480   
00481 } // namespace osl
00482 
00483 #endif /* OSL_PTYPETRAITS_H */
00484 // ;;; Local Variables:
00485 // ;;; mode:c++
00486 // ;;; c-basic-offset:2
00487 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines