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
00112 const Piece promote() const {
00113 assert(canPromote(ptype()));
00114 return Piece(piece-0x80000);
00115 }
00116
00117
00118 const Piece unpromote() const {
00119 return Piece((int)piece|0x80000);
00120 }
00121
00126 const Piece captured() const {
00127
00128
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
00267
00268
00269
00270