root/06/devel-old/pattern.cc

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

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

Line 
1 // File: pattern.cc
2
3 //   Copyright (C) 2001-6 Ulrich Goertz (u@g0ertz.de)
4
5 //   This file is part of Kombilo 0.6, 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 // --------------------------------------------------------------------------
24
25 #include "pattern.h"
26 #include <iostream>
27
28 Symmetries::Symmetries(int sX, int sY) {
29   cout << "Enter method Symmetries::Symmetries" << endl;
30   sizeX = sX;
31   sizeY = sY;
32   dataX = new int[sizeX*sizeY];
33   dataY = new int[sizeX*sizeY];
34   dataCS = new int[sizeX*sizeY];
35   for(int i=0; i<sizeX*sizeY; i++) {
36     dataX[i] = -1;
37     dataY[i] = -1;
38     dataCS[i] = -1;
39   }
40   special = -1;
41 }
42
43
44 Symmetries::~Symmetries() {
45   delete [] dataX;
46   delete [] dataY;
47   delete [] dataCS;
48 }
49
50 Symmetries::Symmetries(const Symmetries& s) {
51   sizeX = s.sizeX;
52   sizeY = s.sizeY;
53   dataX = new int[sizeX*sizeY];
54   dataY = new int[sizeX*sizeY];
55   dataCS = new int[sizeX*sizeY];
56   for(int i=0; i<sizeX*sizeY; i++) {
57     dataX[i] = s.dataX[i];
58     dataY[i] = s.dataY[i];
59     dataCS[i] = s.dataCS[i];
60   }
61   special = s.special;
62 }
63
64 Symmetries& Symmetries::operator=(const Symmetries& s) {
65   if (&s != this) {
66     sizeX = s.sizeX;
67     sizeY = s.sizeY;
68     delete [] dataX;
69     delete [] dataY;
70     delete [] dataCS;
71     dataX = new int[sizeX*sizeY];
72     dataY = new int[sizeX*sizeY];
73     dataCS = new int[sizeX*sizeY];
74     for(int i=0; i<sizeX*sizeY; i++) {
75       dataX[i] = s.dataX[i];
76       dataY[i] = s.dataY[i];
77       dataCS[i] = s.dataCS[i];
78     }
79     special = s.special;
80   }
81   return *this;
82 }
83
84 void Symmetries::set(int i, int j, int k, int l, int cs) {
85   if (0 <= i && i < sizeX && 0 <= j && j < sizeY) {
86     dataX[i + j*sizeX] = k;
87     dataY[i + j*sizeX] = l;
88     dataCS[i + j*sizeX] = cs;
89   }
90   else printf("Error Symmetries1\n"); // FIXME
91 }
92
93 int Symmetries::getX(int i, int j) {
94   if (0 <= i && i < sizeX && 0 <= j && j < sizeY) return dataX[i + j*sizeX];
95   else printf("Error Symmetries2\n"); // FIXME
96   return -1;
97 }
98
99 int Symmetries::getY(int i, int j) {
100   if (0 <= i && i < sizeX && 0 <= j && j < sizeY) return dataY[i + j*sizeX];
101   else printf("Error Symmetries3\n"); // FIXME
102   return -1;
103 }
104
105 int Symmetries::getCS(int i, int j) {
106   if (0 <= i && i < sizeX && 0 <= j && j < sizeY) return dataCS[i + j*sizeX];
107   else printf("Error Symmetries4\n"); // FIXME
108   return -1;
109 }
110
111 int Symmetries::has_key(int i, int j) {
112   if (0 <= i && i < sizeX && 0 <= j && j < sizeY) {
113     if (dataX[i + j*sizeX] == -1) return 0;
114     else return 1;
115   }
116   else printf("Error Symmetries5\n"); // FIXME
117   return 0;
118 }
119
120
121
122 // ----------- class Pattern -----------------------------------------------
123
124 int Pattern::operator==(const Pattern& p) {
125   if (sizeX != p.sizeX || sizeY != p.sizeY) return 0;
126   if (left != p.left || right != p.right || top != p.top || bottom != p.bottom) return 0;
127   if (moveOne != p.moveOne) return 0;
128   for(int i=0; i < sizeX*sizeY; i++)
129     if (initialPos[i] != p.initialPos[i]) return 0;
130   for(int i=0; i < 4*lenContList; i++)
131     if (contList[i] != p.contList[i]) return 0;
132   return 1;
133 }
134
135
136 char Pattern::BW2XO(char c) {
137   if (c == 'B') return 'X';
138   if (c == 'W') return 'O';
139   return c;
140 }
141
142 char Pattern::getInitial(int i, int j) {
143   return initialPos[i + sizeX*j];
144 }
145  
146 char Pattern::getFinal(int i, int j) {
147   return finalPos[i + sizeX*j];
148 }
149  
150 int Pattern::getBits(int b, int i) {
151   return (int)bits[b][i];
152 }
153
154
155 Pattern::Pattern() {
156   // cout << "Enter method Pattern::Pattern()" << endl;
157   initialPos = 0;
158   finalPos = 0;
159   contList = 0;
160   bits = 0;
161   bitlengths = 0; // FIXME?!
162 }
163
164
165 Pattern::Pattern(int le, int ri, int to, int bo, int sX, int sY,
166                  char* iPos, char* cList, int lenCList, char mOne) {
167   // cout << "Enter method Pattern::Pattern" << endl;
168   flip = 0;
169   colorSwitch = 0;
170   if (mOne=='B' || mOne=='X') moveOne = 'X';
171   else moveOne = 'O';
172   if (moveOne == 'X') moveTwo = 'O';
173   else moveTwo = 'X';
174        
175   left = le;
176   right = ri;
177   top = to;
178   bottom = bo;
179
180   // anchors.sort();
181         
182   sizeX = sX;
183   sizeY = sY;
184
185   initialPos = new char[sizeX * sizeY];
186   finalPos = new char[sizeX*sizeY];
187   for(int i=0; i<sizeX*sizeY; i++) {
188     initialPos[i] = iPos[i];
189     finalPos[i] = iPos[i];
190   }
191
192   lenContList = lenCList;
193   contList = new char[lenCList*4+1];
194   for(int i=0; i<4*lenCList; i++) contList[i] = cList[i];
195   for(int i=0; i<lenContList; i++) {
196     finalPos[contList[4*i] + sizeX * contList[4*i+1]] = BW2XO(contList[4*i+2]);
197   }
198   contList[lenCList*4] = 0;
199
200   bits = new charp[4];
201   bitlengths = new int[4];
202
203   for(int i=0; i<2; i++) {
204     for(int j=0; j<2; j++) {
205       int xBlocks = (sizeY+i+1)/2;
206       int yBlocks = (sizeX+j+1)/2;
207       char* nextBlock = new char[400];
208       int nextBlockIndex = 0;
209       nextBlock[nextBlockIndex++] = yBlocks;
210
211       for(int k1=0; k1 < yBlocks; k1++) {
212         char nlist[400];
213         int nlistIndex = 0;
214
215         for(int k2=0; k2 < xBlocks; k2++) {
216           int n = 0;
217           for(int x=0; x<2; x++) {
218             for(int y=0; y<2; y++) {
219               int indexX = k1 * 2 + y - j;
220               int indexY = k2 * 2 + x - i;
221               if (0 <= indexX && indexX < sizeX && 0 <= indexY && indexY < sizeY) {
222                 if (getFinal(indexX,indexY)=='X')
223                   n |= 1 << (2*(2*x+y));
224                 else if (getFinal(indexX,indexY)=='O')
225                   n |= 1 << (2*(2*x+y)+1);
226               }
227             }
228           }
229           nlist[nlistIndex++] = n;
230         }             
231
232         int start = 0;
233         int end = nlistIndex;
234
235         while (start < end && !nlist[start]) start++;
236         while (end > start && !nlist[end-1]) end--;
237
238         nextBlock[nextBlockIndex++] = start;
239         nextBlock[nextBlockIndex++] = end-start;
240         for(int current=start; current < end; current++)
241           nextBlock[nextBlockIndex++] = nlist[current];
242       }
243       char* nB = new char[nextBlockIndex];
244       for(int ii=0; ii<nextBlockIndex; ii++) nB[ii] = nextBlock[ii];
245       bitlengths[2*i + j] = nextBlockIndex;
246       bits[2*i + j] = nB;
247       delete [] nextBlock;
248     }
249   }
250   // cout << "Leave method Pattern::Pattern(...)" << endl;
251 }
252
253 Pattern::~Pattern() {
254   // cout << "Enter method Pattern::~Pattern" << endl;
255   if (initialPos) delete [] initialPos;
256   if (finalPos) delete [] finalPos;
257   if (contList) delete [] contList;
258   if (bitlengths) {
259     delete [] bitlengths;
260     for(int i=0; i<4; i++)
261       if (bits[i]) delete [] bits[i];
262     delete [] bits;
263   }
264   // cout << "Leave method Pattern::~Pattern" << endl;
265 }
266
267 Pattern::Pattern(const Pattern& p) {
268   // cout << "Enter method Pattern::Pattern(const Pattern&)" << endl;
269   left = p.left;
270   right = p.right;
271   top = p.top;
272   bottom = p.bottom;
273   sizeX = p.sizeX;
274   sizeY = p.sizeY;
275   flip = p.flip;
276   colorSwitch = p.colorSwitch;
277   moveOne = p.moveOne;
278   moveTwo = p.moveTwo;
279
280   initialPos = new char[sizeX*sizeY];
281   finalPos = new char[sizeX*sizeY];
282   for(int i=0; i<sizeX*sizeY; i++) {
283     initialPos[i] = p.initialPos[i];
284     finalPos[i] = p.finalPos[i];
285   }
286   lenContList = p.lenContList;
287   if (lenContList) {
288     contList = new char[lenContList*4];
289     for(int i = 0; i < lenContList*4; i++) contList[i] = p.contList[i];
290   }
291   else contList = 0;
292   if (p.bitlengths) {
293     bits = new charp[4];
294     bitlengths = new int[4];
295
296     for(int i=0; i<4; i++) {
297       bitlengths[i] = p.bitlengths[i];
298       if (bitlengths[i]>0) bits[i] = new char[bitlengths[i]];
299       else {
300         bits[i] = 0;
301         continue;
302       }
303       for(int j=0; j<bitlengths[i]; j++)
304         bits[i][j] = p.bits[i][j];
305     }
306   }
307   else {
308     bits = 0;
309     bitlengths = 0;
310   }
311 }
312
313 Pattern& Pattern::copy(const Pattern& p) {
314   cout << "Enter method Pattern::copy" << endl;
315   if (&p != this) {
316     left = p.left;
317     right = p.right;
318     top = p.top;
319     bottom = p.bottom;
320     sizeX = p.sizeX;
321     sizeY = p.sizeY;
322     flip = p.flip;
323     colorSwitch = p.colorSwitch;
324     moveOne = p.moveOne;
325     moveTwo = p.moveTwo;
326
327     if (initialPos) delete [] initialPos;
328     if (finalPos) delete [] finalPos;
329     if (contList) delete [] contList;
330     if (bits) delete [] bits;
331     if (bitlengths) delete [] bitlengths;
332    
333     initialPos = new char[sizeX*sizeY];
334     finalPos = new char[sizeX*sizeY];
335     for(int i=0; i<sizeX*sizeY; i++) {
336       initialPos[i] = p.initialPos[i];
337       finalPos[i] = p.finalPos[i];
338     }
339     lenContList = p.lenContList;
340     contList = new char[lenContList*4+1];
341     for(int i = 0; i < lenContList*4; i++) contList[i] = p.contList[i];
342     contList[lenContList*4] = 0;
343
344     if (p.bitlengths) {
345       bits = new charp[4];
346       bitlengths = new int[4];
347
348       for(int i=0; i<4; i++) {
349         bitlengths[i] = p.bitlengths[i];
350         if (bitlengths[i]>0) bits[i] = new char[bitlengths[i]];
351         else {
352           bits[i] = 0;
353           continue;
354         }
355         for(int j=0; j<bitlengths[i]; j++)
356           bits[i][j] = p.bits[i][j];
357       }
358     }
359     else {
360       bits = 0;
361       bitlengths = 0;
362     }
363   }
364   return *this;
365   cout << "Leave method Pattern::copy " << endl;
366 }
367
368 void Pattern::printPattern() {
369   printf("print pattern\n");
370 }
371
372
373 int Pattern::flipsX(int i, int x, int y, int XX, int YY) {
374   if (i==0) return x;
375   if (i==1) return XX-x;
376   if (i==2) return x;
377   if (i==3) return XX-x;
378   if (i==4) return y;
379   if (i==5) return YY-y;
380   if (i==6) return y;
381   if (i==7) return YY-y;
382   return -1;
383 }
384
385 int Pattern::flipsY(int i, int x, int y, int XX, int YY) {
386   if (i==0) return y;
387   if (i==1) return y;
388   if (i==2) return YY-y;
389   if (i==3) return YY-y;
390   if (i==4) return x;
391   if (i==5) return x;
392   if (i==6) return XX-x;
393   if (i==7) return XX-x;
394   return -1;
395 }
396
397
398 int Pattern::PatternInvFlip(int i) {
399   if (i == 5) return 6;
400   if (i == 6) return 5;
401   return i;
402 }
403
404 PatternList::PatternList(Pattern& p, int fColor, int nMove, int bsize) {
405   // cout << "Enter method PatternList::PatternList(...)" << endl;
406   pattern.copy(p);
407   fixedColor = fColor;
408   nextMove = nMove;
409   boardsize = bsize;
410   // cout << "BP1" << endl;
411
412   data = patternList();
413   // cout << "Leave method PatternList::PatternList(...)" << endl;
414 }
415
416
417 PatternList::PatternList(const PatternList& pl) {
418   printf("OUCH. Copy constructor for PatternList needed.\n"); // FIXME
419 }
420
421 PatternList& PatternList::operator=(const PatternList& pl) {
422   printf("OUCH. operator= for PatternList needed.\n"); // FIXME
423   return *this;
424 }
425
426        
427 char PatternList::invertColor(char co) {
428   if (co == 'X') return 'O';
429   if (co == 'x') return 'o';
430
431   if (co == 'O') return 'X';
432   if (co == 'o') return 'x';
433
434   return co;
435 }
436        
437 vector<Pattern> PatternList::patternList() {
438   cout << "Enter method PatternList::patternList" << endl;
439        
440   vector<Pattern> l;
441   vector<Pattern> lCS;
442   vector<pair<int,int> > sy;
443   int special = -1;
444
445   for(int f = 0; f < 8; f++) {
446     int newSizeX = max(Pattern::flipsX(f,0,0,pattern.sizeX,pattern.sizeY),
447                        Pattern::flipsX(f,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
448     int newSizeY = max(Pattern::flipsY(f,0,0,pattern.sizeX,pattern.sizeY),
449                        Pattern::flipsY(f,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
450
451     int newLeft = min(Pattern::flipsX(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
452                       Pattern::flipsX(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
453                                       boardsize-1,boardsize-1));
454     int newRight = max(Pattern::flipsX(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
455                        Pattern::flipsX(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
456                                        boardsize-1,boardsize-1)) - (newSizeX-1);
457     int newTop = min(Pattern::flipsY(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
458                      Pattern::flipsY(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
459                                      boardsize-1,boardsize-1));
460     int newBottom = max(Pattern::flipsY(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
461                         Pattern::flipsY(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
462                         boardsize-1,boardsize-1)) - (newSizeY - 1);
463
464     // printf("%d, %d, %d, %d, %d, %d, %d\n", f, newSizeX, newSizeY, newLeft, newRight, newTop, newBottom);
465     char* newInitialPos = new char[pattern.sizeX*pattern.sizeY];
466     for(int i=0; i<pattern.sizeX; i++) {
467       for(int j=0; j<pattern.sizeY; j++) {
468         newInitialPos[Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1) + \
469                       newSizeX*Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1)] = pattern.getInitial(i, j);
470       }
471     }
472
473     char* newContList = new char[pattern.lenContList*4+1];
474     for(int i=0; i<pattern.lenContList; i++) {
475       newContList[4*i] = Pattern::flipsX(f, pattern.contList[4*i], pattern.contList[4*i+1],
476                                          pattern.sizeX-1,pattern.sizeY-1);
477       newContList[4*i+1] = Pattern::flipsY(f, pattern.contList[4*i], pattern.contList[4*i+1],
478                                               pattern.sizeX-1,pattern.sizeY-1);
479       newContList[4*i+2] = pattern.contList[4*i+2];
480       newContList[4*i+3] = '/'; // FIXME: ist doch so Verschwendung
481     }
482     newContList[pattern.lenContList*4] = 0;
483
484     // cout << "BP0" << endl;
485     Pattern pNew(newLeft, newRight, newTop, newBottom, newSizeX, newSizeY,
486                  newInitialPos, newContList, pattern.lenContList, pattern.moveOne);
487
488     pNew.flip = f;
489     // cout << "BP1" << endl;
490
491     delete [] newInitialPos;
492     delete [] newContList;
493     // cout << "BP1.5" << endl;
494
495     vector<Pattern>::iterator it;
496     bool foundNewPattern = true;
497     for(it = l.begin(); it != l.end(); it++) {
498       if (pNew == *it) {
499         foundNewPattern = false;
500         break;
501       }
502     }
503     if (foundNewPattern) l.push_back(pNew);
504
505     if (pNew == pattern) sy.push_back(pair<int,int>(f,0));
506     // cout << "BP2" << endl;
507
508     if (nextMove || !fixedColor) {
509       // FIXME: nach flip "entspricht" links oben nicht mehr 0,0, also newInitialPos, newContList anpassen
510       // FIXME ... verstehe diese Bemerkung nicht!!!
511       // FIXME
512       char* newInitialPos = new char[pattern.sizeX*pattern.sizeY];
513       for(int i=0; i<pattern.sizeX; i++) {
514         for(int j=0; j<pattern.sizeY; j++) {
515           newInitialPos[Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1) + newSizeX*Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1)] =
516             invertColor(pattern.getInitial(i, j));
517         }
518       }
519
520       char* newContList = new char[pattern.lenContList*4+1];
521       for(int i=0; i<pattern.lenContList; i++) {
522         newContList[4*i] = Pattern::flipsX(f, pattern.contList[4*i], pattern.contList[4*i+1], pattern.sizeX-1,pattern.sizeY-1);
523         newContList[4*i+1] = Pattern::flipsY(f, pattern.contList[4*i], pattern.contList[4*i+1], pattern.sizeX-1,pattern.sizeY-1);
524         newContList[4*i+2] = invertColor(pattern.contList[4*i+2]);
525         newContList[4*i+3] = '/'; // FIXME siehe oben
526       }
527       newContList[pattern.lenContList*4] = 0;
528
529       Pattern pNew1(newLeft, newRight, newTop, newBottom, newSizeX, newSizeY,
530                     newInitialPos, newContList, pattern.lenContList, pattern.moveTwo);
531       pNew1.flip = f;
532       pNew1.colorSwitch = 1;
533
534       delete [] newInitialPos;
535       delete [] newContList;
536
537       if (!fixedColor) {
538         vector<Pattern>::iterator it;
539         bool foundNewPattern = true;
540         for(it = lCS.begin(); it != lCS.end(); it++) {
541           if (pNew1 == *it) {
542             foundNewPattern = false;
543             break;
544           }
545         }
546         if (foundNewPattern) l.push_back(pNew1);
547       }
548
549       if (pNew1 == pattern) {
550         if (!fixedColor) sy.push_back(pair<int,int>(f,1));
551         if (nextMove) special = f;
552       }
553     }
554   }
555
556   vector<Pattern>::iterator it;
557   for(it = lCS.begin(); it != lCS.end(); it++) {
558     vector<Pattern>::iterator it_l;
559     bool contained_in_l = false;
560     for(it_l = l.begin(); it_l != l.begin(); it_l++)
561       if (*it == *it_l) {
562         contained_in_l = true;
563         break;
564       }
565     if (!contained_in_l) l.push_back(*it);
566   }
567
568   Symmetries symm(pattern.sizeX, pattern.sizeY);
569   for(int i=0; i<symm.sizeX; i++)
570     for(int j=0; j<symm.sizeY; j++)
571       symm.set(i,j,i,j,0);
572
573   vector<pair<int,int> >::iterator it_s;
574   for(it_s=sy.begin(); it_s!=sy.end(); it_s++) {
575     int s = it_s->first;
576     int newSizeX = max(Pattern::flipsX(s,0,0,pattern.sizeX,pattern.sizeY),
577                        Pattern::flipsX(s,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
578     int newSizeY = max(Pattern::flipsY(s,0,0,pattern.sizeX,pattern.sizeY),
579                        Pattern::flipsY(s,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
580     int c = it_s->second;
581     Symmetries symm1(newSizeX, newSizeY);
582
583     for(int i=0; i < pattern.sizeX; i++) {
584       for(int j=0; j < pattern.sizeY; j++) {
585         int fX = Pattern::flipsX(s, i, j, pattern.sizeX-1, pattern.sizeY-1);
586         int fY = Pattern::flipsY(s, i, j, pattern.sizeX-1, pattern.sizeY-1);
587         if ((i != fX || j != fY) && !symm1.has_key(fX, fY))
588           symm1.set(i,j, fX, fY, c);
589       }
590     }
591
592     int cs;
593     for(int i=0; i<symm.sizeX; i++)
594       for(int j=0; j<symm.sizeY; j++)
595         if (symm1.has_key(symm.getX(i,j), symm.getY(i,j))) {
596           if ((symm1.getCS(symm.getX(i,j),symm.getY(i,j)) || symm.getCS(i,j)) &&
597               !(symm1.getCS(symm.getX(i,j),symm.getY(i,j)) && symm.getCS(i,j)))
598             cs = 1;
599           else cs = 0;
600           symm.set(i,j,symm1.getX(symm.getX(i,j),symm.getY(i,j)),
601               symm1.getY(symm.getX(i,j),symm.getY(i,j)), cs);
602         }
603   }
604
605   if (special == -1)
606     symm.special = -1;
607   else
608     symm.special = Pattern::PatternInvFlip(special);
609
610   symmetries = symm;
611   return l;
612   cout << "Leave method PatternList::patternList" << endl;
613 }
614
615
616 Pattern& PatternList::get(int i) {
617   return data[i];
618 }
619
620
621 int PatternList::size() {
622   return data.size();
623 }
624
625
626 PyObject* PatternList::updateContinuations(int index, int x, int y, char co, int Xint0, int Xint1,
627     int Yint0, int Yint1,
628     int foundWhere, int counter,
629     PyObject* continuations, char* contLabels, int contLabelsIndex,
630     char winner) {
631
632   int xx = Pattern::flipsX(Pattern::PatternInvFlip(data[index].flip), x, y, boardsize-1, boardsize-1);
633   int yy = Pattern::flipsY(Pattern::PatternInvFlip(data[index].flip), x, y, boardsize-1, boardsize-1);
634
635   int XX1 = Pattern::flipsX(Pattern::PatternInvFlip(data[index].flip), Xint0, Yint0, boardsize-1, boardsize-1);
636   int YY1 = Pattern::flipsY(Pattern::PatternInvFlip(data[index].flip), Xint0, Yint0, boardsize-1, boardsize-1);
637   int XX2 = Pattern::flipsX(Pattern::PatternInvFlip(data[index].flip), Xint1-1, Yint1-1, boardsize-1, boardsize-1);
638   int YY2 = Pattern::flipsY(Pattern::PatternInvFlip(data[index].flip), Xint1-1, Yint1-1, boardsize-1, boardsize-1);
639
640   int XX = XX1 < XX2 ? XX1 : XX2;
641   int YY = YY1 < YY2 ? YY1 : YY2;
642
643   xx -= XX;
644   yy -= YY;
645
646   char cc;
647   if ((data[index].colorSwitch && co == 'X') || (!data[index].colorSwitch && co == 'O'))
648     cc = 'B';
649   else cc = 'W';
650
651   int xxN = symmetries.getX(xx,yy);
652   int yyN = symmetries.getY(xx,yy);
653   int cSymm = symmetries.getCS(xx,yy);
654
655   xx = xxN;
656   yy = yyN;
657
658   if ((cc == 'B' && !cSymm) || (cc=='W' && cSymm)) cc = 'B';
659   else cc = 'W';
660
661   int colorSwitch;
662
663   if (nextMove) {
664     if ((nextMove == 2 && cc == 'B') || (nextMove == 1 && cc == 'W')) {
665       if (symmetries.special != -1 && !fixedColor) {
666
667         if (cc == 'B') cc='W';
668         else cc = 'B';
669
670         xx += XX;
671         yy += YY;
672
673         xxN = Pattern::flipsX(symmetries.special, xx, yy, boardsize-1, boardsize-1);
674         yyN = Pattern::flipsY(symmetries.special, xx, yy, boardsize-1, boardsize-1);
675         xx = xxN;
676         yy = yyN;
677
678         int XX1N = Pattern::flipsX(symmetries.special, XX1, YY1, boardsize-1, boardsize-1);
679         int YY1N = Pattern::flipsY(symmetries.special, XX1, YY1, boardsize-1, boardsize-1);
680         XX1 = XX1N;
681         YY1 = YY1N;
682
683         int XX2N = Pattern::flipsX(symmetries.special, XX2, YY2, boardsize-1, boardsize-1);
684         int YY2N = Pattern::flipsY(symmetries.special, XX2, YY2, boardsize-1, boardsize-1);
685         XX2 = XX2N;
686         YY2 = YY2N;
687
688         XX = XX1 < XX2 ? XX1 : XX2;
689         YY = YY1 < YY2 ? YY1 : YY2;
690
691         xx -= XX;
692         yy -= YY;
693
694         int xx1 = symmetries.getX(xx,yy);
695         int yy1 = symmetries.getY(xx,yy);
696         int cSymm1 = symmetries.getCS(xx,yy);
697
698         if (!cSymm1) {
699           xx = xx1;
700           yy = yy1;
701         }
702
703         colorSwitch = 1-cSymm;
704         // if (colorSwitch) numOfSwitched++; // FIXME?!
705       }
706       else
707         return Py_BuildValue("iiii",0,0,0,0);
708     }
709     else {
710       colorSwitch = cSymm;
711       // if (colorSwitch) numOfSwitched++;
712     }
713   }
714   else colorSwitch = cSymm;
715
716   PyObject* xxyyPY = Py_BuildValue("(ii)", xx, yy);
717   PyObject* scxy;
718
719   char text;
720   char ccStr[2];
721   ccStr[0] = cc;
722   ccStr[1] = 0;
723   if ((scxy = PyDict_GetItem(continuations, xxyyPY))) {
724     PyObject *temp = PyInt_FromLong(PyInt_AsLong(PyDict_GetItemString(scxy, ccStr))+1);
725     PyDict_SetItemString(scxy, ccStr, temp);
726     Py_DECREF(temp);
727     text = PyString_AsString(PyDict_GetItemString(scxy, "N"))[0];
728   }
729   else {
730     if (contLabelsIndex >= strlen(contLabels)) text = '?'; // FIXME strlen(contLabels) OK?
731     else {
732       text = contLabels[contLabelsIndex];
733       contLabelsIndex++;
734     }
735
736     if (cc=='B') {
737       scxy = PyDict_New();
738       PyObject* Py0 = PyInt_FromLong(0);
739       PyObject *Py1 = PyInt_FromLong(1);
740       PyDict_SetItemString(scxy, "B", Py1);
741       PyDict_SetItemString(scxy, "W", Py0);
742       PyDict_SetItemString(scxy, "tB", Py0);
743       PyDict_SetItemString(scxy, "tW", Py0);
744       PyDict_SetItemString(scxy, "wB", Py0);
745       PyDict_SetItemString(scxy, "lB", Py0);
746       PyDict_SetItemString(scxy, "wW", Py0);
747       PyDict_SetItemString(scxy, "lW", Py0);
748       PyDict_SetItemString(scxy, "N", PyString_FromStringAndSize(&text, 1));
749       Py_DECREF(Py0);
750       Py_DECREF(Py1);
751       PyDict_SetItem(continuations, xxyyPY, scxy);
752       Py_DECREF(scxy);
753     }
754     else {
755       scxy = PyDict_New();
756       PyObject *Py0 = PyInt_FromLong(0);
757       PyObject *Py1 = PyInt_FromLong(1);
758       PyDict_SetItemString(scxy, "B", Py0);
759       PyDict_SetItemString(scxy, "W", Py1);
760       PyDict_SetItemString(scxy, "tB", Py0);
761       PyDict_SetItemString(scxy, "tW", Py0);
762       PyDict_SetItemString(scxy, "wB", Py0);
763       PyDict_SetItemString(scxy, "lB", Py0);
764       PyDict_SetItemString(scxy, "wW", Py0);
765       PyDict_SetItemString(scxy, "lW", Py0);
766       PyDict_SetItemString(scxy, "N", PyString_FromStringAndSize(&text, 1));
767       Py_DECREF(Py0);
768       Py_DECREF(Py1);
769       PyDict_SetItem(continuations, xxyyPY, scxy);
770       Py_DECREF(scxy);
771     }
772
773     Py_DECREF(xxyyPY);
774
775     char tcc[3]; tcc[0]='t'; tcc[1]=cc; tcc[2]=0;
776     char lcc[3]; lcc[0]='l'; lcc[1]=cc; lcc[2]=0;
777     char wcc[3]; wcc[0]='w'; wcc[1]=cc; wcc[2]=0;
778
779     if (foundWhere != counter && foundWhere != counter+1) {
780       PyObject *temp = PyInt_FromLong(PyInt_AsLong(PyDict_GetItemString(scxy, tcc))+1);
781       PyDict_SetItemString(scxy, tcc, temp);
782       Py_DECREF(temp);
783     }
784
785     if (winner == 'B')
786       if (!(data[index].colorSwitch || colorSwitch)) {
787         PyObject *temp = PyInt_FromLong(PyInt_AsLong(PyDict_GetItemString(scxy, wcc))+1);
788         PyDict_SetItemString(scxy, wcc, temp);
789         Py_DECREF(temp);
790       }
791       else {
792         PyObject *temp = PyInt_FromLong(PyInt_AsLong(PyDict_GetItemString(scxy, lcc))+1);
793         PyDict_SetItemString(scxy, lcc, temp);
794         Py_DECREF(temp);
795       }
796     else if (winner == 'W')
797       if (!(data[index].colorSwitch || colorSwitch)) {
798         PyObject *temp = PyInt_FromLong(PyInt_AsLong(PyDict_GetItemString(scxy, lcc))+1);
799         PyDict_SetItemString(scxy, lcc, temp);
800         Py_DECREF(temp);
801       }
802       else {
803         PyObject *temp = PyInt_FromLong(PyInt_AsLong(PyDict_GetItemString(scxy, wcc))+1);
804         PyDict_SetItemString(scxy, wcc, temp);
805         Py_DECREF(temp);
806       }
807   }
808   return Py_BuildValue("icii", 1, text, contLabelsIndex,
809       (data[index].colorSwitch or colorSwitch));
810 }
811
Note: See TracBrowser for help on using the browser.