Changeset 194
- Timestamp:
- 10/06/06 20:46:47 (2 years ago)
- Files:
-
- 06/libkombilo/cpptest.cc (modified) (3 diffs)
- 06/libkombilo/process.py (modified) (1 diff)
- 06/libkombilo/search.cc (modified) (28 diffs)
- 06/libkombilo/search.h (modified) (8 diffs)
- 06/libkombilo/testhash.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
06/libkombilo/cpptest.cc
r193 r194 8 8 9 9 int 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 } 11 17 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 13 21 gl.start_processing(); 14 22 directory_iterator end_itr; 15 23 // 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"; 18 26 for(directory_iterator it(path); it != end_itr; ++it) { 19 27 string n = it->string(); … … 38 46 printf("%d games.\n", gl.size()); 39 47 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 40 52 // 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"); 42 54 // vector<MoveNC> contList; 43 55 // contList.push_back(MoveNC(6,15,'X')); … … 50 62 gl.search(p, so); 51 63 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()); 56 68 printf("Search pattern:\n"); 57 69 printf("%s\n", p.printPattern().c_str()); 06/libkombilo/process.py
r182 r194 19 19 20 20 starttime = time.time() 21 algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL 21 algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL | ALGO_HASH_CORNER 22 22 try: 23 23 gl = GameList('t1.db', 'id', '', algos, 19) 06/libkombilo/search.cc
r193 r194 36 36 using std::make_pair; 37 37 using std::stack; 38 using std::sort; 38 39 39 40 PatternError::PatternError() {} … … 419 420 } 420 421 421 PatternList::PatternList(Pattern& p, int fColor, int nMove, int bsize) { 422 const 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 432 int Pattern::compose_flips(int i, int j) { 433 return composition_table[j+8*i]; 434 } 435 436 PatternList::PatternList(Pattern& p, int fColor, int nMove, int bsize) throw(PatternError) { 422 437 pattern.copy(p); 423 438 fixedColor = fColor; … … 425 440 boardsize = bsize; 426 441 special = -1; 442 flipTable = new int[16]; 443 for(int i=0; i<16; i++) flipTable[i] = -1; // (patternList() relies on this) 427 444 428 445 patternList(); 446 for(int i=0; i<16; i++) 447 if (flipTable[i] == -1) throw PatternError(); // FIXME: remove this once flipTable works ... 429 448 continuations = new Continuation[pattern.sizeX * pattern.sizeY]; 430 449 } … … 432 451 PatternList::~PatternList() { 433 452 delete [] continuations; 453 delete [] flipTable; 434 454 } 435 455 … … 499 519 if (pNew == *it) { 500 520 foundNewPattern = false; 521 flipTable[f] = flipTable[it->flip]; 501 522 break; 502 523 } 503 524 } 504 if (foundNewPattern) data.push_back(pNew); 525 if (foundNewPattern) { 526 flipTable[f] = data.size(); 527 data.push_back(pNew); 528 } 505 529 506 530 if (pNew == pattern) sy.push_back(pair<int,int>(f,0)); … … 534 558 if (!fixedColor) { 535 559 bool foundNewPattern = true; 560 int lCS_ctr = 0; 536 561 for(vector<Pattern>::iterator it = lCS.begin(); it != lCS.end(); it++) { 537 562 if (pNew1 == *it) { 538 563 foundNewPattern = false; 564 flipTable[f+8] = lCS_ctr; 539 565 break; 540 566 } 567 lCS_ctr++; 541 568 } 542 if (foundNewPattern) lCS.push_back(pNew1); 569 if (foundNewPattern) { 570 lCS.push_back(pNew1); 571 } 543 572 } 544 573 … … 550 579 } 551 580 581 int lCS_ctr = 0; 552 582 for(vector<Pattern>::iterator it = lCS.begin(); it != lCS.end(); it++) { 553 583 bool contained_in_l = false; … … 555 585 if (*it == *it_l) { 556 586 contained_in_l = true; 587 flipTable[8+it->flip] = flipTable[it_l->flip]; 557 588 break; 558 589 } 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++; 560 597 } 561 598 … … 763 800 void Algorithm::finalize_process() {} 764 801 int Algorithm::readDB(sqlite3* DB) { return 0; } 765 int Algorithm::search(PatternList& patternList, GameList& gl, SearchOptions& options) { return -1; } 802 int Algorithm::search(PatternList& patternList, GameList& gl, SearchOptions& options) { 803 printf("enter Algorithm::search\n"); 804 return -1; 805 } 766 806 767 807 Algo_signature::Algo_signature(int bsize) : Algorithm(bsize) { … … 1394 1434 if (p_ij != '.') d[i+p->sizeX*j] = p_ij; 1395 1435 else d[i+p->sizeX*j] = 0; 1396 if (p_ij == 'X' orp_ij == 'O') dNO++;1436 if (p_ij == 'X' || p_ij == 'O') dNO++; 1397 1437 } 1398 1438 } … … 1478 1518 (*it)->orientation, // pattern in question 1479 1519 x-(*it)->mx, y-(*it)->my, // pos of continuation 1480 invco, // color of continuation1520 co, // color of continuation 1481 1521 (counter.total_move_num()-(*it)->dictsF.total_move_num())>2, // tenuki? 1482 1522 gl.getCurrentWinner() … … 1915 1955 #endif 1916 1956 1957 HashhitF::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 1969 HashhitF::HashhitF() { 1970 printf("oops\n"); 1971 cont = 0; 1972 emn = 0; 1973 } 1974 1975 HashhitF::~HashhitF() { 1976 if (cont) delete cont; 1977 if (emn) delete emn; 1978 } 1979 1980 bool cmp_HashhitF(const HashhitF* a, const HashhitF* b) { 1981 return a->gameid < b->gameid; 1982 } 1983 1984 HashhitCS::HashhitCS(int GAMEID, int POSITION, bool CS) { 1985 gameid = GAMEID; 1986 position = POSITION; 1987 cs = CS; 1988 } 1989 1990 bool cmp_HashhitCS(const HashhitCS* a, const HashhitCS* b) { 1991 return a->gameid < b->gameid; 1992 } 1993 1994 1995 typedef vector<HashhitF* >* vpsip; 1996 1997 1917 1998 HashVarInfo::HashVarInfo(hashtype CHC, vector<pair<hashtype, ExtendedMoveNumber>* > * LFC, 1918 ExtendedMoveNumber* MOVENUMBER ) {1999 ExtendedMoveNumber* MOVENUMBER, int NUMSTONES) { 1919 2000 chc = CHC; 2001 numStones = NUMSTONES; 1920 2002 moveNumber = new ExtendedMoveNumber(*MOVENUMBER); 1921 2003 lfc = new vector<pair<hashtype, ExtendedMoveNumber>* >; … … 1926 2008 1927 2009 1928 Algo_hash ::Algo_hash(int bsize) : Algorithm(bsize) {2010 Algo_hash_full::Algo_hash_full(int bsize, int MAXNUMSTONES) : Algorithm(bsize) { 1929 2011 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 2015 Algo_hash_full::~Algo_hash_full() { 2016 } 2017 2018 int Algo_hash_full::insert_hash(hashtype hashCode, ExtendedMoveNumber& mn, Move* continuation) { 1936 2019 // printf("insert %lld\n", hashCode); 1937 2020 char* buf = new char[30 + mn.length*2]; … … 1951 2034 buf[6+2*i] = mn.data[i]%256; 1952 2035 } 1953 char* sql = "insert into algo_hash (hash, gameid, hit) values (?,?,?);";2036 char* sql = "insert into algo_hash_full (hash, gameid, hit) values (?,?,?);"; 1954 2037 sqlite3_stmt *ppStmt=0; 1955 2038 int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 1956 2039 if (rc != SQLITE_OK || ppStmt==0) return rc; 1957 rc = sqlite3_bind_int64(ppStmt, 1, currentHashCode);2040 rc = sqlite3_bind_int64(ppStmt, 1, hashCode); 1958 2041 if (rc != SQLITE_OK) return rc; 1959 2042 rc = sqlite3_bind_int(ppStmt, 2, gid); … … 1969 2052 } 1970 2053 1971 void Algo_hash ::initialize_process(sqlite3* DB) throw(DBError) {2054 void Algo_hash_full::initialize_process(sqlite3* DB) throw(DBError) { 1972 2055 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); 1974 2057 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); 1976 2059 if (rc != SQLITE_OK) throw DBError(); 1977 2060 } 1978 2061 1979 void Algo_hash::newgame_process(int game_id) { 2062 void Algo_hash_full::newgame_process(int game_id) { 2063 numStones = 0; 1980 2064 gid = game_id; 1981 2065 moveNumber = new ExtendedMoveNumber(0); … … 1985 2069 } 1986 2070 1987 void Algo_hash ::AB_process(int x, int y) {2071 void Algo_hash_full::AB_process(int x, int y) { 1988 2072 for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 1989 2073 Move* continuation = new Move(x,y,'B'); … … 1994 2078 delete lfc; 1995 2079 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 2084 void Algo_hash_full::AW_process(int x, int y) { 2000 2085 for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 2001 2086 Move* continuation = new Move(x,y,'W'); … … 2006 2091 delete lfc; 2007 2092 lfc = new vector<pair<hashtype, ExtendedMoveNumber>* >; 2008 currentHashCode -= hashCodes[x + boardsize*y]; 2093 currentHashCode -= Algo_hash::hashCodes[x + boardsize*y]; 2094 numStones++; 2009 2095 } 2010 2096 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)); 2097 void 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 2103 void Algo_hash_full::endOfNode_process() { 2104 if (numStones <= maxNumStones) lfc->push_back(new pair<hashtype, ExtendedMoveNumber>(currentHashCode, *moveNumber)); 2018 2105 moveNumber->next(); 2019 2106 } 2020 2107 2021 void Algo_hash ::pass_process() {2108 void Algo_hash_full::pass_process() { 2022 2109 // (we do not count pass as continuation) 2023 2110 } 2024 2111 2025 void Algo_hash ::move_process(Move m) throw(DBError) {2112 void Algo_hash_full::move_process(Move m) throw(DBError) { 2026 2113 for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 2027 2114 Move* continuation = new Move(m); … … 2034 2121 lfc = new vector<pair<hashtype, ExtendedMoveNumber>* >; 2035 2122 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++; 2037 2125 2038 2126 if (m.captures) { … … 2042 2130 int yy = it->second; 2043 2131 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 2138 void Algo_hash_full::branchpoint_process() { 2139 branchpoints->push(HashVarInfo(currentHashCode, lfc, moveNumber, numStones)); 2051 2140 // printf("push %lld\n", currentHashCode); 2052 2141 } 2053 2142 2054 void Algo_hash ::endOfVariation_process() {2143 void Algo_hash_full::endOfVariation_process() { 2055 2144 for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 2056 2145 int rc = insert_hash((*it)->first, (*it)->second, 0); … … 2063 2152 lfc = branchpoints->top().lfc; 2064 2153 moveNumber = branchpoints->top().moveNumber; 2154 numStones = branchpoints->top().numStones; 2065 2155 // printf("pop %lld\n", currentHashCode); 2066 2156 branchpoints->pop(); 2067 2157 } 2068 2158 2069 void Algo_hash ::endgame_process() {2159 void Algo_hash_full::endgame_process() { 2070 2160 for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 2071 2161 Move* continuation = 0; … … 2079 2169 } 2080 2170 2081 void Algo_hash ::finalize_process() {2082 } 2083 2084 2085 hashtype Algo_hash ::compute_hashkey(Pattern& pattern) {2171 void Algo_hash_full::finalize_process() { 2172 } 2173 2174 2175 hashtype Algo_hash_full::compute_hashkey(Pattern& pattern) { 2086 2176 if (pattern.sizeX != boardsize || pattern.sizeY != boardsize) 2087 2177 return NOT_HASHABLE; 2088 2178 hashtype hashkey = 0; 2089 2179 int ns = 0; 2090 2180 for(int i=0; i<boardsize; i++) { 2091 2181 for(int j=0; j<boardsize; j++) { 2092 2182 char p = pattern.finalPos[i + boardsize*j]; 2093 2183 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; 2098 2194 return hashkey; 2099 2195 } 2100 2196 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) { 2197 int insert_result_hf(void *results, int argc, char **argv, char **azColName) throw (DBError) { 2131 2198 vpsip res = ((pair<vpsip, int>*)results)->first; 2132 2199 int orientation = ((pair<vpsip, int>*)results)->second; 2133 2200 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(); 2139 2203 return 0; 2140 2204 } 2141 2205 2142 int Algo_hash::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { 2206 2207 int Algo_hash_full::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { 2143 2208 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; 2144 2223 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); 2160 2225 // 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(); 2163 2227 while (resultIT != results->end()) { 2164 2228 int index = (*resultIT)->gameid; … … 2204 2268 } 2205 2269 } 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; 2207 2271 delete results; 2208 2272 gl.end_sorted(); 2209 2273 } 2210 2274 return 0; 2275 } 2276 2277 // ----------------------------------------------------------------------------------- 2278 2279 Algo_hash::Algo_hash(int bsize, const string& DBNAMEEXT) : Algorithm(bsize) { 2280 dbnameext = DBNAMEEXT; 2281 maxNumStones = 20; // FIXME 2282 hi = 0; 2283 } 2284 2285 Algo_hash::~Algo_hash() { 2286 if (hi) delete hi; 2287 } 2288 2289 int 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 2309 void 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 2320 void 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 2326 void 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 2331 void 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 2336 void 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 2344 void 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 2354 void Algo_hash::pass_process() { 2355 // (we do not count pass as continuation) 2356 } 2357 2358 void 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 2380 void Algo_hash::branchpoint_process() { 2381 for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 2382 it->bppush(); 2383 } 2384 2385 void Algo_hash::endOfVariation_process() { 2386 for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 2387 it->bppop(); 2388 } 2389 2390 void Algo_hash::endgame_process() { 2391 for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 2392 it->finalize(); 2393 } 2394 2395 void Algo_hash::finalize_process() { 2396 } 2397 2398 2399 pair<hashtype,int> Algo_hash::compute_hashkey(PatternList& pl, int CS) { 2400 return make_pair(NOT_HASHABLE,0); 2401 } 2402 2403 int 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 2415 int 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 2502 Algo_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 2514 pair<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 2576 HashInstance::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 2589 HashInstance::~HashInstance() { 2590 finalize(); 2591 } 2592 2593 void 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 2608 bool 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 2613 void 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 2621 void 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 2631 void 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 2641 void 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 2651 void 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 2661 pair<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 2673 void 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 2679 void HashInstance::bppop() { 2680 delete [] currentHashCode; 2681 currentHashCode = branchpoints->top().first; 2682 numStones = branchpoints->top().second; 2683 branchpoints->pop(); 2211 2684 } 2212 2685 … … 2793 3266 algo_ps[algo_movelist] = new Algo_movelist(boardsize); 2794 3267 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 2796 3273 all = 0; 2797 3274 currentList = oldList = 0; … … 2826 3303 rc = sqlite3_exec(db, "pragma cache_size = 300000;", 0, 0, 0); 2827 3304 if (rc) throw DBError(); 3305 rc = sqlite3_exec(db, "begin transaction;", 0, 0, 0); 3306 if (rc) throw DBError(); 2828 3307 2829 3308 string sql = "select "; // those two we need in any case … … 2837 3316 readDBs = 1; 2838 3317 } else readDBs = 0; 3318 rc = sqlite3_exec(db, "commit;", 0, 0, 0); 3319 if (rc) throw DBError(); 2839 3320 2840 3321 sqlite3_close(db); … … 3111 3592 3112 3593 int hash_result = -1; 3594 // FULL BOARD PATTERN? 3113 3595 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); 3115 3597 if (hash_result == 1) { 3116 3598 } else if (hash_result == 0) { … … 3118 3600 } 3119 3601 } 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 } 3124 3617 } 3125 3618 sqlite3_close(db); 06/libkombilo/search.h
r193 r194 35 35 #ifdef __BORLANDC__ 36 36 typedef __int64 hashtype; 37 const hashtype NOT_HASHABLE = 9223372036854775807i64; 37 38 #else 38 39 typedef long long hashtype; 40 const hashtype NOT_HASHABLE = 9223372036854775807LL; 39 41 #endif 40 42 … … 115 117 static int flipsY(int i, int x, int y, int XX, int YY); 116 118 static int PatternInvFlip(int i); 119 static int compose_flips(int i, int j); // returns index of flip "first j, then i" 117 120 }; 118 121 … … 139 142 std::vector<Symmetries> symmetries; 140 143 Continuation* continuations; 144 int* flipTable; 141 145 int special; 142 146 143 PatternList(Pattern& p, int fColor, int nMove, int bsize) ;147 PatternList(Pattern& p, int fColor, int nMove, int bsize) throw (PatternError); 144 148 ~PatternList(); 145 149 … … 318 322 }; 319 323 320 const hashtype NOT_HASHABLE = 9223372036854775807LL; 321 322 323 class Hashhit { 324 325 class HashhitF { // hashing hit for full board search 324 326 public: 325 327 int gameid; … … 328 330 ExtendedMoveNumber* emn; 329 331 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 337 class HashhitCS { // hasihing hit for corner/side pattern search 338 public: 339 int gameid; 340 int position; 341 bool cs;
