Changeset 242 for 06/libkombilo-branches

Show
Ignore:
Timestamp:
03/18/07 23:37:15 (22 months ago)
Author:
ug
Message:

Hashing for center position works now. Further testing is required.
Processing is still too slow at the moment.

Location:
06/libkombilo-branches/hash_center
Files:
2 added
4 modified

Legend:

Unmodified
Added
Removed
  • 06/libkombilo-branches/hash_center/cpptest.cpp

    r241 r242  
    3131    // string path = "/home/ug/go/kombilo/06/hash_center"; 
    3232    // string path = "/home/ug/go/gtl/reviews"; 
    33     string path = "/home/ug/go/gogod06/2000"; 
     33    string path = "/home/ug/go/gogod06/2001"; 
    3434    int counter = 0; 
    3535    for(directory_iterator it(path); it != end_itr; ++it) { 
     
    7171  // Pattern p(2,3,4,6, 19, 3, 3, ".X.XXXXOX", vector<MoveNC>());  
    7272 
    73 //   Pattern p(CORNER_NW_PATTERN,19,8,8, 
     73//   Pattern p(CORNER_NW_PATTERN,19,8,7, 
    7474//                 "........" 
    7575//                 "........" 
    76 //                 "...X...." 
    77 //                 "........" 
     76//                 "..X....." 
    7877//                 "...O...." 
    7978//                 "........" 
    8079//                 "........" 
     80//                 "........" 
    8181//                 "........"); 
    82   Pattern p(CORNER_NW_PATTERN,19,7,8, 
    83             "......." 
    84             "......." 
    85             "...O..." 
    86             "......." 
    87             "......." 
    88             "......." 
    89             "......." 
    90             "......."); 
     82//   Pattern p(CENTER_PATTERN,19,5,4, 
     83//             "...O." 
     84//             "....." 
     85//             ".XOO." 
     86//             "..OXO"); 
     87  Pattern p(CENTER_PATTERN, 19,5, 4, 
     88            "..XOO" 
     89            "...XX" 
     90            "....." 
     91            "..X.."); 
     92 
    9193  // Pattern p(CORNER_NW_PATTERN,19,7,7,".................X.....X......XO.....OO.........."); 
    9294  // Pattern p(CORNER_NW_PATTERN,19,7,7,".......................X........................."); 
     
    120122  // for(vector<string>::iterator it = res.begin(); it != res.end(); it++) 
    121123  //   printf("%s\n", it->c_str()); 
    122 //   for(int i=0; i<gl.size(); i++) printf("%s\n", gl.currentEntryAsString(i).c_str()); 
     124  for(int i=0; i<gl.size(); i++) printf("%s\n", gl.currentEntryAsString(i).c_str()); 
    123125 
    124126  // ------------------- print some statistics ------------------------------------------ 
  • 06/libkombilo-branches/hash_center/process.py

    r241 r242  
    3131    counter = 0 
    3232    for filename in filenames: 
    33         # print filename 
     33        print counter 
    3434        try: 
    3535            file = open(filename) 
  • 06/libkombilo-branches/hash_center/search.cpp

    r241 r242  
    418418} 
    419419 
    420 Pattern& Pattern::apply_flip(int f, bool CS) { 
     420Pattern Pattern::apply_flip(int f, bool CS) { 
    421421  int newSizeX = max(Pattern::flipsX(f,0,0,sizeX,sizeY), 
    422422      Pattern::flipsX(f,sizeX,sizeY,sizeX,sizeY)); 
     
    468468  } 
    469469 
    470   Pattern* pNew =new Pattern(newLeft, newRight, newTop, newBottom, boardsize, 
    471                              newSizeX, newSizeY, newInitialPos, newContList); 
    472  
    473   pNew->flip = f; 
    474   if (CS) pNew->colorSwitch = 1; 
    475   else pNew->colorSwitch = 0; 
     470  Pattern pNew(newLeft, newRight, newTop, newBottom, boardsize, 
     471               newSizeX, newSizeY, newInitialPos, newContList); 
     472 
     473  pNew.flip = f; 
     474  if (CS) pNew.colorSwitch = 1; 
     475  else pNew.colorSwitch = 0; 
    476476  delete [] newInitialPos; 
    477   return *pNew;  
     477  return pNew; 
    478478} 
    479479 
     
    602602    } 
    603603    if (foundNewPattern) { 
    604       printf("new p: %s\n", pNew.printPattern().c_str()); 
     604//       printf("new p: %s\n", pNew.printPattern().c_str()); 
    605605      flipTable[f] = data.size(); 
    606606      data.push_back(pNew); 
     
    10541054  int rc = sqlite3_exec(db, sql, 0, 0, 0); 
    10551055  if (rc != SQLITE_OK) { 
    1056     printf("error %d\n", rc); 
     1056//     printf("error %d\n", rc); 
    10571057    throw DBError(); 
    10581058  } 
     
    17231723                numOfSwitched += label[2]; 
    17241724                result->push_back(new Hit(new ExtendedMoveNumber((*it)->dictsF), label)); 
     1725//                 printf("hit from %d %d %d\n", (*it)->mx, (*it)->my, (*it)->orientation); 
    17251726              } 
    17261727 
     
    21902191 
    21912192HashhitF::HashhitF() { 
    2192   printf("oops\n"); 
     2193//   printf("oops\n"); 
    21932194  cont = 0; 
    21942195  emn = 0; 
     
    25752576} 
    25762577 
    2577 HashQuery::HashQuery(std::string SQL, Pattern* p0, int OFF0X, int OFF0Y, int FLIP0, hashtype HASHCODE0, Pattern* p1, int FLIP1) { 
     2578HashQuery::HashQuery(std::string SQL, PatternList* PL0, int OFF0X, int OFF0Y, int FLIP0, hashtype HASHCODE0,  
     2579                     PatternList* PL1, int OFF1X, int OFF1Y, int FLIP1) { 
    25782580  sql = SQL; 
    2579   if (p0) { 
    2580     printf("use \n%s\n", p0->printPattern().c_str()); 
    2581     pl0 = new PatternList(*p0,1,0); 
    2582     printf("pl size %d\n", pl0->size()); 
    2583     offset0 = OFF0X + p0->sizeX * OFF0Y; 
    2584     delete p0; 
     2581  if (PL0) { 
     2582    pl0 = PL0; 
     2583//     printf("pl size %d\n", pl0->size()); 
     2584    offset0 = OFF0X + pl0->data[0].sizeX * OFF0Y; 
    25852585  } else { 
    25862586    pl0 = 0; 
    25872587    offset0 = 0; 
    25882588  } 
    2589   if (p1) { 
    2590     pl1 = new PatternList(*p1,1,0); 
    2591     delete p1; 
     2589  if (PL1) { 
     2590    pl1 = PL1; 
    25922591  } else { 
    25932592    pl1 = 0; 
     2593    offset1 = OFF1X + pl1->data[0].sizeX * OFF1Y; 
    25942594  } 
    25952595  flip0 = FLIP0; 
     
    28122812  // printf("leave algo_hash::initialize_processing\n"); 
    28132813} 
    2814          
     2814 
    28152815void Algo_hash::newgame_process(int game_id) { 
    28162816  gid = game_id; 
     
    28212821void Algo_hash::AB_process(int x, int y) { 
    28222822  for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
    2823     (*it)->addB(x,y); 
     2823    (*it)->add('B', x, y); 
    28242824} 
    28252825 
    28262826void Algo_hash::AW_process(int x, int y) { 
    28272827  for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
    2828     (*it)->addW(x,y); 
    2829 }                  
     2828    (*it)->add('W', x, y); 
     2829} 
    28302830 
    28312831void Algo_hash::AE_process(int x, int y, char removed) { 
    2832   if (removed == 'B') { 
    2833     for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) (*it)->removeB(x,y); 
    2834   } else {  
    2835     for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) (*it)->removeW(x,y); 
    2836   } 
     2832  for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) (*it)->remove(removed, x, y); 
    28372833} 
    28382834 
     
    28532849 
    28542850void Algo_hash::move_process(Move m) throw(DBError) { 
    2855   if (m.color == 'B') { 
    2856     for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
    2857       (*it)->addB(m.x, m.y); 
    2858     if (m.captures) { 
    2859       for(vector<p_cc>::iterator cap_it = m.captures->begin(); cap_it != m.captures->end(); cap_it++) { 
    2860         for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
    2861           (*it)->removeW(cap_it->first, cap_it->second); 
    2862       } 
    2863     } 
    2864   } else { 
    2865     for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
    2866       (*it)->addW(m.x, m.y); 
    2867     if (m.captures) { 
    2868       for(vector<p_cc>::iterator cap_it = m.captures->begin(); cap_it != m.captures->end(); cap_it++) { 
    2869         for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
    2870           (*it)->removeB(cap_it->first, cap_it->second); 
    2871       } 
     2851  for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
     2852    (*it)->add(m.color, m.x, m.y); 
     2853  if (m.captures) { 
     2854    for(vector<p_cc>::iterator cap_it = m.captures->begin(); cap_it != m.captures->end(); cap_it++) { 
     2855      for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) 
     2856        (*it)->remove(invertColor(m.color), cap_it->first, cap_it->second); 
    28722857    } 
    28732858  } 
     
    29452930  vector<int>* result = new vector<int>; 
    29462931  bool used[8]; 
    2947   printf("pft "); for(int i=0; i<8; i++) printf("%d, ", pattern_ft[i]); printf("\n"); 
    2948   printf("sft "); 
    2949   for(int i=0; i<8; i++) 
    2950     printf("%d, ", subpattern_ft[i]); 
    2951   printf("\n"); 
     2932//   printf("pft "); for(int i=0; i<8; i++) printf("%d, ", pattern_ft[i]); printf("\n"); 
     2933//   printf("sft "); 
     2934//   for(int i=0; i<8; i++) 
     2935//     printf("%d, ", subpattern_ft[i]); 
     2936//   printf("\n"); 
    29522937  { for(int i=0; i<8; i++) used[i] = false; 
    29532938  } 
     
    29752960  if (gl.start_sorted() == 0) { 
    29762961    // query database 
    2977     printf("sql query: %s\n", query.sql.c_str()); 
     2962//     printf("sql query: %s\n", query.sql.c_str()); 
    29782963    sqlite3_stmt* selStmt = 0; 
    29792964    int rc = sqlite3_prepare(db, query.sql.c_str(), -1, &selStmt, 0); 
     
    29872972    rc = sqlite3_finalize(selStmt); 
    29882973    if (rc != SQLITE_OK) printf("SQLITE errorB %d\n", rc); 
    2989     printf("%d results\n", results->data.size()); 
     2974//     printf("%d results\n", results->data.size()); 
    29902975 
    29912976    // communicate results of query to database 
     
    30122997        if ((*resultIT)->cs) { 
    30132998           subpattern_flipTable = query.pl1->flipTable; 
    3014            fl = query.flip1; 
     2999           fl = Pattern::PatternInvFlip(query.flip1); 
    30153000           subp_sizeX = query.pl1->pattern.sizeX; 
    30163001           subp_sizeY = query.pl1->pattern.sizeY; 
    30173002        } else { 
    30183003          subpattern_flipTable = query.pl0->flipTable; 
    3019           fl = query.flip0; 
     3004          fl = Pattern::PatternInvFlip(query.flip0); 
    30203005          subp_sizeX = query.pl0->pattern.sizeX; 
    30213006          subp_sizeY = query.pl0->pattern.sizeY; 
     
    30373022          if (!(*resultIT)->cs) index = patternList.flipTable[*flip]; 
    30383023          else index = patternList.flipTable[*flip + 8]; 
    3039 //           printf("make cand %d, %d, %d\n", pos_left, pos_top, index); 
     3024//           printf("%d %d %d %d make cand %d, %d, %d\n", pos, ori, fl, *flip, pos_left, pos_top, index); 
    30403025          candidates->push_back(new Candidate(pos_left, pos_top, index)); 
    30413026        } 
     
    30903075          char p = pattern->finalPos[i + pattern->sizeX*j]; 
    30913076          if (p == 'x' || p ==  'o' || p == '*') { 
    3092             printf("c_h 0a\n"); 
     3077//             printf("c_h 0a\n"); 
    30933078            return CompleteHashKey(); 
    30943079          } 
     
    31273112 
    31283113HashQuery Algo_hash_corner::searchQuery(PatternList& patternList) { 
    3129   printf("Enter Algo_hash_corner::search\n"); 
     3114//   printf("Enter Algo_hash_corner::searchQuery\n"); 
    31303115  if (patternList.data[0].sizeX < size ||\ 
    31313116      patternList.data[0].sizeY < size ||\ 
     
    31343119      (patternList.data[0].left != 0 && patternList.data[0].left != boardsize-size) ||\ 
    31353120      (patternList.data[0].top != 0 && patternList.data[0].top != boardsize-size)) { 
    3136     printf("c_h 0\n"); 
     3121//     printf("c_h 0\n"); 
    31373122    return HashQuery(); 
    31383123  } 
     
    31453130 
    31463131  Pattern subp = pattern->subpattern(offsetX, offsetY, size, size); 
    3147   PatternList sub_pl(subp, 0, 0); 
    3148   CompleteHashKey chk0 = compute_hashkey(sub_pl, 0); 
     3132  PatternList* sub_pl = new PatternList(subp, 0, 0); 
     3133  CompleteHashKey chk0 = compute_hashkey(*sub_pl, 0); 
    31493134  if (chk0.hashCode == NOT_HASHABLE) { 
    3150     printf("0 NH\n"); 
     3135//     printf("0 NH\n"); 
    31513136    return HashQuery(); 
    31523137  } 
    3153   int fl = patternList.data[chk0.index].flip; 
    3154  
    3155   char buf[100]; 
    3156   sprintf(buf, "select data,hash from algo_hash_%d_%s where hash ", 
    3157       boardsize, dbnameext.c_str()); 
     3138  int fl = sub_pl->data[chk0.index].flip; 
     3139 
     3140  char buf[200]; 
     3141  sprintf(buf, "select data,hash from algo_hash_%d_%s where hash ", boardsize, dbnameext.c_str()); 
    31583142  string sql = buf; 
    3159   Pattern* p0 = new Pattern(sub_pl.data[0]); 
    3160  
     3143 
     3144  PatternList* sub_pl1; 
    31613145  int fl2 = fl; 
    3162   Pattern* p1 = 0; 
    31633146  if (patternList.data[patternList.size()-1].colorSwitch) { 
    3164     CompleteHashKey chk1 = compute_hashkey(sub_pl, 1); 
     3147    CompleteHashKey chk1 = compute_hashkey(*sub_pl, 1); 
    31653148    // printf("HC2 %lld\n", hashCode2); 
    31663149    if (chk1.hashCode == NOT_HASHABLE) { 
    3167       printf("1 NH\n"); 
     3150//       printf("1 NH\n"); 
    31683151      return HashQuery(); 
    31693152    } 
     
    31733156      sprintf(buf, "in ('%lld', '%lld')", chk0.hashCode, chk1.hashCode); 
    31743157      sql += buf; 
    3175       p1 = new Pattern(sub_pl.data[sub_pl.size()/2]); 
     3158      sub_pl1 = new PatternList(sub_pl->data[sub_pl->size()/2], 1, 0); 
    31763159    } else { 
    31773160      sprintf(buf, "= '%lld'", chk0.hashCode); 
     
    31823165    sql += buf; 
    31833166  } 
    3184   return HashQuery(sql, p0, offsetX, offsetY, fl, chk0.hashCode, p1, fl2); 
     3167  return HashQuery(sql, sub_pl, offsetX, offsetY, fl, chk0.hashCode, sub_pl1, offsetX, offsetY, fl2); 
    31853168} 
    31863169 
     
    32053188 
    32063189 
    3207 Algo_hash_center::Algo_hash_center(int bsize) : Algo_hash(bsize, "CENTER", 16) { 
     3190Algo_hash_center::Algo_hash_center(int bsize, int L_BOUND, int U_BOUND) : Algo_hash(bsize, "CENTER", 16) { 
     3191  l_bound = L_BOUND; 
     3192  u_bound = U_BOUND; 
    32083193  // read "frequency" table from kombilo.db 
    32093194  sqlite3* kombilodb = 0; 
     
    32253210  rc = sqlite3_close(kombilodb); 
    32263211  if (rc != SQLITE_OK) printf("SQLITE errorD %d\n", rc); 
    3227 } 
    3228          
     3212  sizeX = 4; 
     3213  sizeY = 4; 
     3214} 
     3215 
    32293216void Algo_hash_center::endOfNode_process() { 
    32303217  for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) { 
     
    32333220      pair<hashtype,int> phi = (*it)->cHC(); 
    32343221      map<hashtype, int>::iterator freq_it = frequency.find(phi.first); 
    3235       if (freq_it != frequency.end() && freq_it->second > 100 && freq_it->second < 1000)  
     3222      if (freq_it != frequency.end() && freq_it->second > l_bound && freq_it->second < u_bound)  
    32363223        if (insert_hash(phi.first, phi.second) != 0) throw DBError(); 
    32373224    } 
     
    32423229  Algo_hash::initialize_process(DB); 
    32433230  hi = new vector<HashInstance* >; 
    3244   for(int i=0; i<boardsize-3; i++)          // FIXME: boundaries 
    3245     for(int j=0; j<boardsize-3; j++) 
    3246       hi->push_back(new HashInstanceCTR(i, j, 4, 4, boardsize)); 
    3247 } 
    3248  
    3249 hashtype center_hashkey(char* p, int sizeX, int start) { 
    3250   // computes the hash key of the 4x4 pattern in p 
    3251   hashtype currentHashCode[8]; 
    3252   for(int f=0; f<8; f++) { 
    3253     for(int x=0; x<4; x++) { 
    3254       for(int y=0; y<4; y++) { 
    3255         char x1 = Pattern::flipsX(f, x, y, 3, 3); 
    3256         char y1 = Pattern::flipsY(f, x, y, 3, 3); 
    3257         char c = p[start + x1*sizeX + y1]; 
    3258         // stone at position (x1, y1) at bits 4*x1+yy1 4*x1+y1+1 
    3259         int p = 2*(4*x1+y1); 
    3260         if (c=='X') 
    3261           currentHashCode[f] |= 1 << p; // set to 01 = black 
    3262         else if (c == 'W') 
    3263           currentHashCode[f] |= 1 << (p+1); // set to 10 = white 
    3264         else if (c != '.') return NOT_HASHABLE; 
     3231  for(int i=0; i<boardsize-sizeX+1; i++)          // FIXME: boundaries 
     3232    for(int j=0; j<boardsize-sizeY+1; j++) 
     3233      hi->push_back(new HashInstanceCTR(i, j, sizeX, sizeY, boardsize)); 
     3234} 
     3235 
     3236HashQuery Algo_hash_center::searchQuery(PatternList& patternList) { 
     3237//   printf("Enter Algo_hash_center::search\n"); 
     3238  Pattern* pattern = &(patternList.data[0]); 
     3239  int offsetX = 0; 
     3240  int offsetY = 0; 
     3241  int fl = 0; 
     3242  int freq = 1000000; 
     3243  hashtype hashCode = NOT_HASHABLE; 
     3244  PatternList* sub_pl = 0; 
     3245  PatternList* pl0 = 0; 
     3246  for(int oX = 0; oX <= pattern->sizeX - sizeX; oX++) { 
     3247    for(int oY = 0; oY <= pattern->sizeY - sizeY; oY++) { 
     3248      Pattern* subp = &pattern->subpattern(oX, oY, sizeX, sizeY); 
     3249      sub_pl = new PatternList(*subp, 1, 0); 
     3250      CompleteHashKey hc = HashInstanceCTR::center_hashkey(*sub_pl, 0); 
     3251      map<hashtype, int>::iterator f_it = frequency.find(hc.hashCode); 
     3252      if (hc.hashCode != NOT_HASHABLE && f_it != frequency.end() && f_it->second > l_bound && f_it->second < u_bound && f_it->second < freq) { 
     3253        hashCode = hc.hashCode; 
     3254        freq = f_it->second; 
     3255        offsetX = oX; 
     3256        offsetY = oY; 
     3257        if (pl0) delete pl0; 
     3258        pl0 = sub_pl; 
     3259        fl = sub_pl->data[hc.index].flip; 
     3260      } else { 
     3261        delete sub_pl; 
    32653262      } 
    3266     } 
    3267   } 
    3268   hashtype minCHC = currentHashCode[0]; 
    3269   for(int f=1; f<8; f++) {  
    3270     if (currentHashCode[f] < minCHC) { 
    3271       minCHC = currentHashCode[f]; 
    3272     } 
    3273   } 
    3274   return minCHC; 
    3275 } 
    3276  
    3277 CompleteHashKey Algo_hash_center::compute_hashkey(PatternList& pl, int CS) { 
    3278   if (pl.pattern.sizeX < 4 || pl.pattern.sizeY < 4 || 
    3279       (pl.pattern.sizeX < 5 && (pl.pattern.left == 0 || pl.pattern.right == boardsize-1)) || 
    3280       (pl.pattern.sizeY < 5 && (pl.pattern.top == 0 || pl.pattern.bottom == boardsize-1))) 
    3281     return CompleteHashKey(); // NOT_HASHABLE 
    3282  
    3283   // go through all center 4x4 sub-patterns, and compute the corresp. hash key 
    3284  
    3285   int X1 = 0; 
    3286   int Y1 = 0; 
    3287   int X2 = pl.pattern.sizeX - 4; 
    3288   int Y2 = pl.pattern.sizeY - 4; 
    3289  
    3290   // if (pl.pattern.left == 0) X1++; 
    3291   // if (pl.pattern.top == 0) Y1++; 
    3292   // if (pl.pattern.right == boardsize - pl.pattern.sizeX) X2--; 
    3293   // if (pl.pattern.bottom == boardsize - pl.pattern.sizeY) Y2--; 
    3294    
    3295   // 
    3296   return CompleteHashKey(); // NOT_HASHABLE 
    3297 } 
    3298  
    3299 HashQuery Algo_hash_center::searchQuery(PatternList& patternList) { 
    3300   return HashQuery(); 
     3263      delete subp; 
     3264    } 
     3265  } 
     3266 
     3267  if (hashCode == NOT_HASHABLE) { 
     3268    return HashQuery(); 
     3269  } 
     3270 
     3271  char buf[200]; 
     3272  sprintf(buf, "select data,hash from algo_hash_%d_%s where hash ", boardsize, dbnameext.c_str()); 
     3273  string sql = buf; 
     3274 
     3275  int offsetX1 = 0; 
     3276  int offsetY1 = 0; 
     3277  freq = 1000000; 
     3278  hashtype hashCode1 = NOT_HASHABLE; 
     3279  PatternList* sub_pl1; 
     3280  PatternList* pl1 = 0; 
     3281 
     3282  int fl1 = fl; 
     3283  if (patternList.data[patternList.size()-1].colorSwitch) { 
     3284    for(int oX = 0; oX <= pattern->sizeX - sizeX; oX++) { 
     3285      for(int oY = 0; oY <= pattern->sizeY - sizeY; oY++) { 
     3286        Pattern* subp = &patternList.data[patternList.size()/2].subpattern(oX, oY, sizeX, sizeY); 
     3287        sub_pl1 = new PatternList(*subp, 0, 0); 
     3288        CompleteHashKey hc = HashInstanceCTR::center_hashkey(*sub_pl1, 0); 
     3289        map<hashtype, int>::iterator f_it = frequency.find(hc.hashCode); 
     3290        if (hc.hashCode != NOT_HASHABLE && f_it != frequency.end() && f_it->second > l_bound && f_it->second < u_bound && f_it->second < freq) { 
     3291          hashCode1 = hc.hashCode; 
     3292          freq = f_it->second; 
     3293          offsetX1 = oX; 
     3294          offsetY1 = oY; 
     3295          if (pl1) delete pl1; 
     3296          pl1 = sub_pl1; 
     3297          fl1 = sub_pl1->data[hc.index].flip; 
     3298        } else { 
     3299          delete sub_pl1; 
     3300        } 
     3301        delete subp; 
     3302      } 
     3303    } 
     3304 
     3305    if (hashCode1 == NOT_HASHABLE) { 
     3306//       printf("1 NH\n"); 
     3307      return HashQuery(); 
     3308    } 
     3309 
     3310    if (hashCode != hashCode1) { 
     3311      sprintf(buf, "in ('%lld', '%lld')", hashCode, hashCode1); 
     3312      sql += buf; 
     3313    } else { 
     3314      sprintf(buf, "= '%lld'", hashCode); 
     3315      sql += buf; 
     3316    } 
     3317  } else { 
     3318    sprintf(buf, "= '%lld'", hashCode); 
     3319    sql += buf; 
     3320  } 
     3321  return HashQuery(sql, pl0, offsetX, offsetY, fl, hashCode, pl1, offsetX1, offsetY1, fl1); 
    33013322} 
    33023323 
     
    33473368} 
    33483369 
    3349 void HashInstance::addB(char x, char y) { printf("ouch\n"); } 
    3350  
    3351 void HashInstance::addW(char x, char y) { } 
    3352  
    3353 void HashInstance::removeB(char x, char y) { } 
    3354  
    3355 void HashInstance::removeW(char x, char y) { } 
     3370void HashInstance::add(char co, char x, char y) { printf("ouch\n"); } 
     3371 
     3372void HashInstance::remove(char co, char x, char y) { } 
    33563373 
    33573374pair<hashtype,int> HashInstance::cHC() { 
     
    33873404} 
    33883405 
    3389 void HashInstanceCO::addB(char x, char y) { 
     3406void HashInstanceCO::add(char co, char x, char y) { 
    33903407  if (inRelevantRegion(x,y)) { 
    33913408    changed = true; 
    33923409    for(int i=0; i<8; i++) { 
    3393       currentHashCode[i] += Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     3410      if (co == 'X' || co =='B') 
     3411        currentHashCode[i] += Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     3412      else if (co == 'O' || co == 'W') 
     3413        currentHashCode[i] -= Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     3414      else printf("ouch\n"); // FIXME 
    33943415    } 
    33953416    numStones++; 
     
    33973418} 
    33983419 
    3399 void HashInstanceCO::addW(char x, char y) { 
     3420void HashInstanceCO::remove(char co, char x, char y) { 
    34003421  if (inRelevantRegion(x,y)) { 
    34013422    changed = true; 
    34023423    for(int i=0; i<8; i++) { 
    3403       currentHashCode[i] -= Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     3424      if (co == 'X' || co =='B') 
     3425        currentHashCode[i] -= Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     3426      else if (co == 'O' || co == 'W') 
     3427        currentHashCode[i] += Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     3428      else printf("ouch\n"); // FIXME 
    34043429    } 
    34053430    numStones++; 
     
    34073432} 
    34083433 
    3409 void HashInstanceCO::removeB(char x, char y) { 
     3434HashInstanceCTR::HashInstanceCTR(char X, char Y, char SIZEX, char SIZEY, int BOARDSIZE) : HashInstance(X, Y, SIZEX, SIZEY, BOARDSIZE) { 
     3435  if (sizeX != 4 || sizeY != 4) printf("error\n"); // FIXME 
     3436} 
     3437 
     3438HashInstanceCTR::~HashInstanceCTR() { 
     3439  finalize(); 
     3440} 
     3441 
     3442void HashInstanceCTR::add(char co, char x, char y) { 
    34103443  if (inRelevantRegion(x,y)) { 
    34113444    changed = true; 
    34123445    for(int i=0; i<8; i++) { 
    3413       currentHashCode[i] -= Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
    3414     } 
    3415     numStones++; 
    3416   } 
    3417 } 
    3418  
    3419 void HashInstanceCO::removeW(char x, char y) { 
    3420   if (inRelevantRegion(x,y)) { 
    3421     changed = true; 
    3422     for(int i=0; i<8; i++) { 
    3423       currentHashCode[i] += Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
    3424     } 
    3425     numStones++; 
    3426   } 
    3427 } 
    3428  
    3429  
    3430 HashInstanceCTR::HashInstanceCTR(char X, char Y, char SIZEX, char SIZEY, int BOARDSIZE) : HashInstance(X, Y, SIZEX, SIZEY, BOARDSIZE) { 
    3431 } 
    3432  
    3433 HashInstanceCTR::~HashInstanceCTR() { 
    3434   finalize(); 
    3435 } 
    3436  
    3437 void HashInstanceCTR::addB(char x, char y) { 
    3438   if (inRelevantRegion(x,y)) { 
    3439     changed = true; 
    3440     for(int i=0; i<8; i++) { 
     3446//       char x1 = Pattern::flipsX(Pattern::PatternInvFlip(i), x-xx, y-yy, 3, 3); 
     3447//       char y1 = Pattern::flipsY(Pattern::PatternInvFlip(i), x-xx, y-yy, 3, 3); 
    34413448      char x1 = Pattern::flipsX(i, x-xx, y-yy, 3, 3); 
    34423449      char y1 = Pattern::flipsY(i, x-xx, y-yy, 3, 3); 
     
    34443451      int p = 2*(4*x1+y1); 
    34453452      currentHashCode[i] ^= ((currentHashCode[i] >> p)%4) << p; // set to 00 
    3446       currentHashCode[i] |= 1 << p; // set to 01 = black 
    3447     } 
    3448   } 
    3449 } 
    3450  
    3451 void HashInstanceCTR::addW(char x, char y) { 
     3453      if (co == 'X' || co == 'B') 
     3454        currentHashCode[i] |= 1 << p; // set to 01 = black 
     3455      else if (co == 'O' || co == 'W') 
     3456        currentHashCode[i] |= 1 << (p+1); // set to 10 = white 
     3457      else printf("ouch\n"); // FIXME 
     3458    } 
     3459  } 
     3460} 
     3461 
     3462void HashInstanceCTR::remove(char co, char x, char y) { 
    34523463  if (inRelevantRegion(x,y)) { 
    34533464    changed = true; 
    34543465    for(int i=0; i<8; i++) {