square.h
Go to the documentation of this file.
00001 /* square.h
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 } // namespace osl
00314 
00315 #endif /* OSL_POSITION_H */
00316 // ;;; Local Variables:
00317 // ;;; mode:c++
00318 // ;;; c-basic-offset:2
00319 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines