Go to the documentation of this file.00001
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
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
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
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
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 ,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 }
00482
00483 #endif
00484
00485
00486
00487