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 bool operator==(Piece l, Piece r);
00019 class Piece
00020 {
00021 int piece;
00022 Piece(int p) : piece(p)
00023 {
00024 }
00025 public:
00026 static const int SIZE=40;
00027 static const Piece makeDirect(int value) { return Piece(value); }
00028 int intValue() const { return piece; }
00029 static const Piece EMPTY() { return Piece(BLACK,PTYPE_EMPTY,0,Position::STAND()); }
00030 static const Piece EDGE() { return Piece(WHITE,PTYPE_EDGE,0,Position::STAND()); }
00031
00032 Piece(Player owner, Ptype ptype, int num, Position position)
00033 : piece((static_cast<int>(owner)<<20)
00034 |(static_cast<int>(ptype)<<16)
00035 |((num)<<8)| position.uintValue())
00036 {
00037 }
00038 Piece() : piece(EMPTY().piece)
00039 {
00040 }
00044 static const Piece makeKing(Player owner, Position position);
00045
00046 Ptype ptype() const {
00047 return static_cast<Ptype>((piece>>16)&0xf);
00048 }
00049 PtypeO ptypeO() const {
00050 return static_cast<PtypeO>(piece>>16);
00051 }
00052
00053 int number() const {
00054 return (piece>>8)&0xff;
00055 }
00056
00057 const Position position() const {
00058 return Position::makeDirect(piece&0xff);
00059 }
00060
00061 Piece& operator+=(Offset offset) {
00062 piece += offset.intValue();
00063 return *this;
00064 }
00065
00066 void setPosition(Position position) {
00067 piece = (piece&0xfffffe00)+position.uintValue();
00068 }
00069 private:
00070 bool isOnBoardByOwner(Int2Type<BLACK>) const {
00071 return static_cast<int>(static_cast<unsigned int>(piece)&0xfff000ff)>0;
00072 }
00073 bool isOnBoardByOwner(Int2Type<WHITE>) const {
00074 return (static_cast<unsigned int>(piece)&0xfff000ff)>0xfff00000;
00075 }
00076 public:
00083 template<Player P>
00084 bool isOnBoardByOwner() const { return isOnBoardByOwner(Int2Type<P>()); }
00089 bool isOnBoardByOwner(Player owner) const
00090 {
00091 if (owner == BLACK)
00092 return isOnBoardByOwner<BLACK>();
00093 else
00094 return isOnBoardByOwner<WHITE>();
00095 }
00096
00097
00098 const Piece promote() const {
00099 assert(canPromote(ptype()));
00100 return Piece(piece-0x80000);
00101 }
00102
00103
00104 const Piece unpromote() const {
00105 return Piece((int)piece|0x80000);
00106 }
00107
00112 const Piece captured() const {
00113
00114
00115 return Piece((piece&0xfff7ff00)^0xfff80000);
00116 }
00117
00118 const Piece promoteWithMask(int promote_mask) const {
00119 assert(! (isPromoted() && promote_mask));
00120 return Piece(piece - promote_mask);
00121 }
00122 const Piece unpromoteWithMask(int promote_mask) const {
00123 assert(isPromoted() || (promote_mask == 0));
00124 return Piece(piece + promote_mask);
00125 }
00126
00127 const Piece checkPromote(bool promotep) const {
00128 return promoteWithMask(promotep<<19);
00129 }
00130 const Piece checkUnpromote(bool promotep) const {
00131 return unpromoteWithMask(promotep<<19);
00132 }
00133
00137 bool isPromoted() const { return (piece&(1<<19))==0; }
00138
00143 bool isPromotedNotKingGold() const {
00144 assert(ptype()!=KING && ptype()!=GOLD);
00145 return isPromoted();
00146 }
00147
00148 bool isEmpty() const;
00149 bool isEdge() const;
00150 bool isPiece() const;
00151 Player owner() const;
00152
00153 private:
00164 bool canMoveOn(Int2Type<BLACK>) const {
00165 return (static_cast<unsigned int>(EDGE().piece)
00166 < (static_cast<unsigned int>(piece)-1));
00167 }
00174 bool canMoveOn(Int2Type<WHITE>) const {
00175 return EMPTY().piece <= piece;
00176 }
00177 public:
00182 template<Player P>
00183 bool canMoveOn() const { return canMoveOn(Int2Type<P>()); }
00184
00185 bool canMoveOn(Player pl) const{
00186 if(pl==BLACK)
00187 return canMoveOn<BLACK>();
00188 else
00189 return canMoveOn<WHITE>();
00190 }
00191
00192 bool isOnBoard() const {
00193 assert(position().isValid());
00194 return ! position().isPieceStand();
00195 }
00200 unsigned int ptypeOMask(PtypeO ptypeO) const {
00201 const int ret= -((piece&0x00ff0000)^
00202 ((static_cast<int>(ptypeO)<<16)&0x00ff0000));
00203 assert( (this->ptypeO()==ptypeO && ret==0) ||
00204 (this->ptypeO()!=ptypeO && ret<0));
00205 return static_cast<unsigned int>(ret);
00206 }
00207 };
00208
00209 inline bool operator<(Piece l, Piece r)
00210 {
00211 return l.intValue() < r.intValue();
00212 }
00213 inline bool operator==(Piece l, Piece r)
00214 {
00215 return l.intValue() == r.intValue();
00216 }
00217 inline bool operator!=(Piece l, Piece r)
00218 {
00219 return ! (l == r);
00220 }
00221
00222 inline bool Piece::isEmpty() const { return *this == EMPTY(); }
00223 inline bool Piece::isEdge() const { return *this == EDGE(); }
00224 inline bool Piece::isPiece() const { return !isEmpty() && !isEdge(); }
00225 inline Player Piece::owner() const
00226 {
00227 assert(isPiece());
00228 return static_cast<Player>(piece>>20);
00229 }
00230
00231
00232 std::ostream& operator<<(std::ostream& os,const Piece piece);
00233 }
00234
00235 #endif
00236
00237
00238
00239