root/06/libkombilo-branches/hash_center/search.h

Revision 249, 29.0 kB (checked in by ug, 1 year ago)

Merge -r 246:248 from libkombilo main branch.

Line 
1 // File: search.h
2 // part of libkombilo, http://www.u-go.net/kombilo/
3
4 // Copyright (c) 2006 Ulrich Goertz <u@g0ertz.de>
5
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of
7 // this software and associated documentation files (the "Software"), to deal in
8 // the Software without restriction, including without limitation the rights to
9 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10 // of the Software, and to permit persons to whom the Software is furnished to do
11 // so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23
24 #ifndef _SEARCH_H_
25 #define _SEARCH_H_
26
27 #include <vector>
28 #include <utility>
29 #include <stack>
30 #include <set>
31 #include <sqlite3.h>
32 #include "abstractboard.h"
33 #include "sgfparser.h"
34 typedef char* char_p;
35
36 #if (defined(__BORLANDC__) || defined(_MSC_VER))
37 typedef __int64 hashtype;
38 const hashtype NOT_HASHABLE = 9223372036854775807i64;
39 #else
40 typedef long long hashtype;
41 const hashtype NOT_HASHABLE = 9223372036854775807LL;
42 #endif
43
44 const char NO_CONT = 255;
45
46 class SnapshotVector : public std::vector<unsigned char> {
47   public:
48     SnapshotVector();
49     SnapshotVector(char* c, int size);
50
51     void pb_int(int d);
52     void pb_charp(char* c, int size);
53     void pb_char(char c);
54     void pb_string(std::string s);
55     void pb_intp(int* p, int size);
56
57     int retrieve_int();
58     int* retrieve_intp();
59     char retrieve_char();
60     char* retrieve_charp();
61     std::string retrieve_string();
62
63     char* to_charp();
64
65   private:
66     SnapshotVector::iterator current;
67 };
68
69
70 class PatternError {
71   public:
72     PatternError();
73 };
74
75 class DBError {
76   public:
77     DBError();
78 };
79
80 class Symmetries {
81   public:
82     char* dataX;
83     char* dataY;
84     char* dataCS;
85     char sizeX;
86     char sizeY;
87     Symmetries(char sX=0, char sY=0);
88     ~Symmetries();
89     Symmetries(const Symmetries& s);
90     Symmetries& operator=(const Symmetries& s);
91     void set(char i, char j, char k, char l, char cs) throw(PatternError);
92     char getX(char i, char j) throw(PatternError);
93     char getY(char i, char j) throw(PatternError);
94     char getCS(char i, char j) throw(PatternError);
95     char has_key(char i, char j) throw(PatternError);
96 };
97
98 const int CORNER_NW_PATTERN = 0;
99 const int CORNER_NE_PATTERN = 1;
100 const int CORNER_SW_PATTERN = 2;
101 const int CORNER_SE_PATTERN = 3;
102 const int SIDE_N_PATTERN = 4;
103 const int SIDE_W_PATTERN = 5;
104 const int SIDE_E_PATTERN = 6;
105 const int SIDE_S_PATTERN = 7;
106 const int CENTER_PATTERN = 8;
107 const int FULLBOARD_PATTERN = 9;
108
109 class PatternList;
110
111 class Pattern {
112   public:
113     int left; // left, right, top, bottom "==" anchors
114     int right;
115     int bottom;
116     int top;
117     int boardsize;
118
119     int sizeX;
120     int sizeY;
121
122     int flip;                  // used for elements of a patternList
123     int colorSwitch;           // dito
124     char* initialPos;
125     char* finalPos;
126     char* contLabels;
127     std::vector<MoveNC> contList;
128
129
130     // Pattern constructors
131     //
132     // the char* contLabels, if != 0, should have the same size as the pattern, and should
133     // contain pre-fixed label (which should be re-used when presenting the search results)
134     // Positions without a given label should contain '.'
135     //
136     // Note: the char*'s iPos and CONTLABELS will NOT be free'ed by the Pattern class.
137
138     Pattern();
139     Pattern(int le, int ri, int to, int bo, int BOARDSIZE, int sX, int sY, char* iPos, const std::vector<MoveNC>& CONTLIST, char* CONTLABELS = 0) throw(PatternError);
140     Pattern(int type, int BOARDSIZE, int sX, int sY, char* iPos, std::vector<MoveNC> CONTLIST, char* CONTLABELS = 0);
141     Pattern(int type, int BOARDSIZE, int sX, int sY, char* iPos, char* CONTLABELS = 0);
142     Pattern(const Pattern& p);
143     Pattern(SnapshotVector& snv);
144     ~Pattern();
145     Pattern& operator=(const Pattern& p);
146     Pattern& copy(const Pattern& p);
147
148     Pattern apply_flip(int f, bool CS = false);
149     Pattern& subpattern(int offsetX, int offsetY, int sizeX, int sizeY);
150     char getInitial(int i, int j);
151     char getFinal(int i, int j);
152
153     char BW2XO(char c);
154     int operator==(const Pattern& p);
155     std::string printPattern();
156     void to_snv(SnapshotVector& snv);
157
158     static int flipsX(int i, int x, int y, int XX, int YY);
159     static int flipsY(int i, int x, int y, int XX, int YY);
160     static int PatternInvFlip(int i);
161     static int compose_flips(int i, int j); // returns index of flip "first j, then i"
162     // static int compose_flips_CS(int i, int j); // similarly, but taking CS into account (i.e. 0<=i,j<16)
163 };
164
165 class Continuation {
166   public:
167     int B ; // number of all black continuations
168     int W ;
169     int tB; // black tenuki
170     int tW;
171     int wB; // black wins (where cont. is B)
172     int lB; // black loses (where cont. is B)
173     int wW; // black wins (where cont. is W)
174     int lW; // black loses (where cont. is W)
175     Continuation();
176     void from_snv(SnapshotVector& snv);
177     void to_snv(SnapshotVector& snv);
178 };
179
180 class PatternList {
181   public:
182     Pattern pattern;
183     int fixedColor;                      // allow switching colors
184     int nextMove;                        // 1: next must be black, 2: next must be white
185     std::vector<Pattern> data;
186     std::vector<Symmetries> symmetries;
187     Continuation* continuations;
188     // flipTable encodes the action of the group of symmetries of the square times Z/2 (for color switch)
189     // on pattern: flipTable[i] is the index in data of the pattern resulting from applying flip i and no
190     // CS (0<=i<8), or flip i-8 and CS (8<=i<16) to pattern.
191     int* flipTable;
192     // special is -1, or equal to the inverse of the flip which maps pattern to its CS'ed pattern
193     int special;
194
195     PatternList(Pattern& p, int fColor, int nMove) throw (PatternError);
196     ~PatternList();
197
198     // static char invertColor(char co);
199     void patternList();
200     Pattern get(int i);
201     int size();
202     char* updateContinuations(int orientation, int x, int y, char co, bool tenuki, char winner);
203     char* sortContinuations(); // and give them names to be used as labels
204 };
205
206 class Candidate {
207   public:
208     char x;
209     char y;
210     char orientation; // == index in corresp patternList
211
212     Candidate(char X, char Y, char ORIENTATION);
213 };
214
215 class Hit {
216   public:
217     ExtendedMoveNumber* pos;
218     char* label; // this does not really contain the label, but rather the position of the continuation move
219     Hit(ExtendedMoveNumber* POS, char* LABEL);
220     Hit(SnapshotVector& snv); // takes a SnapshotVector and reads information produced by Hit::to_snv()
221     ~Hit();
222     static bool cmp_pts(Hit* a, Hit* b);
223     void to_snv(SnapshotVector& snv);
224 };
225
226 class GameList;
227 class SearchOptions;
228
229 class Algorithm {
230   public:
231     Algorithm(int bsize);
232     virtual ~Algorithm();
233
234     virtual void initialize_process(sqlite3* DB);
235     virtual void newgame_process(int game_id);
236     virtual void AB_process(int x, int y);
237     virtual void AW_process(int x, int y);
238     virtual void AE_process(int x, int y, char removed);
239     virtual void endOfNode_process();
240     virtual void move_process(Move m);
241     virtual void pass_process();
242     virtual void branchpoint_process();
243     virtual void endOfVariation_process();
244     virtual void endgame_process(bool commit=true);
245     virtual void finalize_process();
246     virtual int readDB(sqlite3* DB);
247     virtual int search(PatternList& patternList, GameList& gl, SearchOptions& options);
248
249     int gid;
250     int boardsize;
251     sqlite3* db;
252 };
253
254 class Algo_signature : public Algorithm {
255   public:
256     Algo_signature(int bsize);
257     ~Algo_signature();
258     void initialize_process(sqlite3* DB) throw(DBError);
259     void newgame_process(int game_id);
260     void AB_process(int x, int y);
261     void AW_process(int x, int y);
262     void AE_process(int x, int y, char removed);
263     void endOfNode_process();
264     void move_process(Move m);
265     void pass_process();
266     void branchpoint_process();
267     void endOfVariation_process();
268     void endgame_process(bool commit=true) throw(DBError);
269     void finalize_process();
270
271     int counter;
272     char* signature;
273     char* get_current_signature();
274     std::vector<int> search_signature(char* sig);
275   private:
276     bool main_variation;
277 };
278
279 class Algo_finalpos : public Algorithm {
280   public:
281     Algo_finalpos(int bsize);
282     ~Algo_finalpos();
283     void initialize_process(sqlite3* DB) throw(DBError);
284     void newgame_process(int game_id);
285     void AB_process(int x, int y);
286     void AW_process(int x, int y);
287     void AE_process(int x, int y, char removed);
288     void endOfNode_process();
289     void move_process(Move m);
290     void pass_process();
291     void branchpoint_process();
292     void endOfVariation_process();
293     void endgame_process(bool commit=true) throw(DBError);
294     void finalize_process();
295
296     char* fp;
297     int fpIndex;
298     std::map<int, char* > *data;
299     int readDB(sqlite3* DB);
300     int search(PatternList& patternList, GameList& gl, SearchOptions& options);
301
302     bool equal(unsigned int id1, unsigned int id2); // id1, id2 refer to id's in the database!
303     bool equals_current(unsigned int id1);
304 };
305
306 // in x-coord:
307 const int ENDOFNODE = 128;
308 const int BRANCHPOINT = 64;
309 const int ENDOFVARIATION = 32;
310
311 // in y-coord
312 const int REMOVE = 128;
313 const int BLACK = 64;
314 const int WHITE = 32;
315
316
317 class MovelistCand {
318   public:
319     int orientation;
320     Pattern* p;
321     char* dicts;
322     ExtendedMoveNumber dictsF;
323     bool dictsFound;
324     ExtendedMoveNumber dictsFI;
325     bool dictsFoundInitial;
326     bool dictsDR;
327     int dictsNO;
328     std::vector<MoveNC> contList;
329     int contListIndex;
330     p_cc Xinterv;
331     p_cc Yinterv;
332     char mx;
333     char my;
334
335     MovelistCand(Pattern* P, int ORIENTATION, char* DICTS, int NO, char X, char Y);
336     ~MovelistCand();
337     char dictsget(char x, char y);
338     void dictsset(char x, char y, char d);
339     bool in_relevant_region(char x, char y);
340 };
341
342 class VecMC : public std::vector<MovelistCand* > {
343   public:
344     VecMC();
345     ~VecMC();
346     VecMC* deepcopy(ExtendedMoveNumber& COUNTER, int CANDSSIZE);
347     ExtendedMoveNumber counter;
348     int candssize;
349 };
350
351 class Algo_movelist : public Algorithm {
352   public:
353     Algo_movelist(int bsize);
354     ~Algo_movelist();
355     void initialize_process(sqlite3* DB) throw(DBError);
356     void newgame_process(int game_id);
357     void AB_process(int x, int y);
358     void AW_process(int x, int y);
359     void AE_process(int x, int y, char removed);
360     void endOfNode_process();
361     void move_process(Move m);
362     void pass_process();
363     void branchpoint_process();
364     void endOfVariation_process();
365     void endgame_process(bool commit=true) throw(DBError);
366     void finalize_process();
367     int readDB(sqlite3* DB);
368     int search(PatternList& patternList, GameList& gl, SearchOptions& options);
369
370     std::vector<char> movelist;
371     char* fpC;
372     std::map<int, char* > *data1;
373     std::map<int, char* > *data2;
374     std::map<int, int> *data1l;
375 };
376
377 class HashFEntry {
378   public:
379     hashtype hashCode;
380     char* buf;
381     int length;
382
383     HashFEntry(hashtype HASHCODE, char* BUF, int LENGTH);
384     HashFEntry(const HashFEntry& hfe);
385     ~HashFEntry();
386 };
387
388 class HashhitF { // hashing hit for full board search
389   public:
390     int gameid;
391     char orientation;
392     MoveNC* cont;
393     ExtendedMoveNumber* emn;
394
395     HashhitF();
396     HashhitF(int GAMEID, char ORIENTATION, char* blob);
397     ~HashhitF();
398 };
399
400
401 class HashhitCS;
402 bool cmp_HashhitCS(const HashhitCS* a, const HashhitCS* b);
403
404 class HashhitCS { // hashing hit for corner/side/center pattern search
405   friend bool cmp_HashhitCS(const HashhitCS* a, const HashhitCS* b);
406   public:
407     int gameid;
408     bool cs;
409     HashhitCS(int GAMEID, int POS, int ORI, bool CS);
410     HashhitCS(int GAMEID, int POSITION, bool CS);
411     bool operator==(const HashhitCS& hcs);
412     int get_pos();
413     int get_ori();
414
415   protected:
416     int position;
417
418 };
419
420 class HashVarInfo {
421   public:
422     hashtype chc;
423     std::vector<std::pair<hashtype, ExtendedMoveNumber>* > * lfc;
424     ExtendedMoveNumber* moveNumber;
425     int numStones;
426
427     HashVarInfo(hashtype CHC, std::vector<std::pair<hashtype, ExtendedMoveNumber>* > * LFC, ExtendedMoveNumber* MOVENUMBER, int NUMSTONES);
428 };
429
430 class Algo_hash_full : public Algorithm {
431   public:
432     Algo_hash_full(int bsize, int MAXNUMSTONES = 50);
433     ~Algo_hash_full();
434     void initialize_process(sqlite3* DB) throw(DBError);
435     void newgame_process(int game_id);
436     void AB_process(int x, int y);
437     void AW_process(int x, int y);
438     void AE_process(int x, int y, char removed);
439     void endOfNode_process();
440     void move_process(Move m) throw(DBError);
441     void pass_process();
442     void branchpoint_process();
443     void endOfVariation_process() throw(DBError);
444     void endgame_process(bool commit=true) throw(DBError);
445     void finalize_process();
446     int search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db);
447
448     hashtype compute_hashkey(Pattern& pattern);
449
450     int maxNumStones;
451     int numStones;
452   private:
453     hashtype currentHashCode;
454     ExtendedMoveNumber* moveNumber;
455     std::vector<std::pair<hashtype, ExtendedMoveNumber>* > *lfc; // hash code + move number, still looking for continuation
456     std::stack<HashVarInfo>* branchpoints;
457     int insert_hash(hashtype hashCode, ExtendedMoveNumber& mn, Move* continuation);
458     int insert_all_hashes();
459     std::vector<HashFEntry> hash_vector;
460 };
461
462 class HashInstance {
463   // When processing sgf games, Algo_hash maintains a list of HashInstance's -
464   // those are regions on the board for which hash codes are put into the
465   // database
466
467   public:
468     HashInstance(char X, char Y, char SIZEX, char SIZEY, int BOARDSIZE);
469     virtual ~HashInstance();
470     bool inRelevantRegion(char X, char Y);
471
472     char xx; // position on the board
473     char yy;
474     int pos;
475     int boardsize;
476     char sizeX; // size of the pattern
477     char sizeY;
478     bool changed;
479
480     virtual void initialize();
481     virtual void finalize();
482     virtual void add(char co, char x, char y);
483     virtual void remove(char co, char x, char y);
484     virtual void bppush();
485     virtual void bppop();
486     virtual std::pair<hashtype,int> cHC();  // returns current hash code and corresp. index
487     hashtype* currentHashCode; // array of 8 hashtype values (to automatically symmetrize hash codes)
488     std::stack<std::pair<hashtype*,int> >* branchpoints;
489     int numStones;
490 };
491
492 class HashInstanceCO : public HashInstance {
493   public:
494     HashInstanceCO(char X, char Y, char SIZEX, char SIZEY, int BOARDSIZE);
495     virtual ~HashInstanceCO();
496
497     void add(char co, char x, char y);
498     void remove(char co, char x, char y);
499 };
500
501 class CompleteHashKey;
502
503 class HashInstanceCTR : public HashInstance {
504   public:
505     HashInstanceCTR(char X, char Y, char SIZEX, char SIZEY, int BOARDSIZE);
506     virtual ~HashInstanceCTR();
507
508     void add(char co, char x, char y);
509     void remove(char co, char x, char y);
510
511     static CompleteHashKey center_hashkey(PatternList& pl, int CS);
512 };
513
514 class CompleteHashKey {
515   // returned by compute_hashkey
516   // contains the information about which subpattern was used to compute the actual hashCode
517   public:
518     hashtype hashCode;
519 //     int offsetX;
520 //     int offsetY;
521     int index; // index in corresp. patternList
522
523     CompleteHashKey(); // = NOT_HASHABLE
524     CompleteHashKey(hashtype HASHCODE, int INDEX);
525 };
526
527 class HashQuery {
528   public:
529     std::string sql;
530     PatternList* pl0;
531     PatternList* pl1;
532     int flip0;
533     int flip1;
534     int offset0;
535     int offset1;
536     hashtype hashCode0;
537
538     HashQuery();
539     HashQuery(std::string SQL,
540               PatternList* PL0, int OFF0X, int OFF0Y, int FLIP0, hashtype HASHCODE0,
541               PatternList* PL1, int OFF1X, int OFF1Y, int FLIP1);
542     ~HashQuery();
543     int get_offX();
544     int get_offY();
545 };
546
547 class HashCTREntry {
548   public:
549     std::vector<HashhitCS* > data;
550
551     HashCTREntry();
552     HashCTREntry(unsigned char* c, int l, bool cs = false);
553     ~HashCTREntry();
554
555     void add(unsigned char* c, int l, bool cs, bool do_sort = true);
556     void add(int gameid, int pos, char ori, bool cs = false, bool do_sort = true);
557     void add(int gameid, int position, bool cs = false, bool do_sort = true);
558     unsigned char* to_charp();
559     int get_length();
560 };
561
562 class Algo_hash : public Algorithm {
563   // This class should not be used by the "end-user" (see Algo_hash_corner and
564   // Algo_hash_sides instead)
565
566   public:
567     Algo_hash(int bsize, const std::string& DBNAMEEXT, int MAXNUMSTONES);
568     virtual ~Algo_hash();
569     virtual void initialize_process(sqlite3* DB) throw(DBError);
570     virtual void newgame_process(int game_id);
571     virtual void AB_process(int x, int y);
572     virtual void AW_process(int x, int y);
573     virtual void AE_process(int x, int y, char removed);
574     virtual void endOfNode_process();
575     virtual void move_process(Move m) throw(DBError);
576     virtual void pass_process();
577     virtual void branchpoint_process();
578     virtual void endOfVariation_process();
579     virtual void endgame_process(bool commit=true);
580     virtual void finalize_process();
581     virtual HashQuery searchQuery(PatternList& patternList);
582     virtual int search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db);
583
584     virtual CompleteHashKey compute_hashkey(PatternList& pl, int CS);
585     std::vector<HashInstance* >* hi;
586     static const hashtype hashCodes[];
587     std::string dbnameext;
588     int maxNumStones;
589     std::set<std::pair<hashtype, int> > hash_vector;
590     std::map<hashtype, HashCTREntry* > all_hashes;
591     virtual int insert_hash(hashtype hashCod, int pos);
592     int insert_all_hashes();
593   private:
594     sqlite3_stmt* insStmt;
595     sqlite3_stmt* updStmt;
596     sqlite3_stmt* selStmt;
597 };
598
599 class Algo_hash_corner : public Algo_hash {
600   public:
601     Algo_hash_corner(int bsize, int SIZE=7, int MAXNUMSTONES = 20);
602     CompleteHashKey compute_hashkey(PatternList& pl, int CS);
603     void initialize_process(sqlite3* DB) throw(DBError);
604     HashQuery searchQuery(PatternList& patternList);
605     int size;
606 };
607
608 // class Algo_hash_side : public Algo_hash {
609 //   public:
610 //     Algo_hash_side(int bsize, int SIZEX=6, int SIZEY=4);
611 //     int sizeX;
612 //     int sizeY;
613 // };
614
615 class Algo_hash_center : public Algo_hash {
616   public:
617     Algo_hash_center(int bsize, int L_BOUND, int U_BOUND);
618     void initialize_process(sqlite3* DB) throw(DBError);
619     void endOfNode_process();
620     HashQuery searchQuery(PatternList& patternList);
621
622     std::map<hashtype, int> data;
623   private:
624     std::map<hashtype, int> frequency;
625     int sizeX;
626     int sizeY;
627     int l_bound;
628     int u_bound;
629 };
630
631 // class UIntervals {
632 //  public:
633 //   UIntervals();
634 //
635 //   int first();
636 //   void append(UIntervals interv);
637 //   void inters(UIntervals uinterv);
638 //   int isEmpty();
639 //
640 //   std::vector<pair<int,int>> data;
641 //
642 // };
643 //
644 //
645 // class Algo_intervals : public Algorithm {
646 //  public:
647 //   Algo_intervals(int bsize);
648 //   ~Algo_intervals();
649 //
650 //   std::vector<long> movesArr;
651 //   std::vector<long> moveIntsArr;
652 //
653 //   std::vector<vector<int>*> moves;
654 //
655 //   int counter;
656 //   int ignore;
657 // };
658 //
659 // const int MAXNOMOVES = 16777215;
660 // const int FLAG_POINTER = 16777216;
661 // const int FLAG_BLACK = 33554432;
662 // const int FLAG_WHITE = 67108864;
663
664 const int ALGO_FINALPOS = 1;
665 const int ALGO_MOVELIST = 2;
666 const int ALGO_HASH_FULL = 4;
667 const int ALGO_HASH_CORNER = 8;
668 const int ALGO_INTERVALS = 16;
669 const int ALGO_HASH_CENTER = 32;
670 const int ALGO_HASH_SIDE = 64;
671
672 const int algo_finalpos = 1;
673 const int algo_movelist = 2;
674 const int algo_hash_full = 3;
675 const int algo_hash_corner = 4;
676 const int algo_intervals = 5;
677 const int algo_hash_center = 6;
678 const int algo_hash_side = 7;
679
680 typedef Algorithm* algo_p;
681
682 class ProcessOptions {
683   public:
684     bool processVariations;
685     bool sgfInDB;
686     std::string rootNodeTags; // a comma-separated list of those SGF tags which should be written to the database
687     int algos;           // algorithms to be used
688     int algo_hash_full_maxNumStones;
689     int algo_hash_corner_maxNumStones;
690
691     std::string asString();
692     void validate();
693     std::vector<std::string>* SGFTagsAsStrings();
694
695     ProcessOptions(); // sets default values which have to be overwritten
696     ProcessOptions(std::string s);
697 };
698
699 class SearchOptions {
700   public:
701     int fixedColor;
702     int nextMove; // 0 undetermined, 1 = next move must be black, 2 = next move must be white
703     int moveLimit;
704     bool trustHashFull;
705     bool searchInVariations;
706     int algos;
707
708     SearchOptions();
709     SearchOptions(int FIXEDCOLOR, int NEXTMOVE, int MOVELIMIT=10000);
710     SearchOptions(SnapshotVector& snv);
711     void to_snv(SnapshotVector& snv);
712 };
713
714 class GameListEntry {
715   public:
716     int id; // id within the concerning database
717     std::string gameInfoStr;
718     char winner;
719     std::vector<Hit* > * hits; // used for hits
720     std::vector<Candidate* > * candidates; // used for candidates
721
722     GameListEntry(int ID, char WINNER, std::string GAMEINFOSTR);
723     ~GameListEntry();
724
725     void hits_from_snv(SnapshotVector& snv);
726 };
727
728 class VarInfo {
729   public:
730     Node* n;
731     abstractBoard* b;
732     int i;
733
734     VarInfo(Node* N, abstractBoard* B, int I);
735     VarInfo(const VarInfo& v);
736     ~VarInfo();
737 };
738
739 // process flags (used to determine the behavior for individual games - in contrast to
740 // options which apply to the whole GameList and are given in ProcessOptions)
741 const int CHECK_FOR_DUPLICATES = 1; // check for duplicates using the signature
742 const int CHECK_FOR_DUPLICATES_STRICT = 2; // check for duplicates using the final position
743                                            // (if ALGO_FINAPOS is available)
744 const int OMIT_DUPLICATES = 4;
745 const int OMIT_GAMES_WITH_SGF_ERRORS = 8;
746
747 // process return values
748 // 0:   SGF error occurred when parsing the "tree structure" (i.e. before parsing the individual nodes)
749 //      database was not changed
750 // n>0: n games were processed, use process_results to access the individual results
751
752 // flags used in process_results
753 const int UNACCEPTABLE_BOARDSIZE = 1; // (database not changed)
754 const int SGF_ERROR = 2;
755     // SGF error occurred when playing through the game
756     // (and the rest of the concerning variation was not used).
757     // Depending on OMIT_GAMES_WITH_SGF_ERRORS, everything before this node (and other variations,
758     // if any) was inserted, or the database was not changed.
759 const int IS_DUPLICATE = 4;
760 const int NOT_INSERTED_INTO_DB = 8;
761 const int INDEX_OUT_OF_RANGE = 16;
762
763
764 class GameList {
765   public:
766     char* dbname;
767     std::string orderby;
768                     // constructor receives a FORMAT string; see trac wiki for the syntax to be used
769     std::string format1; // extracted from FORMAT; the column list of the sql query to retrieve the games
770     std::string format2; // extracted from FORMAT, used as template when inserting the query results into the game list
771     int numColumns;
772     int processVariations;
773
774     std::vector<int> boardsizes;
775     std::vector<algo_p> algo_ps;
776     std::vector<sqlite3*> algo_dbs;
777     std::vector<GameListEntry* > * all;
778     std::vector<std::pair<int,int> > * currentList; // pair of game id and position within all
779                                                     // (usually sorted w.r.t. second component)
780     std::vector<std::pair<int,int> > * oldList;
781     int current;
782     sqlite3* db;
783     int readDBs;
784     char* labels;
785     Continuation* continuations;
786     int num_hits;
787     int num_switched;
788     int Bwins;
789     int Wwins;
790     Pattern* mrs_pattern; // most recent search pattern
791     SearchOptions* searchOptions;
792     // ----------------------------------------------------------------------------
793     // the following methods provide the user interface
794
795     // ------- constructor --------------------------------------------------------
796     // p_options will be copied by GameList, so the caller has to free the pointer
797     GameList(char* DBNAME, std::string ORDERBY="", std::string FORMAT="", ProcessOptions* p_options=0, int cache=100) throw(DBError);
798
799     // ------- processing SGF games (to populate the db) --------------------------
800     void start_processing(int PROCESSVARIATIONS=-1) throw(DBError);
801     int process(const char* sgf, const char* path, const char* fn,
802                 const char* DBTREE = 0, int flags=0) throw(SGFError,DBError);
803     int process_results(unsigned int i=0); // result for i-th processed game in most recently processed SGF collection
804     void finalize_processing() throw(DBError);
805    
806     // int remove_game(int index); // TODO
807     // int remove_all_current_games();
808
809     // ------- pattern search -----------------------------------------------------
810     // options is copied in the search method (if != 0), so the caller has to free the pointer
811     void search(Pattern& pattern, SearchOptions* options = 0) throw(DBError);
812     char lookupLabel(char x, char y);
813     Continuation lookupContinuation(char x, char y);
814
815     // ------- signature search ---------------------------------------------------
816     // if boardsize != 0 in sigsearch, then the signature is "symmetrized" with respect
817     // to boardsize
818     void sigsearch(char* sig, int boardsize) throw(DBError);
819     std::string getSignature(int i) throw(DBError);
820
821     // ------- game info search ---------------------------------------------------
822     void gisearch(char* sql, int complete=0) throw(DBError);
823
824     // ------- tagging ------------------------------------------------------------
825     void tagsearch(int tag) throw(DBError);
826     void setTag(int tag, int start=0, int end=0) throw(DBError);
827     void deleteTag(int tag, int i = -1) throw(DBError);
828     std::vector<int> getTags(int i, int tag=0) throw(DBError); // note the order of arguments!
829
830     // ------- duplicates ---------------------------------------------------------
831     int find_duplicates(int bs, bool strict=false) throw(DBError); // return number of duplicate array
832     std::vector<int> retrieve_duplicates_VI(unsigned int i);
833     int* retrieve_duplicates_PI(unsigned int i); // same as above, but returns Pointer to Int
834