piece.h
Go to the documentation of this file.
00001 #ifndef OSL_PIECE_H
00002 #define OSL_PIECE_H
00003 #include "osl/misc/loki.h"
00004 #include "osl/player.h"
00005 #include "osl/square.h"
00006 #include "osl/ptype.h"
00007 
00008 #include <iosfwd>
00009 namespace osl
00010 {
00011   class Piece;
00012   inline bool operator==(Piece l, Piece r);
00013   const int EMPTY_NUM=0x80;
00014   const int EDGE_NUM=0x40;
00022   class Piece
00023   {
00024     int piece;
00025     Piece(int p) : piece(p)
00026     {
00027     }
00028   public:
00029     static const int SIZE=40;
00030     static const Piece makeDirect(int value) { return Piece(value); }
00031     int intValue() const { return piece; }
00032     static const Piece EMPTY()  { return Piece(BLACK,PTYPE_EMPTY,EMPTY_NUM,Square::STAND()); }
00033     static const Piece EDGE() { return Piece(WHITE,PTYPE_EDGE,EDGE_NUM,Square::STAND()); }
00034     static const int BitOffsetPtype=16;
00035     static const int BitOffsetPromote=BitOffsetPtype+3;
00036     static const int BitOffsetMovePromote=BitOffsetPromote+4;
00037     
00038     Piece(Player owner, Ptype ptype, int num, Square square)
00039       : piece((static_cast<int>(owner)<<20)
00040               +(static_cast<int>(ptype)<<BitOffsetPtype)
00041               +((num)<<8)+ square.uintValue())
00042     {
00043     }
00044     Piece() : piece(EMPTY().piece)
00045     {
00046     }
00050     static const Piece
00051 #ifdef __GNUC__
00052         __attribute__ ((pure))
00053 #endif
00054     makeKing(Player owner, Square square);
00055 
00056     Ptype ptype() const {
00057       return static_cast<Ptype>((piece>>BitOffsetPtype)&0xf);
00058     }
00059     PtypeO ptypeO() const {
00060       return static_cast<PtypeO>(piece>>BitOffsetPtype);
00061     }
00062 
00063     int number() const {
00064       return ((piece&0xff00)>>8);
00065     }
00066 
00067     const Square square() const {
00068       return Square::makeDirect(piece&0xff);
00069     }
00070 
00071     Piece& operator+=(Offset offset) {
00072       piece += offset.intValue();
00073       return *this;
00074     }
00075 
00076     void setSquare(Square square) {
00077       piece = (piece&0xffffff00)+square.uintValue();
00078     }
00079   private:
00080     bool isOnBoardByOwner(Int2Type<BLACK>) const {
00081       return static_cast<int>(static_cast<unsigned int>(piece)&0x800000ff)>0;
00082     }
00088     bool isOnBoardByOwner(Int2Type<WHITE>) const {
00089       return static_cast<int>((-piece)&0x800000ff)>0;
00090     }
00091   public:
00098     template<Player P>
00099     bool isOnBoardByOwner() const { return isOnBoardByOwner(Int2Type<P>()); }
00103     bool isOnBoardByOwner(Player owner) const
00104     {
00105       if(owner==BLACK)
00106         return isOnBoardByOwner<BLACK>();
00107       else
00108         return isOnBoardByOwner<WHITE>();
00109     }
00110 
00111     /* 成る.  PROMOTE不可なpieceに適用不可 */
00112     const Piece promote() const {
00113       assert(canPromote(ptype()));
00114       return Piece(piece-0x80000);
00115     }
00116 
00117     /* 成りを戻す.  PROMOTE不可なpieceに適用可  */
00118     const Piece unpromote() const {
00119       return Piece((int)piece|0x80000);
00120     }
00121 
00126     const Piece captured() const {
00127       // return (Piece)((((int)piece|0x80000)&0xffffff00)^0xfff00000);
00128       // をoptimizeする
00129       return Piece((piece&0xfff7ff00)^0xfff80000);
00130     }
00131 
00132     const Piece promoteWithMask(int promote_mask) const {
00133       assert(! (isPromoted() && promote_mask));
00134       assert(promote_mask==0 || promote_mask==(1<<23));
00135       return Piece(piece - (promote_mask>>(BitOffsetMovePromote-BitOffsetPromote)));
00136     }
00137 
00138     const Piece checkPromote(bool promotep) const {
00139       return Piece(piece - (promotep<<19));
00140     }
00141 
00145     bool isPromoted() const { return (piece&(1<<19))==0; }
00146 
00151     bool isOnBoardNotPromoted() const{
00152       int mask=piece&((1<<19)|0xff);
00153       return mask>(1<<19);
00154     }
00155     bool isPromotedNotKingGold() const {
00156       assert(ptype()!=KING && ptype()!=GOLD);
00157       return isPromoted();
00158     }
00159 
00160     bool isEmpty() const {
00161       return (piece&0x8000)!=0;
00162     }
00163     static bool isEmptyNum(int num) {
00164       return (num&0x80)!=0;
00165     }
00166     bool isEdge() const { 
00167       return (piece&0x4000)!=0;
00168     }
00169     static bool isEdgeNum(int num){
00170       assert(!isEmptyNum(num));
00171        return (num&0x40)!=0;
00172     }
00173     static bool isPieceNum(int num){
00174       return (num&0xc0)==0;
00175     }
00176     template<Ptype T>
00177     bool isPtype() const{
00178       return (piece&0xf0000)==((T)<<BitOffsetPtype);
00179     }
00184     bool isPlayerPtype(Player pl,Ptype ptype) const{
00185       assert(PTYPE_PIECE_MIN<=ptype && ptype<=PTYPE_MAX);
00186       return (piece&0x1f0000)==(((ptype)<<BitOffsetPtype)|(pl&0x100000));
00187     }
00192     bool isPlayerBasicPtype(Player pl,Ptype ptype) const{
00193       assert(PTYPE_PIECE_MIN<=ptype && ptype<=PTYPE_MAX);
00194       assert(isBasic(ptype));
00195       if(canPromote(ptype))
00196         return (piece&0x170000)==(((osl::promote(ptype))<<BitOffsetPtype)|(pl&0x100000));
00197       else
00198         return isPlayerPtype(pl,ptype);
00199     }
00200     bool isPiece() const {
00201       return (piece&0xc000)==0;
00202     }
00206     bool pieceIsBlack() const{
00207       assert(isPiece());
00208       return static_cast<int>(piece)>=0;
00209     }
00210     Player owner() const
00211     {
00212       assert(isPiece());
00213       return static_cast<Player>(piece>>20);
00214     }
00215 
00216   private:
00223     bool canMoveOn(Int2Type<BLACK>) const {
00224       return ((piece+0xe0000)&0x104000)==0;
00225     }
00226     bool canMoveOn(Int2Type<WHITE>) const {
00227       return piece>=0;
00228     }
00229   public:
00234     template<Player P>
00235     bool canMoveOn() const { return canMoveOn(Int2Type<P>()); }
00236 
00237     bool canMoveOn(Player pl) const{
00238       if(pl==BLACK) 
00239         return canMoveOn<BLACK>();
00240       else 
00241         return canMoveOn<WHITE>();
00242     }
00243 
00244     bool isOnBoard() const {
00245       assert(square().isValid());
00246       return ! square().isPieceStand();
00247     }
00248   };
00249 
00250   inline bool operator<(Piece l, Piece r)
00251   {
00252     return l.intValue() < r.intValue();
00253   }
00254   inline bool operator==(Piece l, Piece r)
00255   {
00256     return l.intValue() == r.intValue();
00257   }
00258   inline bool operator!=(Piece l, Piece r)
00259   {
00260     return ! (l == r);
00261   }
00262 
00263   std::ostream& operator<<(std::ostream& os,const Piece piece);
00264 }
00265 
00266 #endif /* OSL_PIECE_H */
00267 // ;;; Local Variables:
00268 // ;;; mode:c++
00269 // ;;; c-basic-offset:2
00270 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines