Pattern.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "Pattern.hpp"
00007
00008 using namespace benzene;
00009
00010
00011
00012 Pattern::Pattern()
00013 : m_type(Pattern::UNKNOWN),
00014 m_name("unknown"),
00015 m_flags(0),
00016 m_weight(0)
00017 {
00018 memset(m_slice, 0, sizeof(m_slice));
00019 }
00020
00021
00022
00023 std::string Pattern::serialize() const
00024 {
00025 std::ostringstream os;
00026 os << m_type << ":";
00027 for (int s=0; s<NUM_SLICES; s++) {
00028 for (int a=0; a<NUM_FEATURES; a++) {
00029 if (a) os << ",";
00030 os << (int)m_slice[s][a];
00031 }
00032 os << ";";
00033 }
00034 return os.str();
00035 }
00036
00037 bool Pattern::unserialize(std::string code)
00038 {
00039 std::istringstream ss(code);
00040 char c;
00041 unsigned int i;
00042
00043 #ifndef NDEBUG
00044
00045 const unsigned int check = ~((1<<(MAX_EXTENSION*(MAX_EXTENSION+1)/2))-1);
00046 #endif
00047
00048 ss >> c;
00049 m_type = c;
00050
00051
00052 m_flags = 0;
00053 switch(m_type) {
00054 case MOHEX:
00055 case SHIFT:
00056 m_flags |= HAS_WEIGHT;
00057 break;
00058 }
00059
00060
00061 m_extension = 0;
00062 m_moves1.clear();
00063 m_moves2.clear();
00064 for (int s=0; s<Pattern::NUM_SLICES; s++) {
00065
00066
00067 for (int j = 0; j<Pattern::NUM_FEATURES; j++) {
00068 ss >> c;
00069 ss >> i;
00070 #ifndef NDEBUG
00071
00072 HexAssert((i & check)==0);
00073 #endif
00074 m_slice[s][j] = i;
00075 m_extension = std::max(m_extension,
00076 PatternUtil::GetExtensionFromGodel(i));
00077
00078
00079 if ((i != 0) && (j == FEATURE_MARKED1)) {
00080 m_flags |= HAS_MOVES1;
00081 for (int b=0; b<31; b++) {
00082 if (i & (1U << b)) {
00083 m_moves1.push_back(std::make_pair(s, b));
00084 }
00085 }
00086 }
00087
00088
00089 if ((i != 0) && (j == FEATURE_MARKED2)) {
00090 m_flags |= HAS_MOVES2;
00091 for (int b=0; b<31; b++) {
00092 if (i & (1U << b)) {
00093 m_moves2.push_back(std::make_pair(s, b));
00094 }
00095 }
00096 }
00097 }
00098
00099
00100 HexAssert(BitsetUtil::IsSubsetOf(m_slice[s][FEATURE_BLACK],
00101 m_slice[s][FEATURE_CELLS]));
00102 HexAssert(BitsetUtil::IsSubsetOf(m_slice[s][FEATURE_WHITE],
00103 m_slice[s][FEATURE_CELLS]));
00104 HexAssert(BitsetUtil::IsSubsetOf(m_slice[s][FEATURE_MARKED1],
00105 m_slice[s][FEATURE_CELLS]));
00106 HexAssert(BitsetUtil::IsSubsetOf(m_slice[s][FEATURE_MARKED2],
00107 m_slice[s][FEATURE_CELLS]));
00108
00109
00110 HexAssert((m_slice[s][FEATURE_BLACK] & m_slice[s][FEATURE_WHITE])==0);
00111 }
00112
00113 if (m_flags & HAS_WEIGHT) {
00114 ss >> c;
00115 ss >> i;
00116 m_weight = i;
00117 }
00118
00119 compute_ring_godel();
00120
00121 return true;
00122 }
00123
00124 void Pattern::flipColors()
00125 {
00126 for (int s=0; s<NUM_SLICES; s++) {
00127 std::swap(m_slice[s][Pattern::FEATURE_BLACK],
00128 m_slice[s][Pattern::FEATURE_WHITE]);
00129 }
00130 compute_ring_godel();
00131 }
00132
00133
00134
00135 void Pattern::mirror()
00136 {
00137 int data[32][32][Pattern::NUM_FEATURES];
00138 memset(data, 0, sizeof(data));
00139
00140
00141
00142 for (int s=0; s<NUM_SLICES; s++) {
00143 int fwd = s;
00144 int lft = (s + 2) % NUM_DIRECTIONS;
00145 int x1 = 10 + HexPointUtil::DeltaX(fwd);
00146 int y1 = 10 + HexPointUtil::DeltaY(fwd);
00147 for (int i=1, g=0; i<=Pattern::MAX_EXTENSION; i++) {
00148 int x2 = x1;
00149 int y2 = y1;
00150 for (int j=0; j<i; j++) {
00151 for (int k=0; k<Pattern::NUM_FEATURES; k++) {
00152 data[x2][y2][k] = ((1 << g) & m_slice[s][k]);
00153
00154 }
00155 x2 += HexPointUtil::DeltaX(lft);
00156 y2 += HexPointUtil::DeltaY(lft);
00157 g++;
00158 }
00159 x1 += HexPointUtil::DeltaX(fwd);
00160 y1 += HexPointUtil::DeltaY(fwd);
00161 }
00162 }
00163
00164
00165 m_moves1.clear();
00166 m_moves2.clear();
00167 memset(m_slice, 0, sizeof(m_slice));
00168 for (int s=0; s<NUM_SLICES; s++) {
00169 int fwd = s;
00170 int lft = (s + 2) % NUM_DIRECTIONS;
00171 int x1 = 10 + HexPointUtil::DeltaX(fwd);
00172 int y1 = 10 + HexPointUtil::DeltaY(fwd);
00173 for (int i=1, g=0; i<=Pattern::MAX_EXTENSION; i++) {
00174 int x2 = x1;
00175 int y2 = y1;
00176 for (int j=0; j<i; j++) {
00177 for (int k=0; k<Pattern::NUM_FEATURES; k++) {
00178 if (data[y2][x2][k]) {
00179 m_slice[s][k] ^= (1 << g);
00180 if (k == FEATURE_MARKED1) {
00181 m_moves1.push_back(std::make_pair(s, g));
00182 }
00183 if (k == FEATURE_MARKED2) {
00184 m_moves2.push_back(std::make_pair(s, g));
00185 }
00186 }
00187 }
00188 x2 += HexPointUtil::DeltaX(lft);
00189 y2 += HexPointUtil::DeltaY(lft);
00190 g++;
00191 }
00192 x1 += HexPointUtil::DeltaX(fwd);
00193 y1 += HexPointUtil::DeltaY(fwd);
00194 }
00195 }
00196
00197 compute_ring_godel();
00198 }
00199
00200
00201
00202 void Pattern::compute_ring_godel()
00203 {
00204 for (int i=0; i<NUM_SLICES; i++) {
00205 m_ring_godel[i].SetEmpty();
00206
00207 for (int s=0; s<NUM_SLICES; s++) {
00208 int j = (i+s)%NUM_SLICES;
00209
00210 if ((m_slice[j][FEATURE_CELLS] & 1) == 1) {
00211 m_ring_godel[i].AddSliceToMask(s);
00212
00213 HexColor color = EMPTY;
00214 if ((m_slice[j][FEATURE_BLACK] & 1) == 1)
00215 color = BLACK;
00216 else if ((m_slice[j][FEATURE_WHITE] & 1) == 1)
00217 color = WHITE;
00218
00219 m_ring_godel[i].SetSliceToColor(s, color);
00220 }
00221 }
00222 }
00223 }
00224
00225
00226
00227 void Pattern::LoadPatternsFromStream(std::istream& f,
00228 std::vector<Pattern>& out)
00229 {
00230 std::string name;
00231 bool found_name = false;
00232 bool mirror = false;
00233 while (true) {
00234 std::string line;
00235 if (!getline(f, line))
00236 break;
00237
00238 size_t a = line.find('[');
00239 if (a != std::string::npos) {
00240 if (!found_name) {
00241 size_t b = line.find('/');
00242 if (b != std::string::npos && b > a)
00243 name = line.substr(a+1,b-a-1);
00244 found_name = true;
00245 } else {
00246 mirror = true;
00247 }
00248 }
00249
00250 if (line[0] == Pattern::DEAD ||
00251 line[0] == Pattern::CAPTURED ||
00252 line[0] == Pattern::PERMANENTLY_INFERIOR ||
00253 line[0] == Pattern::MUTUAL_FILLIN ||
00254 line[0] == Pattern::VULNERABLE ||
00255 line[0] == Pattern::REVERSIBLE ||
00256 line[0] == Pattern::DOMINATED ||
00257 line[0] == Pattern::MOHEX ||
00258 line[0] == Pattern::SHIFT)
00259 {
00260 Pattern p;
00261 if (p.unserialize(line)) {
00262 p.setName(name);
00263 out.push_back(p);
00264
00265 if (mirror) {
00266 p.mirror();
00267 p.setName(name + "m");
00268 out.push_back(p);
00269 }
00270 }
00271 found_name = false;
00272 mirror = false;
00273 }
00274 }
00275 }
00276
00277 void Pattern::LoadPatternsFromFile(const char* filename,
00278 std::vector<Pattern>& out)
00279 {
00280 std::ifstream f(filename);
00281 if (!f) {
00282 LogWarning()
00283 << "Could not open file for reading: '" << filename << "'"
00284 << '\n';
00285 }
00286 else {
00287 LoadPatternsFromStream(f, out);
00288 }
00289 }
00290
00291
00292
00293 int PatternUtil::GetExtensionFromGodel(int godel)
00294 {
00295 for (int r=1; r<=Pattern::MAX_EXTENSION; r++) {
00296 int mask = ~((1<<(r*(r+1)/2))-1);
00297 if ((godel & mask) == 0) {
00298 return r;
00299 }
00300 }
00301 HexAssert(false);
00302 return Pattern::MAX_EXTENSION;
00303 }
00304
00305