Go to the documentation of this file.00001
00002
00003 #ifndef OSL_BOARDMASK_H
00004 #define OSL_BOARDMASK_H
00005
00006 #include "osl/square.h"
00007 #include "osl/directionTraits.h"
00008 #include "osl/misc/carray.h"
00009 #include "osl/misc/cstdint.h"
00010 #include "osl/misc/bitOp.h"
00011 #include <iosfwd>
00012
00013 namespace osl
00014 {
00015 namespace container
00016 {
00017 class BoardMask;
00018 bool operator==(const BoardMask&, const BoardMask&);
00019 std::ostream& operator<<(std::ostream&, const BoardMask&);
00021 class BoardMask
00022 {
00024 CArray<unsigned long long,3> contents;
00025 public:
00026 BoardMask() { invalidate(); }
00027 BoardMask(const BoardMask& src) {
00028 contents[0] = src.contents[0];
00029 contents[1] = src.contents[1];
00030 }
00031 BoardMask& operator=(const BoardMask& src) {
00032 if (this != &src) {
00033 contents[0] = src.contents[0];
00034 contents[1] = src.contents[1];
00035 }
00036 return *this;
00037 }
00038 void clear() { contents[0]=contents[1]=0; }
00039 void invalidate() { contents[0] = static_cast<uint64_t>(-1); }
00040 bool isInvalid() const { return contents[0] == static_cast<uint64_t>(-1); }
00041 void set(unsigned int i) {
00042 int j=(i>>6);
00043 contents[j]|=(1ull<<(i&63));
00044 }
00045 void set(Square pos) {
00046 set(index(pos));
00047 }
00048 void reset(unsigned int i) {
00049 int j=(i>>6);
00050 contents[j] &= ~(1ull<<(i&63));
00051 }
00052 void reset(Square pos) { reset(index(pos)); }
00053 bool test(unsigned int i) const {
00054 int j=(i>>6);
00055 return (contents[j]&(1ull<<(i&63)))!=0;
00056 }
00057 bool test(Square pos) const { return test(index(pos)); }
00058 bool anyInRange(const BoardMask& mask) const
00059 {
00060 return (contents[0] & mask.contents[0])
00061 || (contents[1] & mask.contents[1]);
00062 }
00063 BoardMask& operator|=(const BoardMask& mask)
00064 {
00065 contents[0] |= mask.contents[0];
00066 contents[1] |= mask.contents[1];
00067 return *this;
00068 }
00069 bool any() const
00070 {
00071 assert(! isInvalid());
00072 return contents[0] || contents[1];
00073 }
00074 Square takeOneBit()
00075 {
00076 assert(! isInvalid() && any());
00077 if (contents[0])
00078 return toSquare(misc::BitOp::takeOneBit(contents[0]));
00079 return toSquare(misc::BitOp::takeOneBit(contents[1])+64);
00080 }
00081 static int index(int x,int y){ return x*12+y+1; }
00082 static int index(Square pos) {
00083 int v=pos.index();
00084 return v-((v>>2)&0x3c);
00085 }
00086 template<Direction Dir,Player P>
00087 static int getIndexOffset() {
00088 int blackDx=DirectionTraitsGen<Dir>::blackDx;
00089 int blackDy=DirectionTraitsGen<Dir>::blackDy;
00090 int val=blackDx*12+blackDy;
00091 if(P==BLACK) return val;
00092 else return -val;
00093 }
00094 static Square toSquare(int n) { return Square::makeDirect(n+(((n*21)>>8)<<2)); }
00095 friend bool operator==(const BoardMask&, const BoardMask&);
00096 };
00097 inline const BoardMask operator|(const BoardMask& l, const BoardMask& r)
00098 {
00099 BoardMask result = l;
00100 result |= r;
00101 return result;
00102 }
00103 inline bool operator==(const BoardMask& l, const BoardMask& r)
00104 {
00105 return l.contents[0] == r.contents[0]
00106 && l.contents[1] == r.contents[1];
00107 }
00108 class BoardMaskTable5x5
00109 {
00110 CArray<BoardMask, Square::SIZE> data;
00111 public:
00112 BoardMaskTable5x5();
00114 const BoardMask& mask(Square p) const { return data[p.index()]; }
00115 };
00116 extern const BoardMaskTable5x5 Board_Mask_Table5x5;
00117
00118 class BoardMaskTable3x3
00119 {
00120 CArray<BoardMask, Square::SIZE> data;
00121 public:
00122 BoardMaskTable3x3();
00124 const BoardMask& mask(Square p) const { return data[p.index()]; }
00125 };
00126 extern const BoardMaskTable3x3 Board_Mask_Table3x3;
00127
00128 class BoardMaskTable5x3Center
00129 {
00130 CArray<BoardMask, Square::SIZE> data;
00131 public:
00132 BoardMaskTable5x3Center();
00134 const BoardMask& mask(Square p) const { return data[p.index()]; }
00135 };
00136 extern const BoardMaskTable5x3Center Board_Mask_Table5x3_Center;
00137 }
00138 using container::BoardMask;
00139 using container::Board_Mask_Table5x5;
00140 using container::Board_Mask_Table5x3_Center;
00141 using container::Board_Mask_Table3x3;
00142 }
00143
00144
00145 #endif
00146
00147
00148
00149