00001
00002
00003 #ifndef _POSITION_H
00004 #define _POSITION_H
00005
00006 #include "osl/misc/loki.h"
00007 #include "osl/offset.h"
00008 #include <boost/utility/enable_if.hpp>
00009
00010 namespace osl
00011 {
00037 class Position;
00038 bool operator==(Position l, Position r);
00039
00040 class Position
00041 {
00042 unsigned int position;
00043 explicit Position(int p) : position(p)
00044 {
00045 }
00046 public:
00047 static const Position makeDirect(int value) { return Position(value); }
00048 unsigned int uintValue() const { return position; }
00049 enum {
00050 PIECE_STAND=0,
00051 MIN=0,
00052 SIZE=0x100
00053 };
00054 Position() : position(PIECE_STAND)
00055 {
00056 }
00057 static const Position STAND() { return Position(PIECE_STAND); }
00058 Position(int x, int y) : position((x*Offset::BOARD_HEIGHT)+y+1)
00059 {
00060 assert(position < SIZE);
00061 }
00065 static const Position makeNoCheck(int x, int y) {
00066 return Position((x*Offset::BOARD_HEIGHT)+y+1);
00067 }
00068 static const Position nth(unsigned int i) { return Position(i+MIN); }
00072 int x() const { return position >> 4; }
00076 int y() const { return (position&0xf)-1; }
00080 int y1() const { return position&0xf; }
00081 unsigned int index() const { return position - MIN; }
00082 static unsigned int indexMax() { return SIZE - MIN; }
00083 int indexForOffset32() const { return position + (position&0xf0); }
00084
00085 bool isPieceStand() const { return position == PIECE_STAND; }
00086 bool isOnBoardSlow() const;
00092 bool isOnBoard() const {
00093 return (0xffffff88&(position-0x12)&
00094 ((unsigned int)((position&0x77)^0x12)+0xffffff77))==0;
00095 }
00100 bool isEdge() const {
00101 assert(!isPieceStand() && 0<=x() && x()<=10 && 0<=y() && y()<=10);
00102 return (0x88&(position-0x12)&((position&0x11)+0xf7))!=0;
00103 }
00104 bool isValid() const;
00105
00106
00107 const Position positionForBlackSlow(Player player) const;
00108
00109 const Position positionForBlack(Int2Type<BLACK>) const{
00110 assert(isOnBoard());
00111 Position ret=*this;
00112 return ret;
00113 }
00114
00115 const Position positionForBlack(Int2Type<WHITE>) const{
00116 assert(isOnBoard());
00117 Position ret=makeDirect(Position(9,9).uintValue()+Position(1,1).uintValue()-uintValue());
00118 return ret;
00119 }
00124 template<Player P>
00125 const Position positionForBlack() const{
00126 return positionForBlack(Int2Type<P>());
00127 }
00128 const Position positionForBlack(Player player) const{
00129 if(player==BLACK)
00130 return positionForBlack<BLACK>();
00131 else
00132 return positionForBlack<WHITE>();
00133 }
00134
00135 const Position rotate180() const
00136 {
00137 return positionForBlack<WHITE>();
00138 }
00139 const Position rotate180EdgeOK() const
00140 {
00141 Position ret=makeDirect(Position(9,9).uintValue()+Position(1,1).uintValue()-uintValue());
00142 return ret;
00143 }
00144 const Position rotate180Safe() const
00145 {
00146 if (isPieceStand())
00147 return *this;
00148 return positionForBlack<WHITE>();
00149 }
00150 const Position flipHorizontal() const
00151 {
00152 if (isPieceStand())
00153 return *this;
00154 return Position(10-x(), y());
00155 }
00156
00157 static const Position onBoardMax(){ return Position(9,9); }
00158 static const Position onBoardMin(){ return Position(1,1); }
00159
00163 bool isOnBoardRegion() const {
00164 return static_cast<unsigned int>(index()-onBoardMin().index())
00165 <= static_cast<unsigned int>(onBoardMax().index()-onBoardMin().index());
00166 }
00167
00168 Position& operator++() {
00169 position += 1;
00170 return *this;
00171 }
00172
00173 static int reverseX(int x) { return 10-x; }
00174 static int reverseY(int y) { return 10-y; }
00175 private:
00176 template<Player P>
00177 static bool canPromoteY(int y,Int2Type<P>);
00178 static bool canPromoteY(int y,Int2Type<BLACK>)
00179 {
00180 return y <= 3;
00181 }
00182 static bool canPromoteY(int y,Int2Type<WHITE>)
00183 {
00184 return y >= 7;
00185 }
00186 bool canPromote(Int2Type<BLACK>) const{
00187 return (uintValue()&0xf)<=4;
00188 }
00189 bool canPromote(Int2Type<WHITE>) const{
00190 return (uintValue()&0x8)!=0;
00191 }
00192 public:
00193 template <Player P>
00194 static bool canPromoteY(int y) { return canPromoteY(y,Int2Type<P>()); }
00195 template <Player P>
00196 bool canPromote() const{
00197 return canPromote(Int2Type<P>());
00198 }
00199 bool canPromote(Player player) const
00200 {
00201 if (player==BLACK)
00202 return canPromote<BLACK>();
00203 else
00204 return canPromote<WHITE>();
00205 }
00210 bool isULRD(Position pos) const{
00211 assert(isOnBoard() && pos.isOnBoard());
00212 unsigned int v=uintValue() ^ pos.uintValue();
00213 return (((v+0xefull)^v)&0x110ull)!=0x110ull;
00214 }
00218 bool isUD(Position pos) const{
00219 assert(isOnBoard() && pos.isOnBoard());
00220 unsigned int v=uintValue() ^ pos.uintValue();
00221 return (v&0xf0)==0;
00222 }
00226 template<Player P>
00227 bool isU(Position pos) const{
00228 assert(isOnBoard() && pos.isOnBoard());
00229 unsigned int v=uintValue() ^ pos.uintValue();
00230 if(P==BLACK)
00231 return ((v|(uintValue()-pos.uintValue()))&0xf0)==0;
00232 else
00233 return ((v|(pos.uintValue()-uintValue()))&0xf0)==0;
00234 }
00238 bool isLR(Position pos) const{
00239 assert(isOnBoard() && pos.isOnBoard());
00240 unsigned int v=uintValue() ^ pos.uintValue();
00241 return (v&0xf)==0;
00242 }
00243 Position& operator+=(Offset offset) {
00244 position += offset.intValue();
00245 return *this;
00246 }
00247 Position& operator-=(Offset offset) {
00248 position -= offset.intValue();
00249 return *this;
00250 }
00251 const Position operator+(Offset offset) const {
00252 Position result(*this);
00253 return result+=offset;
00254 }
00255 const Position operator-(Offset offset) const {
00256 Position result(*this);
00257 return result-=offset;
00258 }
00259 const Offset operator-(Position other) const {
00260 return Offset::makeDirect(position - other.position);
00261 }
00262 template<int Y>
00263 bool yEq() {
00264 return (uintValue()&0xf)==(Y+1);
00265 }
00266 template<int Y>
00267 bool yLe(typename boost::enable_if_c<Y != 2>::type * =0) {
00268 return (uintValue()&0xf)<=(Y+1);
00269 }
00270 template<int Y>
00271 bool yLe(typename boost::enable_if_c<Y == 2>::type * =0) {
00272 return (uintValue()&0xc)==0;
00273 }
00274 template<int Y>
00275 bool yGe(typename boost::enable_if_c<Y!=7>::type * =0) {
00276 return (uintValue()&0xf)>=(Y+1);
00277 }
00278 template<int Y>
00279 bool yGe(typename boost::enable_if_c<Y==7>::type * =0) {
00280 return (uintValue()&0x8)!=0;
00281 }
00282 };
00283
00284 inline bool operator==(Position l, Position r)
00285 {
00286 return l.uintValue() == r.uintValue();
00287 }
00288 inline bool operator!=(Position l, Position r)
00289 {
00290 return ! (l == r);
00291 }
00292 inline bool operator<(Position l, Position r)
00293 {
00294 return l.uintValue() < r.uintValue();
00295 }
00296 inline bool operator>(Position l, Position r)
00297 {
00298 return l.uintValue() > r.uintValue();
00299 }
00300 std::ostream& operator<<(std::ostream&, Position);
00301
00302 }
00303
00304 #endif
00305
00306
00307
00308