00001 #ifndef _PIECE_H
00002 #define _PIECE_H
00003 #include "osl/misc/loki.h"
00004 #include "osl/player.h"
00005 #include "osl/position.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,Position::STAND()); }
00033 static const Piece EDGE() { return Piece(WHITE,PTYPE_EDGE,EDGE_NUM,Position::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, Position position)
00039 : piece((static_cast<int>(owner)<<20)
00040 +(static_cast<int>(ptype)<<BitOffsetPtype)
00041 +((num)<<8)+ position.uintValue())
00042 {
00043 }
00044 Piece() : piece(EMPTY().piece)
00045 {
00046 }
00050 static const Piece makeKing(Player owner, Position position);
00051
00052 Ptype ptype() const {
00053 return static_cast<Ptype>((piece>>BitOffsetPtype)&0xf);
00054 }
00055 PtypeO ptypeO() const {
00056 return static_cast<PtypeO>(piece>>BitOffsetPtype);
00057 }
00058
00059 int number() const {
00060 return ((piece&0xff00)>>8);
00061 }
00062
00063 const Position position() const {
00064 return Position::makeDirect(piece&0xff);
00065 }
00066
00067 Piece& operator+=(Offset offset) {
00068 piece += offset.intValue();
00069 return *this;
00070 }
00071
00072 void setPosition(Position position) {
00073 piece = (piece&0xffffff00)+position.uintValue();
00074 }
00075 private:
00076 bool isOnBoardByOwner(Int2Type<BLACK>) const {
00077 return static_cast<int>(static_cast<unsigned int>(piece)&0x800000ff)>0;
00078 }
00084 bool isOnBoardByOwner(Int2Type<WHITE>) const {
00085 return static_cast<int>((-piece)&0x800000ff)>0;
00086 }
00087 public:
00094 template<Player P>
00095 bool isOnBoardByOwner() const { return isOnBoardByOwner(Int2Type<P>()); }
00099 bool isOnBoardByOwner(Player owner) const
00100 {
00101 if(owner==BLACK)
00102 return isOnBoardByOwner<BLACK>();
00103 else
00104 return isOnBoardByOwner<WHITE>();
00105 }
00106
00107
00108 const Piece promote() const {
00109 assert(canPromote(ptype()));
00110 return Piece(piece-0x80000);
00111 }
00112
00113
00114 const Piece unpromote() const {
00115 return Piece((int)piece|0x80000);
00116 }
00117
00122 const Piece captured() const {
00123
00124
00125 return Piece((piece&0xfff7ff00)^0xfff80000);
00126 }
00127
00128 const Piece promoteWithMask(int promote_mask) const {
00129 assert(! (isPromoted() && promote_mask));
00130 assert(promote_mask==0 || promote_mask==(1<<23));
00131 return Piece(piece - (promote_mask>>(BitOffsetMovePromote-BitOffsetPromote)));
00132 }
00133
00134 const Piece checkPromote(bool promotep) const {
00135 return Piece(piece - (promotep<<19));
00136 }
00137
00141 bool isPromoted() const { return (piece&(1<<19))==0; }
00142
00147 bool isOnBoardNotPromoted() const{
00148 int mask=piece&((1<<19)|0xff);
00149 return mask>(1<<19);
00150 }
00151 bool isPromotedNotKingGold() const {
00152 assert(ptype()!=KING && ptype()!=GOLD);
00153 return isPromoted();
00154 }
00155
00156 bool isEmpty() const {
00157 return (piece&0x8000)!=0;
00158 }
00159 static bool isEmptyNum(int num) {
00160 return (num&0x80)!=0;
00161 }
00162 bool isEdge() const {
00163 return (piece&0x4000)!=0;
00164 }
00165 static bool isEdgeNum(int num){
00166 assert(!isEmptyNum(num));
00167 return (num&0x40)!=0;
00168 }
00169 static bool isPieceNum(int num){
00170 return (num&0xc0)==0;
00171 }
00172 template<Ptype T>
00173 bool isPtype() const{
00174 return (piece&0xf0000)==((T)<<BitOffsetPtype);
00175 }
00176 bool isPiece() const {
00177 return (piece&0xc000)==0;
00178 }
00182 bool pieceIsBlack() const{
00183 assert(isPiece());
00184 return static_cast<int>(piece)>=0;
00185 }
00186 Player owner() const
00187 {
00188 assert(isPiece());
00189 return static_cast<Player>(piece>>20);
00190 }
00191
00192 private:
00199 bool canMoveOn(Int2Type<BLACK>) const {
00200 return ((piece+0xe0000)&0x104000)==0;
00201 }
00202 bool canMoveOn(Int2Type<WHITE>) const {
00203 return piece>=0;
00204 }
00205 public:
00210 template<Player P>
00211 bool canMoveOn() const { return canMoveOn(Int2Type<P>()); }
00212
00213 bool canMoveOn(Player pl) const{
00214 if(pl==BLACK)
00215 return canMoveOn<BLACK>();
00216 else
00217 return canMoveOn<WHITE>();
00218 }
00219
00220 bool isOnBoard() const {
00221 assert(position().isValid());
00222 return ! position().isPieceStand();
00223 }
00224 };
00225
00226 inline bool operator<(Piece l, Piece r)
00227 {
00228 return l.intValue() < r.intValue();
00229 }
00230 inline bool operator==(Piece l, Piece r)
00231 {
00232 return l.intValue() == r.intValue();
00233 }
00234 inline bool operator!=(Piece l, Piece r)
00235 {
00236 return ! (l == r);
00237 }
00238
00239 std::ostream& operator<<(std::ostream& os,const Piece piece);
00240 }
00241
00242 #endif
00243
00244
00245
00246