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