00001
00002
00003 #ifndef _POSITION_H
00004 #define _POSITION_H
00005
00006 #include "osl/misc/loki.h"
00007 #include "osl/offset.h"
00008
00009 namespace osl
00010 {
00036 class Position;
00037 bool operator==(Position l, Position r);
00038
00039 class Position
00040 {
00041 unsigned int position;
00042 explicit Position(int p) : position(p)
00043 {
00044 }
00045 public:
00046 static const Position makeDirect(int value) { return Position(value); }
00047 unsigned int uintValue() const { return position; }
00048 enum {
00049 PIECE_STAND=0,
00050 MIN=0,
00051 SIZE=0x100
00052 };
00053 Position() : position(PIECE_STAND)
00054 {
00055 }
00056 static const Position STAND() { return Position(PIECE_STAND); }
00057 Position(int x, int y) : position((x*Offset::BOARD_HEIGHT)+y+1)
00058 {
00059 assert(position < SIZE);
00060 }
00061 static const Position nth(unsigned int i) { return Position(i+MIN); }
00065 int x() const { return position >> 4; }
00069 int y() const { return (position&0xf)-1; }
00070 unsigned int index() const { return position - MIN; }
00071 static unsigned int indexMax() { return SIZE - MIN; }
00072 int indexForOffset32() const { return position + (position&0xf0); }
00073
00074 bool isPieceStand() const { return position == PIECE_STAND; }
00075 bool isOnBoardSlow() const;
00081 bool isOnBoard() const {
00082 unsigned int x=position-0x12;
00083 x=(x&0x1ff)+(x&0x1f0);
00084 return ((0x718-x)&0x610)==0x610;
00085 }
00086 bool isValid() const;
00087
00088
00089 const Position positionForBlackSlow(Player player) const;
00090
00091 const Position positionForBlack(Int2Type<BLACK>) const{
00092 assert(isOnBoard());
00093 Position ret=*this;
00094 return ret;
00095 }
00096
00097 const Position positionForBlack(Int2Type<WHITE>) const{
00098 assert(isOnBoard());
00099 Position ret=makeDirect(Position(9,9).uintValue()+Position(1,1).uintValue()-uintValue());
00100 return ret;
00101 }
00106 template<Player P>
00107 const Position positionForBlack() const{
00108 return positionForBlack(Int2Type<P>());
00109 }
00110 const Position positionForBlack(Player player) const{
00111 if(player==BLACK)
00112 return positionForBlack<BLACK>();
00113 else
00114 return positionForBlack<WHITE>();
00115 }
00116
00117 const Position rotate180() const
00118 {
00119 return positionForBlack<WHITE>();
00120 }
00121 const Position rotate180Safe() const
00122 {
00123 if (isPieceStand())
00124 return *this;
00125 return positionForBlack<WHITE>();
00126 }
00127 const Position flipHorizontal() const
00128 {
00129 if (isPieceStand())
00130 return *this;
00131 return Position(10-x(), y());
00132 }
00133
00134 static const Position onBoardMax(){ return Position(9,9); }
00135 static const Position onBoardMin(){ return Position(1,1); }
00136
00140 bool isOnBoardRegion() const {
00141 return static_cast<unsigned int>(index()-onBoardMin().index())
00142 <= static_cast<unsigned int>(onBoardMax().index()-onBoardMin().index());
00143 }
00144
00145 Position& operator++() {
00146 position += 1;
00147 return *this;
00148 }
00149
00150 static int reverseX(int x) { return 10-x; }
00151 static int reverseY(int y) { return 10-y; }
00152 private:
00153 bool canPromote(Int2Type<BLACK>) const
00154 {
00155 assert(isOnBoard());
00156 return y() <= 3;
00157 }
00158 bool canPromote(Int2Type<WHITE>) const
00159 {
00160 assert(isOnBoard());
00161 return y() >= 7;
00162 }
00163 public:
00164 template <Player P>
00165 bool canPromote() const { return canPromote(Int2Type<P>()); }
00166 bool canPromote(Player player) const
00167 {
00168 if (player==BLACK)
00169 return canPromote<BLACK>();
00170 else
00171 return canPromote<WHITE>();
00172 }
00173
00174 Position& operator+=(Offset offset) {
00175 position += offset.intValue();
00176 return *this;
00177 }
00178 Position& operator-=(Offset offset) {
00179 position -= offset.intValue();
00180 return *this;
00181 }
00182 const Position operator+(Offset offset) const {
00183 Position result(*this);
00184 return result+=offset;
00185 }
00186 const Position operator-(Offset offset) const {
00187 Position result(*this);
00188 return result-=offset;
00189 }
00190 const Offset operator-(Position other) const {
00191 return Offset::makeDirect(position - other.position);
00192 }
00193 };
00194
00195 inline bool operator==(Position l, Position r)
00196 {
00197 return l.uintValue() == r.uintValue();
00198 }
00199 inline bool operator!=(Position l, Position r)
00200 {
00201 return ! (l == r);
00202 }
00203 std::ostream& operator<<(std::ostream&, Position);
00204
00205 }
00206
00207 #endif
00208
00209
00210
00211