Changeset 194

Show
Ignore:
Timestamp:
10/06/06 20:46:47 (2 years ago)
Author:
ug
Message:

Hashing for corner patterns AlgoHash. Various smaller bug fixes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 06/libkombilo/cpptest.cc

    r193 r194  
    88 
    99int main(int argc, char** argv) { 
    10   GameList gl("t1.db", "id", "[[PW]] - [[PB]] ([[winner]]), [[filename.]]", ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL, 19); 
     10  int algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL | ALGO_HASH_CORNER; 
     11  bool process = false; 
     12  for(int i=1; i<argc; i++) { 
     13    if (!strcmp(argv[i], "-nh")) // disable hashing 
     14      algos = ALGO_FINALPOS | ALGO_MOVELIST; 
     15    if (!strcmp(argv[i], "-p")) process = true; 
     16  } 
    1117 
    12   if (argc>1 && !strcmp(argv[1], "-p")) { 
     18  GameList gl("t1.db", "id", "[[PW]] - [[PB]] ([[winner]]), [[filename.]]", algos, 19); 
     19 
     20  if (process) { // process sgf's. must be first argument 
    1321    gl.start_processing(); 
    1422    directory_iterator end_itr; 
    1523    // string path = "/home/ug/go/kombilo/06/libkombilo"; 
    16     string path = "/home/ug/go/gtl/reviews"; 
    17     // string path = "/home/ug/go/gogod06/1999"; 
     24    // string path = "/home/ug/go/gtl/reviews"; 
     25    string path = "/home/ug/go/gogod06/1999"; 
    1826    for(directory_iterator it(path); it != end_itr; ++it) { 
    1927      string n = it->string(); 
     
    3846  printf("%d games.\n", gl.size()); 
    3947 
     48  Pattern p(CORNER_NW_PATTERN,19,8,8,"...................X......X.......XO......OO...................."); 
     49  // Pattern p(CORNER_NW_PATTERN,19,7,7,".................X.....X......XO.....OO.........."); 
     50  // Pattern p(CORNER_NW_PATTERN,19,7,7,".......................X........................."); 
     51 
    4052  // gl.gisearch("pw = 'Hane Naoki'"); 
    41   Pattern p(CENTER_PATTERN, 19, 3, 5, ".X..OX.OX.OXOXO")
     53  // Pattern p(CENTER_PATTERN, 19, 3, 5, ".X..OX.OX.OXOXO")
    4254  // vector<MoveNC> contList; 
    4355  // contList.push_back(MoveNC(6,15,'X')); 
     
    5062  gl.search(p, so); 
    5163  printf("num games: %d, num hits: %d\n", gl.size(), gl.numHits()); 
    52   vector<string> res = gl.currentEntriesAsStrings(); 
    53   for(vector<string>::iterator it = res.begin(); it != res.end(); it++) 
    54     printf("%s\n", it->c_str()); 
    55   // for(int i=0; i<gl.size(); i++) printf("%s\n", gl.currentEntryAsString(i).c_str()); 
     64  // vector<string> res = gl.currentEntriesAsStrings(); 
     65  // for(vector<string>::iterator it = res.begin(); it != res.end(); it++) 
     66  //   printf("%s\n", it->c_str()); 
     67  for(int i=0; i<gl.size(); i++) printf("%s\n", gl.currentEntryAsString(i).c_str()); 
    5668  printf("Search pattern:\n"); 
    5769  printf("%s\n", p.printPattern().c_str()); 
  • 06/libkombilo/process.py

    r182 r194  
    1919 
    2020    starttime = time.time() 
    21     algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL 
     21    algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL | ALGO_HASH_CORNER 
    2222    try: 
    2323        gl = GameList('t1.db', 'id', '', algos, 19) 
  • 06/libkombilo/search.cc

    r193 r194  
    3636using std::make_pair; 
    3737using std::stack; 
     38using std::sort; 
    3839 
    3940PatternError::PatternError() {} 
     
    419420} 
    420421 
    421 PatternList::PatternList(Pattern& p, int fColor, int nMove, int bsize) { 
     422const int composition_table[] = { 
     423  0, 1, 2, 3, 4, 5, 6, 7, 
     424  1, 0, 3, 2, 5, 4, 7, 6, 
     425  2, 3, 0, 1, 6, 7, 4, 5, 
     426  3, 2, 1, 0, 7, 6, 5, 4, 
     427  4, 6, 5, 7, 0, 2, 1, 3, 
     428  5, 7, 4, 6, 1, 3, 0, 2, 
     429  6, 4, 7, 5, 2, 0, 3, 1, 
     430  7, 5, 6, 4, 3, 1, 2, 0 }; 
     431 
     432int Pattern::compose_flips(int i, int j) { 
     433  return composition_table[j+8*i]; 
     434
     435 
     436PatternList::PatternList(Pattern& p, int fColor, int nMove, int bsize) throw(PatternError) { 
    422437  pattern.copy(p); 
    423438  fixedColor = fColor; 
     
    425440  boardsize = bsize; 
    426441  special = -1; 
     442  flipTable = new int[16]; 
     443  for(int i=0; i<16; i++) flipTable[i] = -1; // (patternList() relies on this) 
    427444 
    428445  patternList(); 
     446  for(int i=0; i<16; i++)  
     447    if (flipTable[i] == -1) throw PatternError(); // FIXME: remove this once flipTable works ... 
    429448  continuations = new Continuation[pattern.sizeX * pattern.sizeY]; 
    430449} 
     
    432451PatternList::~PatternList() { 
    433452  delete [] continuations; 
     453  delete [] flipTable; 
    434454} 
    435455 
     
    499519      if (pNew == *it) { 
    500520        foundNewPattern = false; 
     521        flipTable[f] = flipTable[it->flip]; 
    501522        break; 
    502523      } 
    503524    } 
    504     if (foundNewPattern) data.push_back(pNew); 
     525    if (foundNewPattern) { 
     526      flipTable[f] = data.size(); 
     527      data.push_back(pNew); 
     528    } 
    505529 
    506530    if (pNew == pattern) sy.push_back(pair<int,int>(f,0)); 
     
    534558      if (!fixedColor) { 
    535559        bool foundNewPattern = true; 
     560        int lCS_ctr = 0; 
    536561        for(vector<Pattern>::iterator it = lCS.begin(); it != lCS.end(); it++) { 
    537562          if (pNew1 == *it) { 
    538563            foundNewPattern = false; 
     564            flipTable[f+8] = lCS_ctr; 
    539565            break; 
    540566          } 
     567          lCS_ctr++; 
    541568        } 
    542         if (foundNewPattern) lCS.push_back(pNew1); 
     569        if (foundNewPattern) { 
     570          lCS.push_back(pNew1); 
     571        } 
    543572      } 
    544573 
     
    550579  } 
    551580 
     581  int lCS_ctr = 0; 
    552582  for(vector<Pattern>::iterator it = lCS.begin(); it != lCS.end(); it++) { 
    553583    bool contained_in_l = false; 
     
    555585      if (*it == *it_l) { 
    556586        contained_in_l = true; 
     587        flipTable[8+it->flip] = flipTable[it_l->flip]; 
    557588        break; 
    558589      } 
    559     if (!contained_in_l) data.push_back(*it); 
     590    if (!contained_in_l) { 
     591      flipTable[8+it->flip] = data.size(); 
     592      data.push_back(*it); 
     593    } 
     594    for(int ii=it->flip+1; ii<8; ii++)  
     595      if (flipTable[8+ii] == lCS_ctr) flipTable[8+ii] = flipTable[8+it->flip]; 
     596    lCS_ctr++; 
    560597  } 
    561598 
     
    763800void Algorithm::finalize_process() {} 
    764801int Algorithm::readDB(sqlite3* DB) { return 0; } 
    765 int Algorithm::search(PatternList& patternList, GameList& gl, SearchOptions& options) { return -1; } 
     802int Algorithm::search(PatternList& patternList, GameList& gl, SearchOptions& options) {  
     803  printf("enter Algorithm::search\n"); 
     804  return -1;  
     805
    766806 
    767807Algo_signature::Algo_signature(int bsize) : Algorithm(bsize) { 
     
    13941434          if (p_ij != '.') d[i+p->sizeX*j] = p_ij; 
    13951435          else d[i+p->sizeX*j] = 0; 
    1396           if (p_ij == 'X' or p_ij == 'O') dNO++; 
     1436          if (p_ij == 'X' || p_ij == 'O') dNO++; 
    13971437        } 
    13981438      } 
     
    14781518                  (*it)->orientation, // pattern in question 
    14791519                  x-(*it)->mx, y-(*it)->my, // pos of continuation 
    1480                   invco, // color of continuation 
     1520                  co, // color of continuation 
    14811521                  (counter.total_move_num()-(*it)->dictsF.total_move_num())>2, // tenuki? 
    14821522                  gl.getCurrentWinner() 
     
    19151955#endif 
    19161956 
     1957HashhitF::HashhitF(int GAMEID, char ORIENTATION, char* blob) { 
     1958  gameid = GAMEID; 
     1959  orientation = ORIENTATION; 
     1960  cont = new MoveNC(blob[0], blob[1], blob[2]); 
     1961  emn = new ExtendedMoveNumber; 
     1962  emn->length = blob[3] * 256 + blob[4]; 
     1963  emn->data = new int[emn->length]; 
     1964  for(int i=0; i<emn->length; i++) { 
     1965    emn->data[i] = blob[5+2*i]*256 + blob[6+2*i]; 
     1966  } 
     1967} 
     1968 
     1969HashhitF::HashhitF() { 
     1970  printf("oops\n"); 
     1971  cont = 0; 
     1972  emn = 0; 
     1973} 
     1974 
     1975HashhitF::~HashhitF() { 
     1976  if (cont) delete cont; 
     1977  if (emn) delete emn; 
     1978} 
     1979 
     1980bool cmp_HashhitF(const HashhitF* a, const HashhitF* b) { 
     1981  return a->gameid < b->gameid; 
     1982} 
     1983 
     1984HashhitCS::HashhitCS(int GAMEID, int POSITION, bool CS) { 
     1985  gameid = GAMEID; 
     1986  position = POSITION; 
     1987  cs = CS; 
     1988} 
     1989 
     1990bool cmp_HashhitCS(const HashhitCS* a, const HashhitCS* b) { 
     1991  return a->gameid < b->gameid; 
     1992} 
     1993 
     1994 
     1995typedef vector<HashhitF* >* vpsip; 
     1996 
     1997 
    19171998HashVarInfo::HashVarInfo(hashtype CHC, vector<pair<hashtype, ExtendedMoveNumber>* > * LFC, 
    1918                          ExtendedMoveNumber* MOVENUMBER) { 
     1999                         ExtendedMoveNumber* MOVENUMBER, int NUMSTONES) { 
    19192000  chc = CHC; 
     2001  numStones = NUMSTONES; 
    19202002  moveNumber = new ExtendedMoveNumber(*MOVENUMBER); 
    19212003  lfc = new vector<pair<hashtype, ExtendedMoveNumber>* >; 
     
    19262008 
    19272009 
    1928 Algo_hash::Algo_hash(int bsize) : Algorithm(bsize) { 
     2010Algo_hash_full::Algo_hash_full(int bsize, int MAXNUMSTONES) : Algorithm(bsize) { 
    19292011  branchpoints = 0; 
    1930 
    1931  
    1932 Algo_hash::~Algo_hash() { 
    1933 
    1934  
    1935 int Algo_hash::insert_hash(hashtype hashCode, ExtendedMoveNumber& mn, Move* continuation) { 
     2012  maxNumStones = MAXNUMSTONES; 
     2013
     2014 
     2015Algo_hash_full::~Algo_hash_full() { 
     2016
     2017 
     2018int Algo_hash_full::insert_hash(hashtype hashCode, ExtendedMoveNumber& mn, Move* continuation) { 
    19362019  // printf("insert %lld\n", hashCode); 
    19372020  char* buf = new char[30 + mn.length*2]; 
     
    19512034    buf[6+2*i] = mn.data[i]%256; 
    19522035  } 
    1953   char* sql = "insert into algo_hash (hash, gameid, hit) values (?,?,?);"; 
     2036  char* sql = "insert into algo_hash_full (hash, gameid, hit) values (?,?,?);"; 
    19542037  sqlite3_stmt *ppStmt=0; 
    19552038  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
    19562039  if (rc != SQLITE_OK || ppStmt==0) return rc; 
    1957   rc = sqlite3_bind_int64(ppStmt, 1, currentHashCode); 
     2040  rc = sqlite3_bind_int64(ppStmt, 1, hashCode); 
    19582041  if (rc != SQLITE_OK) return rc; 
    19592042  rc = sqlite3_bind_int(ppStmt, 2, gid); 
     
    19692052} 
    19702053 
    1971 void Algo_hash::initialize_process(sqlite3* DB) throw(DBError) { 
     2054void Algo_hash_full::initialize_process(sqlite3* DB) throw(DBError) { 
    19722055  db = DB; 
    1973   int rc = sqlite3_exec(db, "create table if not exists algo_hash ( id integer primary key, hash integer, gameid integer, hit text );", 0, 0, 0); 
     2056  int rc = sqlite3_exec(db, "create table if not exists algo_hash_full ( id integer primary key, hash integer, gameid integer, hit text );", 0, 0, 0); 
    19742057  if (rc != SQLITE_OK) throw DBError(); 
    1975   rc = sqlite3_exec(db, "create index if not exists hash_idx on algo_hash(hash);", 0, 0, 0); 
     2058  rc = sqlite3_exec(db, "create index if not exists hash_idx on algo_hash_full(hash);", 0, 0, 0); 
    19762059  if (rc != SQLITE_OK) throw DBError(); 
    19772060} 
    19782061         
    1979 void Algo_hash::newgame_process(int game_id) { 
     2062void Algo_hash_full::newgame_process(int game_id) { 
     2063  numStones = 0; 
    19802064  gid = game_id; 
    19812065  moveNumber = new ExtendedMoveNumber(0); 
     
    19852069} 
    19862070 
    1987 void Algo_hash::AB_process(int x, int y) { 
     2071void Algo_hash_full::AB_process(int x, int y) { 
    19882072  for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 
    19892073    Move* continuation = new Move(x,y,'B'); 
     
    19942078  delete lfc; 
    19952079  lfc = new vector<pair<hashtype, ExtendedMoveNumber>* >; 
    1996   currentHashCode += hashCodes[x + boardsize*y]; 
    1997 
    1998  
    1999 void Algo_hash::AW_process(int x, int y) { 
     2080  currentHashCode += Algo_hash::hashCodes[x + boardsize*y]; 
     2081  numStones++; 
     2082
     2083 
     2084void Algo_hash_full::AW_process(int x, int y) { 
    20002085  for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 
    20012086    Move* continuation = new Move(x,y,'W'); 
     
    20062091  delete lfc; 
    20072092  lfc = new vector<pair<hashtype, ExtendedMoveNumber>* >; 
    2008   currentHashCode -= hashCodes[x + boardsize*y]; 
     2093  currentHashCode -= Algo_hash::hashCodes[x + boardsize*y]; 
     2094  numStones++; 
    20092095}                  
    20102096 
    2011 void Algo_hash::AE_process(int x, int y, char removed) { 
    2012   if (removed == 'B') currentHashCode -= hashCodes[x + boardsize*y]; 
    2013   else currentHashCode += hashCodes[x + boardsize*y]; 
    2014 
    2015  
    2016 void Algo_hash::endOfNode_process() { 
    2017   lfc->push_back(new pair<hashtype, ExtendedMoveNumber>(currentHashCode, *moveNumber)); 
     2097void Algo_hash_full::AE_process(int x, int y, char removed) { 
     2098  if (removed == 'B') currentHashCode -= Algo_hash::hashCodes[x + boardsize*y]; 
     2099  else currentHashCode += Algo_hash::hashCodes[x + boardsize*y]; 
     2100  numStones--; 
     2101
     2102 
     2103void Algo_hash_full::endOfNode_process() { 
     2104  if (numStones <= maxNumStones) lfc->push_back(new pair<hashtype, ExtendedMoveNumber>(currentHashCode, *moveNumber)); 
    20182105  moveNumber->next(); 
    20192106} 
    20202107 
    2021 void Algo_hash::pass_process() { 
     2108void Algo_hash_full::pass_process() { 
    20222109  // (we do not count pass as continuation) 
    20232110} 
    20242111 
    2025 void Algo_hash::move_process(Move m) throw(DBError) { 
     2112void Algo_hash_full::move_process(Move m) throw(DBError) { 
    20262113  for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 
    20272114    Move* continuation = new Move(m); 
     
    20342121  lfc = new vector<pair<hashtype, ExtendedMoveNumber>* >; 
    20352122  int epsilon = (m.color == 'B' || m.color == 'X' ? 1 : -1); 
    2036   currentHashCode += epsilon * hashCodes[m.x + boardsize*m.y]; 
     2123  currentHashCode += epsilon * Algo_hash::hashCodes[m.x + boardsize*m.y]; 
     2124  numStones++; 
    20372125 
    20382126  if (m.captures) { 
     
    20422130      int yy = it->second; 
    20432131 
    2044       currentHashCode += epsilon * hashCodes[xx + boardsize*yy]; 
    2045     } 
    2046   } 
    2047 
    2048  
    2049 void Algo_hash::branchpoint_process() { 
    2050   branchpoints->push(HashVarInfo(currentHashCode, lfc, moveNumber)); 
     2132      currentHashCode += epsilon * Algo_hash::hashCodes[xx + boardsize*yy]; 
     2133      numStones--; 
     2134    } 
     2135  } 
     2136
     2137 
     2138void Algo_hash_full::branchpoint_process() { 
     2139  branchpoints->push(HashVarInfo(currentHashCode, lfc, moveNumber, numStones)); 
    20512140  // printf("push %lld\n", currentHashCode); 
    20522141} 
    20532142 
    2054 void Algo_hash::endOfVariation_process() { 
     2143void Algo_hash_full::endOfVariation_process() { 
    20552144  for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 
    20562145    int rc = insert_hash((*it)->first, (*it)->second, 0); 
     
    20632152  lfc = branchpoints->top().lfc; 
    20642153  moveNumber = branchpoints->top().moveNumber; 
     2154  numStones = branchpoints->top().numStones; 
    20652155  // printf("pop %lld\n", currentHashCode); 
    20662156  branchpoints->pop(); 
    20672157} 
    20682158 
    2069 void Algo_hash::endgame_process() { 
     2159void Algo_hash_full::endgame_process() { 
    20702160  for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 
    20712161    Move* continuation = 0; 
     
    20792169} 
    20802170  
    2081 void Algo_hash::finalize_process() { 
    2082 } 
    2083  
    2084  
    2085 hashtype Algo_hash::compute_hashkey(Pattern& pattern) { 
     2171void Algo_hash_full::finalize_process() { 
     2172} 
     2173 
     2174 
     2175hashtype Algo_hash_full::compute_hashkey(Pattern& pattern) { 
    20862176  if (pattern.sizeX != boardsize || pattern.sizeY != boardsize) 
    20872177    return NOT_HASHABLE; 
    20882178  hashtype hashkey = 0; 
    2089              
     2179  int ns = 0;           
    20902180  for(int i=0; i<boardsize; i++) { 
    20912181    for(int j=0; j<boardsize; j++) { 
    20922182      char p = pattern.finalPos[i + boardsize*j]; 
    20932183      if (p == 'x' || p ==  'o' || p == '*') return NOT_HASHABLE; 
    2094       else if (p == 'X') hashkey += hashCodes[i + boardsize*j]; 
    2095       else if (p == 'O') hashkey -= hashCodes[i + boardsize*j]; 
    2096     } 
    2097   } 
     2184      else if (p == 'X') { 
     2185        hashkey += Algo_hash::hashCodes[i + boardsize*j]; 
     2186        ns++; 
     2187      } else if (p == 'O') { 
     2188        hashkey -= Algo_hash::hashCodes[i + boardsize*j]; 
     2189        ns++; 
     2190      } 
     2191    } 
     2192  } 
     2193  if (ns > maxNumStones) return NOT_HASHABLE; 
    20982194  return hashkey; 
    20992195} 
    21002196 
    2101 Hashhit::Hashhit(int GAMEID, char ORIENTATION, char* blob) { 
    2102   gameid = GAMEID; 
    2103   orientation = ORIENTATION; 
    2104   cont = new MoveNC(blob[0], blob[1], blob[2]); 
    2105   emn = new ExtendedMoveNumber; 
    2106   emn->length = blob[3] * 256 + blob[4]; 
    2107   emn->data = new int[emn->length]; 
    2108   for(int i=0; i<emn->length; i++) { 
    2109     emn->data[i] = blob[5+2*i]*256 + blob[6+2*i]; 
    2110   } 
    2111 
    2112  
    2113 Hashhit::Hashhit() { 
    2114   printf("oops\n"); 
    2115   cont = 0; 
    2116   emn = 0; 
    2117 
    2118  
    2119 Hashhit::~Hashhit() { 
    2120   if (cont) delete cont; 
    2121   if (emn) delete emn; 
    2122 
    2123  
    2124 bool hashhit_cmp(const Hashhit* a, const Hashhit* b) { 
    2125   return a->gameid < b->gameid; 
    2126 
    2127  
    2128 typedef vector<Hashhit* >* vpsip; 
    2129  
    2130 int insert_result(void *results, int argc, char **argv, char **azColName) throw (DBError) { 
     2197int insert_result_hf(void *results, int argc, char **argv, char **azColName) throw (DBError) { 
    21312198  vpsip res = ((pair<vpsip, int>*)results)->first; 
    21322199  int orientation = ((pair<vpsip, int>*)results)->second; 
    21332200  if (argc==2 && argv[0]) { 
    2134     res->push_back(new Hashhit(atoi(argv[0]), orientation, argv[1])); 
    2135   } else { 
    2136     printf("ouch\n"); 
    2137     throw DBError(); 
    2138   } 
     2201    res->push_back(new HashhitF(atoi(argv[0]), orientation, argv[1])); 
     2202  } else throw DBError(); 
    21392203  return 0; 
    21402204} 
    21412205 
    2142 int Algo_hash::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { 
     2206 
     2207int Algo_hash_full::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { 
    21432208  int hash_result = -1; // -1 = failure; 0 = ok, but have to check w/ Algo_movelist, 1 = ok, produced final result 
     2209  int plS = patternList.size(); 
     2210  vpsip results = new vector<HashhitF* >; 
     2211  for(int N=0; N<plS; N++) { 
     2212    hashtype hashCode = compute_hashkey(patternList.data[N]); 
     2213    if (hashCode == NOT_HASHABLE) return -1; // failure 
     2214 
     2215    char sql[100]; 
     2216    sprintf(sql, "select gameid,hit from algo_hash_full where hash = %lld", hashCode); 
     2217    // printf("hc %lld, %s\n", hashCode, sql); 
     2218    pair<vpsip, int> rN(results, N); 
     2219    sqlite3_exec(db, sql, insert_result_hf, &rN, 0); 
     2220  } 
     2221  if (options.trustHashFull && patternList.pattern.contList.size()==0) hash_result = 1; 
     2222  else hash_result = 0; 
    21442223  if (gl.start_sorted() == 0) { 
    2145     int plS = patternList.size(); 
    2146     vpsip results = new vector<Hashhit* >; 
    2147     // printf("enter algo_hash.search %d\n", plS); 
    2148     for(int N=0; N<plS; N++) { 
    2149       hashtype hashCode = compute_hashkey(patternList.data[N]); 
    2150       if (hashCode == NOT_HASHABLE) return -1; // failure 
    2151  
    2152       char sql[100]; 
    2153       sprintf(sql, "select gameid,hit from algo_hash where hash = %lld", hashCode); 
    2154       // printf("hc %lld, %s\n", hashCode, sql); 
    2155       pair<vpsip, int> rN(results, N); 
    2156       sqlite3_exec(db, sql, insert_result, &rN, 0); 
    2157     } 
    2158     if (options.trustHashFull && patternList.pattern.contList.size()==0) hash_result = 1; 
    2159     else hash_result = 0; 
     2224    sort(results->begin(), results->end(), cmp_HashhitF); 
    21602225    // printf("res-size %d\n", results->size()); 
    2161     sort(results->begin(), results->end(), hashhit_cmp); 
    2162     vector<Hashhit* >::iterator resultIT = results->begin(); 
     2226    vector<HashhitF* >::iterator resultIT = results->begin(); 
    21632227    while (resultIT != results->end()) { 
    21642228      int index = (*resultIT)->gameid; 
     
    22042268      } 
    22052269    } 
    2206     for(vector<Hashhit* >::iterator it = results->begin(); it != results->end(); it++) delete *it; 
     2270    for(vector<HashhitF* >::iterator it = results->begin(); it != results->end(); it++) delete *it; 
    22072271    delete results; 
    22082272    gl.end_sorted(); 
    22092273  } 
    22102274  return 0; 
     2275} 
     2276 
     2277// ----------------------------------------------------------------------------------- 
     2278 
     2279Algo_hash::Algo_hash(int bsize, const string& DBNAMEEXT) : Algorithm(bsize) { 
     2280  dbnameext = DBNAMEEXT; 
     2281  maxNumStones = 20; // FIXME 
     2282  hi = 0; 
     2283} 
     2284 
     2285Algo_hash::~Algo_hash() { 
     2286  if (hi) delete hi; 
     2287} 
     2288 
     2289int Algo_hash::insert_hash(hashtype hashCode, int pos) { 
     2290  // printf("insert %lld\n", hashCode); 
     2291  char sql[200]; 
     2292  sprintf(sql, "insert into algo_hash%s (hash, gameid, position) values (?,?,?);", dbnameext.c_str()); 
     2293  sqlite3_stmt *ppStmt=0; 
     2294  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
     2295  if (rc != SQLITE_OK || ppStmt==0) return rc; 
     2296  rc = sqlite3_bind_int64(ppStmt, 1, hashCode); 
     2297  if (rc != SQLITE_OK) return rc; 
     2298  rc = sqlite3_bind_int(ppStmt, 2, gid); 
     2299  if (rc != SQLITE_OK) return rc; 
     2300  rc = sqlite3_bind_int(ppStmt, 3, pos); 
     2301  if (rc != SQLITE_OK) return rc; 
     2302  rc = sqlite3_step(ppStmt); 
     2303  if (rc != SQLITE_DONE) return rc; 
     2304  rc = sqlite3_finalize(ppStmt); 
     2305  if (rc != SQLITE_OK) return rc; 
     2306  return 0; // success 
     2307} 
     2308 
     2309void Algo_hash::initialize_process(sqlite3* DB) throw(DBError) { 
     2310  db = DB; 
     2311  char buf[200]; 
     2312  sprintf(buf, "create table if not exists algo_hash%s ( hash integer, gameid integer, position integer );", dbnameext.c_str()); 
     2313  int rc = sqlite3_exec(db, buf, 0, 0, 0); 
     2314  if (rc != SQLITE_OK) throw DBError(); 
     2315  sprintf(buf, "create index if not exists hash_idx%s on algo_hash%s(hash);", dbnameext.c_str(), dbnameext.c_str()); 
     2316  rc = sqlite3_exec(db, buf, 0, 0, 0); 
     2317  if (rc != SQLITE_OK) throw DBError(); 
     2318} 
     2319         
     2320void Algo_hash::newgame_process(int game_id) { 
     2321  gid = game_id; 
     2322  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2323    it->initialize(); 
     2324} 
     2325 
     2326void Algo_hash::AB_process(int x, int y) { 
     2327  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2328    it->addB(x,y); 
     2329} 
     2330 
     2331void Algo_hash::AW_process(int x, int y) { 
     2332  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2333    it->addW(x,y); 
     2334}                  
     2335 
     2336void Algo_hash::AE_process(int x, int y, char removed) { 
     2337  if (removed == 'B') { 
     2338    for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) it->removeB(x,y); 
     2339  } else {  
     2340    for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) it->removeW(x,y); 
     2341  } 
     2342} 
     2343 
     2344void Algo_hash::endOfNode_process() { 
     2345  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) { 
     2346    if (it->numStones <= maxNumStones && it->changed) { 
     2347      it->changed = false; 
     2348      pair<hashtype,int> phi = it->cHC(); 
     2349      if (insert_hash(phi.first, phi.second) != 0) throw DBError(); 
     2350    } 
     2351  } 
     2352} 
     2353 
     2354void Algo_hash::pass_process() { 
     2355  // (we do not count pass as continuation) 
     2356} 
     2357 
     2358void Algo_hash::move_process(Move m) throw(DBError) { 
     2359  if (m.color == 'B') { 
     2360    for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2361      it->addB(m.x, m.y); 
     2362    if (m.captures) { 
     2363      for(vector<p_cc>::iterator cap_it = m.captures->begin(); cap_it != m.captures->end(); cap_it++) { 
     2364        for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2365          it->removeW(cap_it->first, cap_it->second); 
     2366      } 
     2367    } 
     2368  } else { 
     2369    for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2370      it->addW(m.x, m.y); 
     2371    if (m.captures) { 
     2372      for(vector<p_cc>::iterator cap_it = m.captures->begin(); cap_it != m.captures->end(); cap_it++) { 
     2373        for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2374          it->removeB(cap_it->first, cap_it->second); 
     2375      } 
     2376    } 
     2377  } 
     2378} 
     2379 
     2380void Algo_hash::branchpoint_process() { 
     2381  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2382    it->bppush(); 
     2383} 
     2384 
     2385void Algo_hash::endOfVariation_process() { 
     2386  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2387    it->bppop(); 
     2388} 
     2389 
     2390void Algo_hash::endgame_process() { 
     2391  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
     2392    it->finalize(); 
     2393} 
     2394  
     2395void Algo_hash::finalize_process() { 
     2396} 
     2397 
     2398 
     2399pair<hashtype,int> Algo_hash::compute_hashkey(PatternList& pl, int CS) { 
     2400  return make_pair(NOT_HASHABLE,0); 
     2401} 
     2402 
     2403int insert_result(void *rN, int argc, char **argv, char **azColName) throw (DBError) { 
     2404  vector<HashhitCS* >* results = ((pair<vector<HashhitCS* >*, hashtype>*)rN)->first; 
     2405  hashtype hashCode = ((pair<vector<HashhitCS* >*, hashtype>*)rN)->second; 
     2406 
     2407  if (argc==3 && argv[0] && argv[1] && argv[2]) { 
     2408    // printf("found %s, %lld", argv[2], atoi(argv[2])); 
     2409    ((vector<HashhitCS* >*)results)->push_back(new HashhitCS(atoi(argv[0]), atoi(argv[1]), atoll(argv[2])!=hashCode)); 
     2410  } else throw DBError(); 
     2411  return 0; 
     2412} 
     2413 
     2414 
     2415int Algo_hash::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { 
     2416  // return value: -1 = failure; 0 = ok, but have to check w/ Algo_movelist 
     2417 
     2418  vector<HashhitCS* >* results = new vector<HashhitCS* >; 
     2419 
     2420  pair<hashtype, int> hco = compute_hashkey(patternList, 0); 
     2421  hashtype hashCode = hco.first; 
     2422  // printf("HC %lld\n", hashCode); 
     2423  hashtype hashCode2 = hashCode; 
     2424  if (hashCode == NOT_HASHABLE) { 
     2425    delete results; 
     2426    return -1; // failure 
     2427  } 
     2428  int fl = patternList.data[hco.second].flip; 
     2429  int fl2 = fl; 
     2430  char buf[100]; 
     2431  sprintf(buf, "select gameid,position,hash from algo_hash%s where hash = %lld",  
     2432      dbnameext.c_str(), hashCode); 
     2433  string sql = buf; 
     2434 
     2435  bool cs = patternList.data[patternList.size()-1].colorSwitch; 
     2436  if (cs) { 
     2437    pair<hashtype, int> hco = compute_hashkey(patternList, 1); 
     2438    hashCode2 = hco.first; 
     2439    // printf("HC2 %lld\n", hashCode2); 
     2440    if (hashCode == NOT_HASHABLE) { 
     2441      delete results; 
     2442      return -1; // failure 
     2443    } 
     2444    fl2 = patternList.data[hco.second].flip; 
     2445 
     2446    if (hashCode != hashCode2) { 
     2447      sprintf(buf, " or hash = %lld", hashCode2); 
     2448      sql += buf; 
     2449    } 
     2450  } 
     2451  sql += " order by gameid"; 
     2452 
     2453  if (gl.start_sorted() == 0) { 
     2454    // query database 
     2455 
     2456    // printf("%s\n", sql); 
     2457    pair<vector<HashhitCS* >*, hashtype> rN(results, hashCode); 
     2458    sqlite3_exec(db, sql.c_str(), insert_result, &rN, 0); 
     2459    // printf("results->size() %d\n", results->size()); 
     2460 
     2461    // communicate results of query to database 
     2462     
     2463    vector<HashhitCS* >::iterator resultIT = results->begin(); 
     2464    while (resultIT != results->end()) { 
     2465      // printf("gid %d\n", (*resultIT)->gameid); 
     2466      int index = (*resultIT)->gameid; 
     2467 
     2468      vector<Candidate* >* candidates = new vector<Candidate* >; 
     2469      while ((*resultIT)->gameid == index) { 
     2470        // int pos = (*resultIT)->position % (1<<16); 
     2471        int ori = (*resultIT)->position / (1<<16); 
     2472        // printf("%d %d\n", pos, ori); 
     2473        if (cs && hashCode == hashCode2) { // this is a somewhat pathological case ... 
     2474          int ind = patternList.flipTable[Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl)]; 
     2475          candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 
     2476          ind = patternList.flipTable[8+Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl2)]; 
     2477          candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 
     2478        } else { 
     2479          if ((*resultIT)->cs) { 
     2480            // FIXME works only for corner patterns right now! 
     2481            int ind = patternList.flipTable[8+Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl2)]; 
     2482            // printf("cand cs %d %d %d\n", patternList.flipTable[8+Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl2)], patternList.data[ind].left, patternList.data[ind].top); 
     2483            candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 
     2484          } else { 
     2485            int ind = patternList.flipTable[Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl)]; 
     2486            // printf("cand %d %d %d\n", patternList.flipTable[Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl)], patternList.data[ind].left, patternList.data[ind].top); 
     2487            candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 
     2488          } 
     2489        } 
     2490        resultIT++; 
     2491        if (resultIT == results->end()) break; 
     2492      } 
     2493      gl.makeIndexCandidate(index, candidates); 
     2494    } 
     2495    for(vector<HashhitCS* >::iterator it = results->begin(); it != results->end(); it++) delete *it; 
     2496    delete results; 
     2497    gl.end_sorted(); 
     2498  } else return -1; 
     2499  return 0; 
     2500} 
     2501 
     2502Algo_hash_corner::Algo_hash_corner(int bsize, int SIZE) : Algo_hash(bsize, "CORNER") { 
     2503  size = SIZE; 
     2504  char buf[5]; 
     2505  sprintf(buf, "%d", size); 
     2506  dbnameext += buf; 
     2507  hi = new vector<HashInstance>; 
     2508  hi->push_back(HashInstance(0,0,size,size,boardsize)); 
     2509  hi->push_back(HashInstance(0,bsize-size,size,size,boardsize)); 
     2510  hi->push_back(HashInstance(bsize-size,0,size,size,boardsize)); 
     2511  hi->push_back(HashInstance(bsize-size, bsize-size, size, size,boardsize)); 
     2512} 
     2513 
     2514pair<hashtype,int> Algo_hash_corner::compute_hashkey(PatternList& pl, int CS) { 
     2515  if (pl.data[0].sizeX < size || pl.data[0].sizeY < size || pl.data[0].left != pl.data[0].right || pl.data[0].top != pl.data[0].bottom || (pl.data[0].left != 0 && pl.data[0].left != boardsize-size) || (pl.data[0].top != 0 && pl.data[0].top != boardsize-size)) return make_pair(NOT_HASHABLE,0); 
     2516  hashtype hk = NOT_HASHABLE; 
     2517  int f = 0; 
     2518  vector<hashtype> hCodes; 
     2519  for(int pCtr=0; pCtr<pl.size(); pCtr++) { 
     2520    if (CS == pl.data[pCtr].colorSwitch) { 
     2521      hashtype hashkey = 0; 
     2522      int ns = 0; 
     2523 
     2524      Pattern *pattern = & pl.data[pCtr]; 
     2525      int offsetX = 0; 
     2526      int offsetY = 0; 
     2527      if (pattern->left > 0) offsetX = boardsize-size-pattern->left; // pattern located on east side of board 
     2528      if (pattern->top > 0) offsetY = boardsize-size-pattern->top;   // ... south ... 
     2529      for(int i=0; i<size; i++) { 
     2530        for(int j=0; j<size; j++) { 
     2531          char p = pattern->finalPos[i+offsetX + pattern->sizeX*(j+offsetY)]; 
     2532          if (p == 'x' || p ==  'o' || p == '*') return make_pair(NOT_HASHABLE,0); 
     2533          else if (p == 'X') { 
     2534            hashkey += hashCodes[i+offsetX+pattern->left + boardsize*(j+offsetY+pattern->top)]; 
     2535            ns++; 
     2536          } else if (p == 'O') { 
     2537            hashkey -= hashCodes[i+offsetX+pattern->left + boardsize*(j+offsetY+pattern->top)]; 
     2538            ns++; 
     2539          } 
     2540        } 
     2541      } 
     2542      if (ns > maxNumStones) return make_pair(NOT_HASHABLE,0); 
     2543 
     2544      // make sure all hash keys are unique 
     2545      for(vector<hashtype>::iterator it = hCodes.begin(); it != hCodes.end(); it++) 
     2546        if (*it == hashkey) return make_pair(NOT_HASHABLE, 0); 
     2547      hCodes.push_back(hashkey); 
     2548 
     2549      if (hk==NOT_HASHABLE || hashkey<hk) { 
     2550        hk = hashkey; 
     2551        f = pCtr; 
     2552      } 
     2553    } 
     2554  } 
     2555  return make_pair(hk, f); 
     2556} 
     2557 
     2558// Algo_hash_side::Algo_hash_side(int bsize, int SIZEX, int SIZEY) : Algo_hash(bsize, "SIDE") { 
     2559//   sizeX = SIZEX; 
     2560//   sizeY = SIZEY; 
     2561//   char buf[10]; 
     2562//   sprintf(buf, "%d_%d", sizeX, sizeY); 
     2563//   dbnameext += buf; 
     2564//  
     2565//   hi = new vector<HashInstance>; 
     2566//   for(int i=1; i<bsize-1-sizeX; i++) 
     2567//     hi->push_back(HashInstance(i,0,sizeX, sizeY,boardsize)); 
     2568//   for(int i=1; i<bsize-1-sizeX; i++) 
     2569//     hi->push_back(HashInstance(i,bsize-sizeY,sizeX, sizeY,boardsize)); 
     2570//   for(int i=1; i<bsize-1-sizeX; i++) 
     2571//     hi->push_back(HashInstance(0, i, sizeY, sizeX,boardsize)); 
     2572//   for(int i=1; i<bsize-1-sizeX; i++) 
     2573//     hi->push_back(HashInstance(bsize-sizeY, i, sizeY, sizeX,boardsize)); 
     2574// } 
     2575 
     2576HashInstance::HashInstance(char X, char Y, char SIZEX, char SIZEY, int BOARDSIZE) { 
     2577  boardsize = BOARDSIZE; 
     2578  xx = X; 
     2579  yy = Y; 
     2580  pos = xx + boardsize*yy; 
     2581  sizeX = SIZEX;  
     2582  sizeY = SIZEY; 
     2583  branchpoints = 0; 
     2584  currentHashCode = 0; 
     2585  numStones = 0; 
     2586  changed = true; 
     2587} 
     2588 
     2589HashInstance::~HashInstance() { 
     2590  finalize(); 
     2591} 
     2592 
     2593void HashInstance::finalize() { 
     2594  if (branchpoints) { 
     2595    while (branchpoints->size()) { 
     2596      delete [] branchpoints->top().first; 
     2597      branchpoints->pop(); 
     2598    } 
     2599    delete branchpoints; 
     2600    branchpoints = 0; 
     2601  } 
     2602  if (currentHashCode) { 
     2603    delete [] currentHashCode; 
     2604    currentHashCode = 0; 
     2605  } 
     2606} 
     2607 
     2608bool HashInstance::inRelevantRegion(char X, char Y) { 
     2609  if (xx <= X && X < xx+sizeX && yy <= Y && Y < yy+sizeY) return true; 
     2610  return false; 
     2611} 
     2612 
     2613void HashInstance::initialize() { 
     2614  currentHashCode = new hashtype[8];  
     2615  for(int i=0; i<8; i++) currentHashCode[i] = 0; // start with empty board 
     2616  numStones = 0; 
     2617  branchpoints = new stack<pair<hashtype*,int> >; 
     2618  changed = true; // do record empty pattern ... 
     2619} 
     2620 
     2621void HashInstance::addB(char x, char y) { 
     2622  if (inRelevantRegion(x,y)) { 
     2623    changed = true; 
     2624    for(int i=0; i<8; i++) { 
     2625      currentHashCode[i] += Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     2626    } 
     2627    numStones++; 
     2628  } 
     2629} 
     2630 
     2631void HashInstance::addW(char x, char y) { 
     2632  if (inRelevantRegion(x,y)) { 
     2633    changed = true; 
     2634    for(int i=0; i<8; i++) { 
     2635      currentHashCode[i] -= Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     2636    } 
     2637    numStones++; 
     2638  } 
     2639} 
     2640 
     2641void HashInstance::removeB(char x, char y) { 
     2642  if (inRelevantRegion(x,y)) { 
     2643    changed = true; 
     2644    for(int i=0; i<8; i++) { 
     2645      currentHashCode[i] -= Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     2646    } 
     2647    numStones++; 
     2648  } 
     2649} 
     2650 
     2651void HashInstance::removeW(char x, char y) { 
     2652  if (inRelevantRegion(x,y)) { 
     2653    changed = true; 
     2654    for(int i=0; i<8; i++) { 
     2655      currentHashCode[i] += Algo_hash::hashCodes[Pattern::flipsX(i,x,y,boardsize-1, boardsize-1) + boardsize*Pattern::flipsY(i,x,y,boardsize-1, boardsize-1)]; 
     2656    } 
     2657    numStones++; 
     2658  } 
     2659} 
     2660 
     2661pair<hashtype,int> HashInstance::cHC() { 
     2662  int flip = 0; 
     2663  hashtype minCHC = currentHashCode[0]; 
     2664  for(int i=1; i<8; i++) {  
     2665    if (currentHashCode[i] < minCHC) { 
     2666      minCHC = currentHashCode[i]; 
     2667      flip = i; 
     2668    } 
     2669  } 
     2670  return make_pair(minCHC, flip*(1<<16)  + pos); 
     2671} 
     2672 
     2673void HashInstance::bppush() { 
     2674  hashtype* chc = new hashtype[8]; 
     2675  for(int i=0; i<8; i++) chc[i] = currentHashCode[i]; 
     2676  branchpoints->push(make_pair(chc, numStones)); 
     2677} 
     2678 
     2679void HashInstance::bppop() { 
     2680  delete [] currentHashCode; 
     2681  currentHashCode = branchpoints->top().first; 
     2682  numStones = branchpoints->top().second; 
     2683  branchpoints->pop(); 
    22112684} 
    22122685 
     
    27933266    algo_ps[algo_movelist] = new Algo_movelist(boardsize); 
    27943267  if (algos & ALGO_HASH_FULL)  
    2795     algo_ps[algo_hash_full] = new Algo_hash(boardsize); 
     3268    algo_ps[algo_hash_full] = new Algo_hash_full(boardsize); // FIXME need to give MAXNUMSTONES here 
     3269  if (algos & ALGO_HASH_CORNER)  
     3270    algo_ps[algo_hash_corner] = new Algo_hash_corner(boardsize, 7); // FIXME options 
     3271  // if (algos & ALGO_HASH_SIDE)  
     3272  //   algo_ps[algo_hash_side] = new Algo_hash_side(boardsize, 6, 4); // FIXME need to give MAXNUMSTONES here 
    27963273  all = 0; 
    27973274  currentList = oldList = 0; 
     
    28263303  rc = sqlite3_exec(db, "pragma cache_size = 300000;", 0, 0, 0); 
    28273304  if (rc) throw DBError(); 
     3305  rc = sqlite3_exec(db, "begin transaction;", 0, 0, 0); 
     3306  if (rc) throw DBError(); 
    28283307 
    28293308  string sql = "select "; // those two we need in any case 
     
    28373316    readDBs = 1; 
    28383317  } else readDBs = 0; 
     3318  rc = sqlite3_exec(db, "commit;", 0, 0, 0); 
     3319  if (rc) throw DBError(); 
    28393320 
    28403321  sqlite3_close(db); 
     
    31113592 
    31123593  int hash_result = -1; 
     3594  // FULL BOARD PATTERN? 
    31133595  if (pl.pattern.sizeX == 19 && pl.pattern.sizeY == 19 && algo_ps[algo_hash_full]) { 
    3114     hash_result = ((Algo_hash*)algo_ps[algo_finalpos])->search(pl, *this, so, db); 
     3596    hash_result = ((Algo_hash_full*)algo_ps[algo_hash_full])->search(pl, *this, so, db); 
    31153597    if (hash_result == 1) { 
    31163598    } else if (hash_result == 0) { 
     
    31183600    } 
    31193601  } 
    3120   if (hash_result == -1) { 
    3121     algo_ps[algo_finalpos]->search(pl, *this, so); // FIXME: once more algorithms are available, this 
    3122                                                    // has to become more elaborate 
    3123     algo_ps[algo_movelist]->search(pl, *this, so); 
     3602  if (hash_result == -1) { // not a full board pattern (or not hashable) 
     3603 
     3604    // CORNER PATTERN? 
     3605    if (pl.pattern.sizeX >= 7 && pl.pattern.sizeY >= 7 && algo_ps[algo_hash_corner]) { // FIXME 
     3606      hash_result = ((Algo_hash_corner*)algo_ps[algo_hash_corner])->search(pl, *this, so, db); 
     3607      if (hash_result == 0) { 
     3608        printf("corner hashing successful\n"); 
     3609        algo_ps[algo_movelist]->search(pl, *this, so); 
     3610      } 
     3611    } 
     3612 
     3613    if (hash_result == -1) { 
     3614      algo_ps[algo_finalpos]->search(pl, *this, so); 
     3615      algo_ps[algo_movelist]->search(pl, *this, so); 
     3616    } 
    31243617  } 
    31253618  sqlite3_close(db); 
  • 06/libkombilo/search.h

    r193 r194  
    3535#ifdef __BORLANDC__ 
    3636typedef __int64 hashtype; 
     37const hashtype NOT_HASHABLE = 9223372036854775807i64; 
    3738#else 
    3839typedef long long hashtype; 
     40const hashtype NOT_HASHABLE = 9223372036854775807LL; 
    3941#endif 
    4042 
     
    115117    static int flipsY(int i, int x, int y, int XX, int YY); 
    116118    static int PatternInvFlip(int i); 
     119    static int compose_flips(int i, int j); // returns index of flip "first j, then i" 
    117120}; 
    118121 
     
    139142    std::vector<Symmetries> symmetries; 
    140143    Continuation* continuations; 
     144    int* flipTable; 
    141145    int special; 
    142146 
    143     PatternList(Pattern& p, int fColor, int nMove, int bsize)
     147    PatternList(Pattern& p, int fColor, int nMove, int bsize) throw (PatternError)
    144148    ~PatternList(); 
    145149 
     
    318322}; 
    319323 
    320 const hashtype NOT_HASHABLE = 9223372036854775807LL; 
    321  
    322  
    323 class Hashhit { 
     324 
     325class HashhitF { // hashing hit for full board search 
    324326  public: 
    325327    int gameid; 
     
    328330    ExtendedMoveNumber* emn; 
    329331 
    330     Hashhit(); 
    331     Hashhit(int GAMEID, char ORIENTATION, char* blob); 
    332     ~Hashhit(); 
     332    HashhitF(); 
     333    HashhitF(int GAMEID, char ORIENTATION, char* blob); 
     334    ~HashhitF(); 
     335}; 
     336 
     337class HashhitCS { // hasihing hit for corner/side pattern search 
     338  public: 
     339    int gameid; 
     340    int position; 
     341    bool cs;