root/06/devel-old/algos.cc

Revision 175, 39.7 kB (checked in by ug, 2 years ago)

Done some more work on pattern.cc; seems to work now.

Line 
1 // File: algos.cc
2
3 //   Copyright (C) 2001-6 Ulrich Goertz (u@g0ertz.de)
4
5 //   This is part of Kombilo, a go database program.
6
7 //   This program is free software; you can redistribute it and/or modify
8 //   it under the terms of the GNU General Public License as published by
9 //   the Free Software Foundation; either version 2 of the License, or
10 //   (at your option) any later version.
11
12 //   This program is distributed in the hope that it will be useful,
13 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //   GNU General Public License for more details.
16
17 //   You should have received a copy of the GNU General Public License
18 //   along with this program (see doc/license.txt); if not, write to the Free Software
19 //   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 //   The GNU GPL is also currently available at
21 //   http://www.gnu.org/copyleft/gpl.html
22
23 #include <iostream>
24 #include <fstream>
25 using namespace std;
26
27 #include "algos.h"
28
29 // ---------------------------------------------------------------------------------------
30
31
32 string retrieve_datap0(PyObject* datapath) {
33 }
34
35 string retrieve_datap1(PyObject* datapath) {
36 }
37
38 Algorithm::Algorithm(int bsize) {
39   boardsize = bsize;
40 }
41
42
43 Algo_finalpos::Algo_finalpos(int bsize) : Algorithm(bsize) {
44   finalpos = 0;
45   finalposIndex = -1;
46   finalposSize = 0;
47   fp = 0;
48   fpIndex = -1;
49 }
50
51 Algo_finalpos::~Algo_finalpos() {
52   delete [] finalpos;
53 }
54
55
56 void Algo_finalpos::initialize_process(int l) {
57   finalposSize = l*100;
58   finalpos = new char[finalposSize];
59   finalposIndex = 0;
60 }
61
62 void Algo_finalpos::newgame_process() {
63   fp = new char[100];
64   for(int i=0; i<100; i++) fp[i] = 255;
65 }
66
67 void Algo_finalpos::AB_process(int x, int y) {
68   fp[y/2 + 10*(x/2)] &= ~(1 << (2*(x%2 + 2*(y%2))));
69 }
70
71 void Algo_finalpos::AW_process(int x, int y) {
72   fp[y/2 + 10*(x/2)] &= ~(1 << (2*(x%2 + 2*(y%2))+1));
73 }
74
75 void Algo_finalpos::AE_process(int x, int y, char removed) {
76 }
77
78 void Algo_finalpos::endOfNode_process() {
79 }
80
81 void Algo_finalpos::B_process(int x, int y, PyObject* cap) {
82   fp[y/2 + 10*(x/2)] &= ~(1 << (2*(x%2 + 2*(y%2))));
83 }
84
85 void Algo_finalpos::W_process(int x, int y, cap) {
86   fp[y/2 + 10*(x/2)] &= ~(1 << (2*(x%2 + 2*(y%2))+1));
87 }
88
89 void Algo_finalpos::branchpoint_process() {
90 }
91
92 void Algo_finalpos::endOfVariation_process() {
93 }
94
95 void Algo_finalpos::endgame_process() {
96   if (finalposIndex > finalposSize-100) printf("OOPS\n"); // FIXME (remove or throw exception)
97   for(int i=0; i<100; i++) finalpos[finalposIndex++] = fp[i];
98   delete [] fp;
99 }
100
101 void Algo_finalpos::finalize_process(PyObject* datap) {
102   String fn = retrieve_datap0(datap) + "/finalpos" + retrieve_datap1(datap) + ".db"; // FIXME: linux specific!?
103   ofstream file(fn, ios::out|ios::trunc|ios::binary) // FIXME: careful with ios::trunc
104   file.write(finalpos, finalposSize);
105   file.close();
106 }
107
108
109 int Algo_finalpos::duplicateCheck(sli, datapath) { // FIXME argument types
110   if (!strcmp(datapath, "")) {
111     for(int i=0; i<100; i++)
112       if (finalpos[sli*100+i] != fp[i])
113         return 0;
114     return 1;
115   }
116   return 0; // FIXME
117
118 //   if (strcmp(currentDatap,datap)) {
119 //     delete [] currentDatap;
120 //     currentDatap = new char[strlen(datap)+1];
121 //     strcpy(currentDatap, datap);
122 //
123 //     char* currentFP = new char[];
124 //
125 //     try {
126 //       file = open(os.path.join(datap[0], 'finalpos'+datap[1]+'.db'), 'rb');
127 //       while (1) {
128 //  try self.currentFP.fromfile(file, 1000000);
129 //  except EOFError break;
130 //       }
131 //       file.close();
132 //     }
133 //     except return 0;
134 //   }
135 //   
136 //   for(int i=0; i<100; i++)
137 //     if (currentFP[sli*100+i] != fp[i])
138 //       return 0;
139 //   return 1;   
140 }
141
142 int Algo_finalpos::retrieve_db(PyObject* datap) {
143   String fn = retrieve_datap0(datap) + "/finalpos" + retrieve_datap1(datap) + ".db"; // FIXME: linux specific!?
144   ifstream file (fn, ios::in|ios::binary|ios::ate);
145   if (file.is_open()) {
146     ifstream::pos_type size = file.tellg();
147     delete [] finalpos;
148     finalpos = new char[size];
149     file.seekg (0, ios::beg);
150     file.read (memblock, size);
151     file.close();
152     return 1;
153   }
154   else cout << "Unable to open file";
155   return 0;
156 }
157
158
159 Algo_finalpos::search(patternList, options, db, progBar, progStart, progEnd) {
160
161   int ctr = 0;
162
163   possiblePatterns = range(patternList.size());
164   index = db.start();
165   int counter = 0;
166   if (!self.retrieve_db(db.datapath)) {
167     printf("error\n"); // FIXME
168     return;
169   }
170
171   while (index != -1) {   // FIXME: db.start/next should return -1 instead of None; algosPY entsprechend aendern
172     counter++;
173     if (progBar && !(counter % 10))
174       progBar.redraw((progEnd-progStart)*counter/len(db.current) + progStart);
175
176     matchList = [];
177
178     for(N in possiblePatterns) {
179                        
180       Pattern pattern = patternList.get(N);
181       for(int a0=pattern.left; a0 <= pattern.right; a0++) {
182   for(int a1 = pattern.top; a1 <= pattern.bottom; a1++) {
183     int matches = 1;
184                                    
185     int pIndex = 2*(a1%2) + (a0%2);
186     char* patternBits = pattern.bits[pIndex]; // FIXME?
187     int pbIndex = 0;
188           int fpIndex = index*100 + a1/2 + (a0/2)*10;
189
190     for(int x=0; x<patternBits[0]; x++) {
191       char start = patternBits[pbIndex+1];
192             char length = patternBits[pbIndex+2];
193       fpIndex += start;
194       pbIndex += 2;
195       for(int y=0; y<length; y++) {
196         pbIndex++;
197         if (patternBits[pbIndex] & finalpos[fpIndex]) {
198     matches = 0;
199     break;
200         }
201         fpIndex++;
202       }
203       if (!matches) break;
204       fpIndex += 10 - start - length;
205     }               
206     if (matches) matchList.append((N,(a0,a1))); // FIXME
207   }
208       }
209     }
210
211     if (matchList) db.makeCurrentCandidate(matchList);
212     else db.discardCurrent();
213
214     index = db.next();
215   }
216 }
217
218
219
220
221
222
223 Algo_movelist::Algo_movelist(int bsize) : Algorithm(bsize) {
224 }
225
226 Algo_movelist::~Algo_movelist() {
227   delete [] finalposC;
228 }
229
230 void Algo_movelist:: initialize_process(int l) {
231
232   mainlistArr = vector<char>();
233   posTable = vector<long>();
234                    
235   finalposCSize = l*50;
236   finalposC = new char[finalposCSize];
237   finalposCIndex = 0;
238 }                                         
239
240 void Algo_movelist::newgame_process() {
241
242   movelist = vector<char>;
243
244   fpCSize = 50;
245   fpC = new char[fpCSize];
246   fpCIndex = 0;
247   for(int i=0; i<fpCSize; i++) fpC[i] = 0;
248 }
249        
250 void Algo_movelist::AB_process(int x, int y) {
251   // FIXME : safety check movelistIndex > movelistSize?
252   movelist.push_back((char)x);
253   movelist.push_back((char)(y | BLACK));
254 }
255        
256
257 void Algo_movelist::AW_process(int x, int y) {
258   movelist.push_back((char)x);
259   movelist.push_back((char)(y | WHITE));
260 }
261
262
263 void Algo_movelist::AE_process(int x, int y, char removed) {
264   movelist.push_back((char)x);
265   if (removed == 'B') movelist.push_back((char)(y | REMOVE | BLACK));
266   else if (removed == 'W') movelist.push_back((char)(y | REMOVE | WHITE));
267   else printf("oops\n");  // FIXME
268 }
269
270 void Algo_movelist::endOfNode_process() {
271   if (movelist.size()>1) {
272     if (movelist[movelist.size()-2] & ENDOFNODE) {
273       movelist.push_back(ENDOFNODE);
274       movelist.push_back(0);
275     }
276     else movelist[movelist.size()-2] |= ENDOFNODE; // FIXME: funktioniert das so?
277   }
278 }
279
280 void Algo_movelist::B_process(int x, int y, cap) {
281   if (!movelist.size()) {
282     movelist.push_back(ENDOFNODE);
283     self.movelist.push_back(0);
284   }
285   movelist.push_back(x);
286   movelist.push_back(y | BLACK);
287
288   for(x, y in cap) { // FIXME
289     movelist.push_back(x);
290     movelist.push_back(y | REMOVE | WHITE);
291     self.fpC[y/4 + 5*(x/2)] |= 1 << (x%2 + 2*(y%4));
292   }
293 }
294                
295 void Algo_movelist::W_process(int x, int y, cap) {
296   if (!movelist.size()) {
297     movelist.push_back(ENDOFNODE);
298     movelist.push_back(0);
299   }
300   movelist.push_back(x);
301   movelist.push_back(y | WHITE);
302
303   for(x, y in cap) {
304     movelist.push_back(x);
305     movelist.push_back(y | REMOVE | BLACK);
306     self.fpC[y/4 + 5*(x/2)] |= 1 << (x%2 + 2*(y%4));
307   }
308 }
309
310 void Algo_movelist::branchpoint_process() {
311   movelist.push_back(BRANCHPOINT);
312   movelist.push_back(0);
313 }
314
315 void Algo_movelist::endOfVariation_process() {
316   movelist.push_back(ENDOFVARIATION);
317   movelist.push_back(0);
318 }
319
320 void Algo_movelist::endgame_process() {
321   posTable.append(len(self.mainlistArr));
322   mainlistArr.push_back(255);
323   mainlistArr.push_back(255);
324   for(int i=0; i<movelist.size(); i++)
325     mainlistArr.push_back(movelist[i]);
326  
327   for(int i=0; i<fpCSize; i++)
328     finalposC[finalposCIndex++] = fpC[i];
329
330   delete [] fpC;
331   fpCIndex = -1;
332   fpCSize = 0;
333 }
334
335 void Algo_movelist::finalize_process(datap) {
336   String fn = retrieve_datap0(datap) + "/posTable" + retrieve_datap1(datap) + ".db"; // FIXME: linux specific!?
337   ofstream file(fn, ios::out|ios::trunc|ios::binary) // FIXME: careful with ios::trunc
338   file.write(posTable, posTableSize); // FIXME: posTable is vector, posTableSize does not exist
339   file.close();
340  
341   fn = datap0 + "/lists" + datap1 + ".db"; // FIXME: linux specific!?
342   file(fn, ios::out|ios::trunc|ios::binary) // FIXME: careful with ios::trunc
343   file.write(mainlistArr, mainlistArrSize); // FIXME: mainlistArr is vector!, mainlistArrSize does not exist
344   file.close();
345  
346   fn = datap0 + "/finalposC" + datap1 + ".db"; // FIXME: linux specific!?
347   file(fn, ios::out|ios::trunc|ios::binary) // FIXME: careful with ios::trunc
348   file.write(finalposC, finalposCSize);
349   file.close();
350 }
351
352 void Algo_movelist::retrieve_db(datap) {
353
354   String fn = retrieve_datap0(datap) + "/finalposC" + retrieve_datap1(datap) + ".db"; // FIXME: linux specific!?
355   ifstream file (fn, ios::in|ios::binary|ios::ate);
356   if (file.is_open()) {
357     ifstream::pos_type size = file.tellg();
358     delete [] finalposC;
359     finalposC = new char[size];
360     file.seekg (0, ios::beg);
361     file.read (memblock, size);
362     file.close();
363   }
364   else {
365     cout << "Unable to open file";
366     return 0;
367   }
368   fn = retrieve_datap0(datap) + "/lists" + retrieve_datap1(datap) + ".db"; // FIXME: linux specific!?
369   ifstream file (fn, ios::in|ios::binary|ios::ate);
370   if (file.is_open()) {
371     ifstream::pos_type size = file.tellg();
372     delete [] mainlistArr;
373     mainlistArr = new char[size];
374     file.seekg (0, ios::beg);
375     file.read (memblock, size);
376     file.close();
377   }
378   else {
379     cout << "Unable to open file";
380     return 0;
381   }
382   fn = retrieve_datap0(datap) + "/posTable" + retrieve_datap1(datap) + ".db"; // FIXME: linux specific!?
383   ifstream file (fn, ios::in|ios::binary|ios::ate);
384   if (file.is_open()) {
385     ifstream::pos_type size = file.tellg();
386     delete [] posTable;
387     posTable = new char[size]; // FIXME: not a char array???
388     file.seekg (0, ios::beg);
389     file.read (memblock, size);
390     file.close();
391     return 1;
392   }
393   else {
394     cout << "Unable to open file";
395     return 0;
396   }
397   return 0;
398 }
399
400
401
402 void Algo_movelist::search(patternList, options, db,
403          continuations, contLabelsIndex, contLabels,
404          progBar, progStart, progEnd) {
405
406   int numOfHits = 0;
407   int self_numOfSwitched = 0;
408   int Bwins = 0;
409   int Wwins = 0;
410
411   int movelimit = 1000;
412   int showColorSwap = 1;
413
414   if (options.has_key('movelimit')) movelimit = options['movelimit'];
415   if (options.has_key('showcolorswap')) showColorSwap = options['showcolorswap'];
416
417   if (!retrieve_db(db.datapath)) {
418     printf("error\n"); // FIXME
419     return;
420   }
421            
422   int index = db.start();
423   int gameCounter = 0;
424        
425   while (index != -1) {
426
427     gameCounter++;
428     if (progBar && !(gameCounter % 10))
429       progBar.redraw((progEnd-progStart)*gameCounter/len(db.current) + progStart);
430            
431     result = [];
432     numOfSwitched = 0;
433     branchpoints = [];
434
435     // movelist = mainlistArr;
436     int movelistIndex = posTable[index] + 2;
437
438     int endMovelist = movelistIndex;
439     while (endMovelist < mainlistArr.size() && mainlistArr[endMovelist] != 255)
440       endMovelist += 2;
441        
442     dicts = {};
443     contList = {};
444     contListIndex = {};
445     dictsNO = {};
446     Xinterv = {};
447     Yinterv = {};
448
449     for (m in db.getCurrentMatchlist()) {
450       d = {};
451       dNO = 0;
452       Pattern p = patternList.get(m[0]);
453       for(int i=0; i<p.sizeX; i++) {
454   for(int j=0; j<p.sizeY; j++) {
455     char p_ij = p.getInitial(i,j);
456     if (p_ij != '.') d[(i+m[1][0],j+m[1][1])] = p_ij;
457     if (p_ij == 'X' or p_ij == 'O') dNO++;
458   }
459       }
460
461       dicts[m] = d;
462       dictsNO[m] = dNO;
463
464       contList[m] = [];
465       for (x, y, color in p.contList)
466   contList[m].append((x+m[1][0], y+m[1][1], color));
467
468       contListIndex[m] = 0;
469       Xinterv[m] = (m[1][0], m[1][0] + p.sizeX);
470       Yinterv[m] = (m[1][1], m[1][1] + p.sizeY);
471     }
472    
473     int counter = 0;
474            
475     while (movelistIndex < endMovelist && counter <= self.movelimit) {
476
477       if (mainlistArr[movelistIndex] & BRANCHPOINT) {
478   self.branchpoints.append((deepcopy(dicts), deepcopy(dictsNO),
479           deepcopy(contList), deepcopy(contListIndex), counter));
480   movelistIndex += 2;
481   continue;
482       }
483       else if (mainlistArr[movelistIndex] & ENDOFVARIATION) {
484   if (!patternList.nextMove) {
485     for(m in dicts.keys())
486       if (dicts[m].has_key('found')) {
487         Pattern p = patternList.get(m[0]); // FIXME: besser pointer uebergeben?
488         if (p.colorSwitch) numOfSwitched++;
489         if (p.colorSwitch && showColorSwap)
490     result.append((dicts[m]['found'], '-'));
491         else result.append((dicts[m]['found'], ''));
492       }
493   }
494   dicts, dictsNO, contList, contListIndex, counter = self.branchpoints.pop();
495   movelistIndex += 2;
496   continue;
497       }
498      
499       int endOfNode = mainlistArr[movelistIndex] & ENDOFNODE;
500
501       int x = mainlistArr[movelistIndex] & 31;
502       int y = mainlistArr[movelistIndex+1] & 31;
503
504       char co;
505       char invco;
506
507       if (!(mainlistArr[movelistIndex+1] & REMOVE) && (mainlistArr[movelistIndex+1] & (BLACK | WHITE))) {
508   if (mainlistArr[movelistIndex+1] & BLACK) {
509     co = 'X';
510     invco = 'O';
511   }
512   else {
513     co = 'O';
514     invco = 'X';
515   }
516
517   for(m in dicts.keys()) {
518     if (Xinterv[m][0] <= x && x < Xinterv[m][1] && Yinterv[m][0] <= y && y < Yinterv[m][1]) {
519       if (dicts[m].has_key('found')) {
520         hit, label, contLabelsIndex, switched = patternList.updateContinuations(m[0], x, y, invco,
521                           Xinterv[m], Yinterv[m],
522                           dicts[m]['found'], counter,
523                           continuations, contLabels,
524                           contLabelsIndex,
525                           db.getCurrentWinner());
526         if (!hit) {
527     del dicts[m];
528     del dictsNO[m];
529     continue;
530         }
531        
532         numOfSwitched += switched; // FIXME: CHECK, was: patternList[m[0]].colorSwitch
533
534         if (switched && showColorSwap)
535     // FIXME: CHECK,was: (patternList[m[0]].colorSwitch or colorSwitch) and showColorSwap:
536     result.append((dicts[m]['found'], label + '-'));
537         else result.append((dicts[m]['found'], label));
538         del dicts[m];
539         del dictsNO[m];
540         continue;     // with for m in dicts.keys()
541       }
542       else if (dicts[m].has_key('foundInitial')) {
543         if ((x, y, co) == contList[m][contListIndex[m]]) {
544     contListIndex[m]++;
545     if (contListIndex[m] == len(contList[m])) {
546       dicts[m]['found'] = counter;
547       del dicts[m]['foundInitial'];
548     }
549         }
550         else {
551     if (dicts[m].has_key('dontRestore')) {
552       del dicts[m];
553       continue;
554     }
555     else {
556       contListIndex[m] = 0;
557       del dicts[m]['foundInitial'];
558     }
559         }
560       }
561                    
562       if (!dicts[m].has_key((x,y))) {
563         if (!(self.finalposC[index*50 + y/4 + 5*(x/2)] & (1 << (x%2 + 2*(y%4))))) {
564
565     if (!contListIndex[m]) {
566       del dicts[m];
567       continue;
568     }
569                 else dicts[m]['dontRestore'] = 1;
570         }
571         else {
572     dicts[m][(x,y)] = '.';
573     dictsNO[m]++;
574         }
575       }
576       else if (dicts[m][(x,y)] == lower(invco)) {
577         if (!(self.finalposC[index*50 + y/4 + 5*(x/2)] & (1 << (x%2 + 2*(y%4))))) {
578     if (!contListIndex[m]) {
579       del dicts[m];
580       continue;
581     }
582     else dicts[m]['dontRestore'] = 1;
583         }
584         else dictsNO[m]++;
585       }
586       else if (dicts[m][(x,y)] == co) {
587         del dicts[m][(x,y)];
588         dictsNO[m]--;
589       }
590     }
591   }
592       }
593       else if (mainlistArr[movelistIndex+1] & REMOVE) {
594   if (mainlistArr[movelistIndex+1] & BLACK) {
595     co = 'X';
596     invco = 'O';
597   }
598   else if mainlistArr[movelistIndex+1] & WHITE {
599     co = 'O';
600     invco = 'X';
601   }
602   else printf("oops\n"); // FIXME
603
604   for (m in dicts.keys()) {
605     if (!dicts[m].has_key('found')) {
606       if (Xinterv[m][0] <= x && x < Xinterv[m][1] && Yinterv[m][0] <= y && y < Yinterv[m][1]) {
607         if (dicts[m].has_key('foundInitial')) {
608     int ii = contListIndex[m];
609     while (ii < len(contList[m]) && contList[m][ii][2] == '-' &&
610            (x != contList[m][ii][0] || y != contList[m][ii][1]))
611       ii++;
612     if (ii < len(contList[m]) && contList[m][ii][2] == '-') {
613       help = contList[m][ii];
614       contList[m][ii] = contList[m][contListIndex[m]];
615       contlist[contListIndex[m]] = help;
616
617       contListIndex[m]++;
618     }
619     else {
620       if (dicts[m].has_key('dontRestore')) {
621         del dicts[m];
622         continue;
623       }
624       else {
625         contListIndex[m] = 0;
626         del dicts[m]['foundInitial'];
627       }
628     }
629         }
630         if (!dicts[m].has_key((x,y))) {
631     dicts[m][(x,y)] = co;
632     dictsNO[m]++;
633         }
634         else if (dicts[m][(x,y)] == lower(invco)) {
635     dictsNO[m]--;
636         }
637         else if (dicts[m][(x,y)] == '.') {
638     del dicts[m][(x,y)];
639     dictsNO[m]--;
640         }
641       }
642     }
643   }
644       }
645
646       if (endOfNode) {
647   for (m in dicts.keys()) {
648     if (!dictsNO[m] && !dicts[m].has_key('found') && !dicts[m].has_key('foundInitial'))
649       if (contListIndex[m] == len(contList[m])) dicts[m]['found'] = counter;
650       else dicts[m]['foundInitial'] = counter;
651   }
652  
653   counter++;
654       }
655                    
656       if (dicts=={} && !self.branchpoints) break;
657       movelistIndex += 2;
658     }
659
660     if (!patternList.nextMove) {
661       for (m in dicts.keys()) {
662   Pattern p = patternList.get(m[0]);
663   if (dicts[m].has_key('found')) {
664     if (p.colorSwitch) numOfSwitched++;
665     if (p.colorSwitch && showColorSwap) result.append((dicts[m]['found'], '-'));
666     else result.append((dicts[m]['found'], ''));
667   }
668       }
669     }
670
671     if (result) {
672       numOfHits += len(result);
673       self_numOfSwitched += numOfSwitched;
674            
675       if (db.getCurrentWinner() == 'B') {
676   Bwins += len(result) - numOfSwitched;
677   Wwins += Wwins + numOfSwitched;
678       }
679       else if (db.getCurrentWinner() == 'W') {
680   Bwins += numOfSwitched;
681   Wwins += len(result) - numOfSwitched;
682       }
683       result.sort();
684       db.makeCurrentHit(join([str(x[0])+x[1] for x in result], ', '));
685     }
686     else db.discardCurrent();
687
688     index = db.next();
689   }
690   return numOfHits, Bwins, Wwins, self.numOfSwitched;
691 }
692    
693
694 // Algo_hash::Algo_hash(int bsize, plist, char* fname) : ALgorithm(bsize) {
695 //   poslist = [[0,0] + p for p in plist];
696 //   filename = new char[strlen(fname)+1];
697 //   strcpy(filename, fname);
698 // }
699 //
700 // Algo_hash::~Algo_hash() {
701 //   delete [] filename;
702 // }
703 //
704 // void Algo_hash::initialize_process(l) {
705 //   hash_global = hashTable(l, self.filename);
706 //   gameCtr = 0;
707 // }
708 //         
709 // void Algo_hash::newgame_process() {
710 //
711 //   for (p in self.poslist) {
712 //     p[0] = 0;
713 //     p[1] = 0;
714 //   }
715 //
716 //   hash_global.newCtr(gameCtr);
717 //   branchpoints = [];
718 // }
719 //
720 // void Algo_hash::AB_process(int x, int y) {
721 //   for (p in self.poslist) {
722 //     if (p[2] <= x && x <= p[4] && p[3] <= y && y <= p[5]) {
723 //       p[0]++;
724 //       p[1] += hashTable.hash_value[(x,y)];
725 //     }
726 //   }
727 // }
728 //
729 // void Algo_hash::AW_process(int x, int y) {
730 //   for (p in self.poslist) {
731 //     if (p[2] <= x && x <= p[4] && p[3] <= y && y <= p[5]) {
732 //       p[0]++;
733 //       p[1] -= hashTable.hash_value[(x,y)];
734 //     }
735 //   }
736 // }                 
737 //
738 // void Algo_hash::AE_process(int x, int y, char removed) {
739 //   int epsilon;
740 //   if (removed == 'B') epsilon = -1;
741 //   else epsilon = 1;
742 //   
743 //   for (p in self.poslist) {
744 //     if (p[2] <= x && x <= p[4] && p[3] <= y && y <= p[5]) {
745 //       p[0]--;
746 //       p[1] += epsilon * hashTable.hash_value[(x,y)];
747 //     }
748 //   }
749 // }
750 //
751 // void Algo_hash::endOfNode_process() {
752 //   for(p in self.poslist)
753 //     if (p[0] <= p[6]) self.hash_global.append(p[1]);
754 // }
755 //
756 // void Algo_hash::B_process(int x, int y, cap) {
757 //   self.move_process(x, y, cap, 1);
758 // }
759 //
760 // void Algo_hash::W_process(int x, int y, cap) {
761 //   self.move_process(x, y, cap, -1);
762 // }
763 //
764 // void Algo_hash::move_process(int x, int y, cap, epsilon) {
765 //   for (p in self.poslist)
766 //     if (p[2] <= x && x <= p[4] && p[3] <= y && y <= p[5]) {
767 //       p[0]++;
768 //       p[1] += epsilon * hashTable.hash_value[(x,y)];
769 //     }
770 //   
771 //   for (c in cap) {
772 //     for(p in self.poslist)
773 //       if (p[2] <= c[0] && c[0] <= p[4] && p[3] <= c[1] && c[1] <= p[5]) {
774 //  p[0] -= 1;
775 //  p[1] += epsilon * hashTable.hash_value[c];
776 //       }
777 //   }
778 // }
779 //
780 // void Algo_hash::branchpoint_process() {
781 //   branchpoints.append(deepcopy(self.poslist));
782 // }
783 //
784 // void Algo_hash::endOfVariation_process() {
785 //   poslist = self.branchpoints.pop();
786 // }
787 //
788 // void Algo_hash::endgame_process() {
789 //   gameCtr++;
790 // }
791 // 
792 // void Algo_hash::finalize_process(PyObject* datap) {
793 //   hash_global.newCtr(gameCtr);
794 //   hash_global.sortedOutput(datap);
795 // }
796 //
797 //
798 // long Algo_hash::compute_hashkey(Pattern pattern, type) {
799 //
800 //   int numOfStones = 0;
801 //
802 //   a0,b0,a1,b1, maxNumOfStones = type;
803 //   long hashkey = 0;
804 //             
805 //   for(int i=a0, i<a1+1; i++) {
806 //     for(int j=b0; j<b1+1; j++) {
807 //       if (pattern.data[i-pattern.anchors[0][0]][j-pattern.anchors[0][1]] in ['x', 'o', '*'])
808 //  return NOT_HASHABLE;
809 //       else if (pattern.data[i-pattern.anchors[0][0]][j-pattern.anchors[0][1]] == 'X') {
810 //  hashkey += hashTable.hash_value[(i,j)];
811 //  numOfStones += 1;
812 //       }
813 //       else if (pattern.data[i-pattern.anchors[0][0]][j-pattern.anchors[0][1]] == 'O') {
814 //  hashkey -= hashTable.hash_value[(i,j)];
815 //  numOfStones += 1;
816 //       }
817 //     }
818 //     if numOfStones > maxNumOfStones: return NOT_HASHABLE;
819 //   }
820 //   return hashkey;
821 // }
822 //
823 // int Algo_hash::retrieve_db(PyObject* datap) {
824 //  String fn = ... filename ...; // FIXME
825 //  ifstream file (fn, ios::in|ios::binary|ios::ate);
826 //  if (file.is_open()) {
827 //    ifstream::pos_type size = file.tellg();
828 //    delete [] hash;
829 //    hash = new char[size]; // FIXME: not a char array?
830 //    file.seekg (0, ios::beg);
831 //    file.read (memblock, size);
832 //    file.close();
833 //  }
834 //   else {
835 //    cout << "Unable to open file";
836 //    return 0;
837 //  }
838 //  String fn = ... filename + "T" ...; // FIXME
839 //  ifstream file (fn, ios::in|ios::binary|ios::ate);
840 //  if (file.is_open()) {
841 //    ifstream::pos_type size = file.tellg();
842 //    delete [] hashT;
843 //    hashT = new char[size];
844 //    file.seekg (0, ios::beg);
845 //    file.read (memblock, size);
846 //    file.close();
847 //  }
848 //   else {
849 //    cout << "Unable to open file";
850 //    return 0;
851 //  }
852 //   return 0;
853 // }
854 //
855 // void Algo_hash::search(patternList, options, db, progBar, progStart, progEnd) {
856 //   for(int i=0; i<patternList.size(); i++) {
857 //     Pattern pattern = patternList.get(i);
858 //     pattern_hashkeys = {};
859 //             
860 //     for(int a0=pattern.left; a0<=pattern.right; a0++) {
861 //       for(int a1=pattern.top; a1<=pattern.bottom; a1++) {
862 //  pattern_hashkeys[(a0,a1)] = [];
863 //  for(p in self.poslist) {
864 //    if (a0 <= p[2] && a0+pattern.sizeX >= p[4] a1 <= p[3] && a1+pattern.sizeY >= p[5]) {
865 //      hk = self.compute_hashkey(pattern, p[2:]);
866 //
867 //      if (hk != NOT_HASHABLE) pattern.hashkeys[(a0,a1)].append([hk]);
868 //    }
869 //  }
870 //  if (!pattern.hashkeys[(a0,a1)]) return;
871 //       }
872 //     }
873 //   }
874 //         
875 //   if (!self.retrieve_db(db.datapath)) {
876 //     printf("error\n"); // FIXME
877 //     return;
878 //   }
879 //         
880 //   for(int N=0; N<patternList.size(); N++) {
881 //     Pattern pattern = patternList.get(N);
882 //             
883 //     for(int a0=pattern.left; a0<=pattern.right; a0++) {
884 //       for(int a1=pattern.top; a1<=pattern.bottom; a1++) {
885 //             
886 //  for(int hk=0; hk<len(pattern.hashkeys[(a0,a1)]); hk++) {
887 //
888 //    int hashkey = pattern.hashkeys[(a0,a1)][hk][0];
889 //    int start = 0;
890 //    int end = len(self.hashT)/2;
891 //                   
892 //    int hash_start;
893 //    int hash_end;
894 //
895 //    while (start < end) {
896 //      int help = self.hashT[2*((start+end)/2)];
897 //      if (help == hashkey) {
898 //        hash_start = self.hashT[2*((start+end)/2)+1];
899 //        if (2*((start+end)/2)+3 >= len(self.hashT)) hash_end = len(hash);
900 //        else hash_end = self.hashT[2*((start+end)/2)+3];
901 //
902 //        pattern.hashkeys[(a0,a1)][hk].extend([hash_start, hash_start, hash_end]);
903 //        break;