/kombilo/search.cpp
C++ | 5380 lines | 4166 code | 524 blank | 690 comment | 1777 complexity | 0e1bbdbcb1b0e8ea2618a8bcc476aa52 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- // File: search.cpp
- // part of libkombilo, http://www.u-go.net/kombilo/
- // Copyright (c) 2006-7 Ulrich Goertz <u@g0ertz.de>
- // Permission is hereby granted, free of charge, to any person obtaining a copy of
- // this software and associated documentation files (the "Software"), to deal in
- // the Software without restriction, including without limitation the rights to
- // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- // of the Software, and to permit persons to whom the Software is furnished to do
- // so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in all
- // copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- // SOFTWARE.
- #include "sgfparser.h"
- #include "abstractboard.h"
- #include "search.h"
- #include <stdio.h>
- #include <string>
- #include <cstring>
- using std::min;
- using std::max;
- using std::string;
- using std::vector;
- using std::map;
- using std::pair;
- using std::make_pair;
- using std::stack;
- #if defined(_MSC_VER)
- #include <algorithm>
- #else
- using std::sort;
- #endif
- SnapshotVector::SnapshotVector() : vector<unsigned char>() {
- current = begin();
- }
- SnapshotVector::SnapshotVector(char* c, int size) : vector<unsigned char>() {
- for(int i=0; i<size; i++) push_back(c[i]);
- current = begin();
- }
- void SnapshotVector::pb_int(int d) {
- for(int i = 0; i < 4; i++) {
- push_back((unsigned char)(d % 256));
- d = d >> 8;
- }
- }
- void SnapshotVector::pb_charp(char* c, int size) {
- pb_int(size);
- for(int i=0; i<size; i++) push_back(c[i]);
- }
- void SnapshotVector::pb_intp(int* p, int size) {
- pb_int(size);
- for(int i=0; i<size; i++) pb_int(p[i]);
- }
- void SnapshotVector::pb_string(string s) {
- pb_int(s.size()+1);
- for(unsigned int i=0; i<s.size(); i++) push_back(s[i]);
- push_back(0);
- }
- void SnapshotVector::pb_char(char c) {
- push_back(c);
- }
- int SnapshotVector::retrieve_int() {
- int result = 0;
- for(int i=0; i<4; i++) {
- result += *current << (i*8);
- current++;
- }
- return result;
- }
- int* SnapshotVector::retrieve_intp() {
- int sz = retrieve_int();
- int* result = new int[sz];
- for(int i=0; i<sz; i++)
- result[i] = retrieve_int();
- return result;
- }
- char SnapshotVector::retrieve_char() {
- char c = *current;
- current++;
- return c;
- }
- char* SnapshotVector::retrieve_charp() {
- int sz = retrieve_int();
- char* result = new char[sz];
- for(int i=0; i<sz; i++) {
- result[i] = *current;
- current++;
- }
- return result;
- }
- string SnapshotVector::retrieve_string() {
- char* cp = retrieve_charp();
- string s(cp);
- delete [] cp;
- return s;
- }
- char* SnapshotVector::to_charp() {
- char* result = new char[size()];
- int counter = 0;
- for(SnapshotVector::iterator it = begin(); it != end(); it++) result[counter++] = *it;
- return result;
- }
- PatternError::PatternError() {}
- Continuation::Continuation() {
- B = 0;
- W = 0;
- tB = 0;
- tW = 0;
- wB = 0;
- lB = 0;
- wW = 0;
- lW = 0;
- }
- void Continuation::from_snv(SnapshotVector& snv) {
- B = snv.retrieve_int();
- W = snv.retrieve_int();
- tB = snv.retrieve_int();
- tW = snv.retrieve_int();
- wB = snv.retrieve_int();
- lB = snv.retrieve_int();
- wW = snv.retrieve_int();
- lW = snv.retrieve_int();
- }
- void Continuation::to_snv(SnapshotVector& snv) {
- snv.pb_int(B);
- snv.pb_int(W);
- snv.pb_int(tB);
- snv.pb_int(tW);
- snv.pb_int(wB);
- snv.pb_int(lB);
- snv.pb_int(wW);
- snv.pb_int(lW);
- }
- Symmetries::Symmetries(char sX, char sY) {
- sizeX = sX;
- sizeY = sY;
- dataX = new char[sizeX*sizeY];
- dataY = new char[sizeX*sizeY];
- dataCS = new char[sizeX*sizeY];
- for(int i=0; i<sizeX*sizeY; i++) {
- dataX[i] = -1;
- dataY[i] = -1;
- dataCS[i] = -1;
- }
- }
- Symmetries::~Symmetries() {
- delete [] dataX;
- delete [] dataY;
- delete [] dataCS;
- }
- Symmetries::Symmetries(const Symmetries& s) {
- sizeX = s.sizeX;
- sizeY = s.sizeY;
- dataX = new char[sizeX*sizeY];
- dataY = new char[sizeX*sizeY];
- dataCS = new char[sizeX*sizeY];
- for(int i=0; i<sizeX*sizeY; i++) {
- dataX[i] = s.dataX[i];
- dataY[i] = s.dataY[i];
- dataCS[i] = s.dataCS[i];
- }
- }
- Symmetries& Symmetries::operator=(const Symmetries& s) {
- if (&s != this) {
- sizeX = s.sizeX;
- sizeY = s.sizeY;
- delete [] dataX;
- delete [] dataY;
- delete [] dataCS;
- dataX = new char[sizeX*sizeY];
- dataY = new char[sizeX*sizeY];
- dataCS = new char[sizeX*sizeY];
- for(int i=0; i<sizeX*sizeY; i++) {
- dataX[i] = s.dataX[i];
- dataY[i] = s.dataY[i];
- dataCS[i] = s.dataCS[i];
- }
- }
- return *this;
- }
- void Symmetries::set(char i, char j, char k, char l, char cs) throw(PatternError) {
- if (0 <= i && i < sizeX && 0 <= j && j < sizeY) {
- dataX[i + j*sizeX] = k;
- dataY[i + j*sizeX] = l;
- dataCS[i + j*sizeX] = cs;
- }
- else throw PatternError();
- }
- char Symmetries::getX(char i, char j) throw(PatternError) {
- if (0 <= i && i < sizeX && 0 <= j && j < sizeY) return dataX[i + j*sizeX];
- else throw PatternError();
- return -1;
- }
- char Symmetries::getY(char i, char j) throw(PatternError) {
- if (0 <= i && i < sizeX && 0 <= j && j < sizeY) return dataY[i + j*sizeX];
- else throw PatternError();
- return -1;
- }
- char Symmetries::getCS(char i, char j) throw(PatternError) {
- if (0 <= i && i < sizeX && 0 <= j && j < sizeY) return dataCS[i + j*sizeX];
- else throw PatternError();
- return -1;
- }
- char Symmetries::has_key(char i, char j) throw(PatternError) {
- if (0 <= i && i < sizeX && 0 <= j && j < sizeY) {
- if (dataX[i + j*sizeX] == -1) return 0;
- else return 1;
- }
- else throw PatternError();
- return 0;
- }
- // ----------- class Pattern -----------------------------------------------
- int Pattern::operator==(const Pattern& p) {
- if (boardsize != p.boardsize) return 0;
- if (sizeX != p.sizeX || sizeY != p.sizeY) return 0;
- if (left != p.left || right != p.right || top != p.top || bottom != p.bottom) return 0;
- for(int i=0; i < sizeX*sizeY; i++)
- if (initialPos[i] != p.initialPos[i]) return 0;
- if (contList != p.contList) return 0;
- return 1;
- }
- char Pattern::BW2XO(char c) {
- if (c == 'B') return 'X';
- if (c == 'W') return 'O';
- return c;
- }
- char Pattern::getInitial(int i, int j) {
- return initialPos[i + sizeX*j];
- }
-
- char Pattern::getFinal(int i, int j) {
- return finalPos[i + sizeX*j];
- }
-
- Pattern::Pattern() {
- initialPos = 0;
- finalPos = 0;
- flip = 0;
- colorSwitch = 0;
- sizeX = 0;
- sizeY = 0;
- boardsize = 0;
- contLabels = 0;
- }
- Pattern::Pattern(int type, int BOARDSIZE, int sX, int sY, char* iPos, char* CONTLABELS) {
- flip = 0;
- colorSwitch = 0;
- sizeX = sX;
- sizeY = sY;
- boardsize = BOARDSIZE;
- if (CONTLABELS) {
- contLabels = new char[sizeX * sizeY];
- for(int i=0; i<sizeX*sizeY; i++) contLabels[i] = CONTLABELS[i];
- } else contLabels = 0;
- if (type == CORNER_NW_PATTERN || type == FULLBOARD_PATTERN) {
- left = right = top = bottom = 0;
- } else if (type == CORNER_NE_PATTERN) {
- top = bottom = 0;
- left = right = boardsize - sizeX;
- } else if (type == CORNER_SE_PATTERN) {
- top = bottom = boardsize - sizeY;
- left = right = boardsize - sizeX;
- } else if (type == CORNER_SW_PATTERN) {
- top = bottom = boardsize - sizeY;
- left = right = 0;
- } else if (type == SIDE_N_PATTERN) {
- top = bottom = 0;
- left = 1;
- right = boardsize -1 - sizeX;
- } else if (type == SIDE_E_PATTERN) {
- left = right = boardsize - sizeX;
- top = 1;
- bottom = boardsize -1 - sizeY;
- } else if (type == SIDE_W_PATTERN) {
- left = right = 0;
- top = 1;
- bottom = boardsize -1 - sizeY;
- } else if (type == SIDE_S_PATTERN) {
- top = bottom = boardsize - sizeY;
- left = 1;
- right = boardsize -1 - sizeX;
- } else if (type == CENTER_PATTERN) {
- left = top = 1;
- right = boardsize -1 - sizeX;
- bottom = boardsize -1 - sizeY;
- }
- initialPos = new char[sizeX * sizeY];
- finalPos = new char[sizeX*sizeY];
- for(int i=0; i<sizeX*sizeY; i++) {
- initialPos[i] = iPos[i];
- finalPos[i] = iPos[i];
- }
- }
- Pattern::Pattern(int type, int BOARDSIZE, int sX, int sY,
- char* iPos, vector<MoveNC> CONTLIST, char* CONTLABELS) {
- flip = 0;
- colorSwitch = 0;
- sizeX = sX;
- sizeY = sY;
- boardsize = BOARDSIZE;
- if (CONTLABELS) {
- contLabels = new char[sizeX * sizeY];
- for(int i=0; i<sizeX*sizeY; i++) contLabels[i] = CONTLABELS[i];
- } else contLabels = 0;
- if (type == CORNER_NW_PATTERN || type == FULLBOARD_PATTERN) {
- left = right = top = bottom = 0;
- } else if (type == CORNER_NE_PATTERN) {
- top = bottom = 0;
- left = right = boardsize - sizeX;
- } else if (type == CORNER_SE_PATTERN) {
- top = bottom = boardsize - sizeY;
- left = right = boardsize - sizeX;
- } else if (type == CORNER_SW_PATTERN) {
- top = bottom = boardsize - sizeY;
- left = right = 0;
- } else if (type == SIDE_N_PATTERN) {
- top = bottom = 0;
- left = 1;
- right = boardsize -1 - sizeX;
- } else if (type == SIDE_E_PATTERN) {
- left = right = boardsize - sizeX;
- top = 1;
- bottom = boardsize -1 - sizeY;
- } else if (type == SIDE_W_PATTERN) {
- left = right = 0;
- top = 1;
- bottom = boardsize -1 - sizeY;
- } else if (type == SIDE_S_PATTERN) {
- top = bottom = boardsize - sizeY;
- left = 1;
- right = boardsize -1 - sizeX;
- } else if (type == CENTER_PATTERN) {
- left = top = 1;
- right = boardsize -1 - sizeX;
- bottom = boardsize -1 - sizeY;
- }
- initialPos = new char[sizeX * sizeY];
- finalPos = new char[sizeX*sizeY];
- for(int i=0; i<sizeX*sizeY; i++) {
- initialPos[i] = iPos[i];
- finalPos[i] = iPos[i];
- }
- contList = CONTLIST;
- }
- Pattern::Pattern(int le, int ri, int to, int bo, int BOARDSIZE, int sX, int sY,
- char* iPos, const vector<MoveNC>& CONTLIST, char* CONTLABELS) throw(PatternError) {
- // check whether anchor rectangle is valid
- if (le < 0 || ri+sX > BOARDSIZE || to < 0 || bo+sY > BOARDSIZE || ri < le || bo < to) throw PatternError();
- flip = 0;
- colorSwitch = 0;
- left = le;
- right = ri;
- top = to;
- bottom = bo;
- boardsize = BOARDSIZE;
- sizeX = sX;
- sizeY = sY;
- if (CONTLABELS) {
- contLabels = new char[sizeX * sizeY];
- for(int i=0; i<sizeX*sizeY; i++) contLabels[i] = CONTLABELS[i];
- } else contLabels = 0;
- initialPos = new char[sizeX * sizeY];
- finalPos = new char[sizeX*sizeY];
- for(int i=0; i<sizeX*sizeY; i++) {
- initialPos[i] = iPos[i];
- finalPos[i] = iPos[i];
- }
- contList = CONTLIST;
- }
- Pattern::Pattern(SnapshotVector& snv) {
- flip = snv.retrieve_int();
- colorSwitch = snv.retrieve_int();
- left = snv.retrieve_int();
- right = snv.retrieve_int();
- top = snv.retrieve_int();
- bottom = snv.retrieve_int();
- boardsize = snv.retrieve_int();
- sizeX = snv.retrieve_int();
- sizeY = snv.retrieve_int();
- if (snv.retrieve_char()) { // contLabels?
- contLabels = snv.retrieve_charp();
- } else contLabels = 0;
- initialPos = snv.retrieve_charp();
- finalPos = snv.retrieve_charp();
- int size = snv.retrieve_int();
- for(int i=0; i<size; i++)
- contList.push_back(MoveNC(snv.retrieve_char(), snv.retrieve_char(), snv.retrieve_char())); // x, y, color
- }
- void Pattern::to_snv(SnapshotVector& snv) {
- snv.pb_int(flip);
- snv.pb_int(colorSwitch);
- snv.pb_int(left);
- snv.pb_int(right);
- snv.pb_int(top);
- snv.pb_int(bottom);
- snv.pb_int(boardsize);
- snv.pb_int(sizeX);
- snv.pb_int(sizeY);
- if (contLabels) {
- snv.pb_char(1);
- snv.pb_charp(contLabels, sizeX*sizeY);
- } else snv.pb_char(0);
- snv.pb_charp(initialPos, sizeX*sizeY);
- snv.pb_charp(finalPos, sizeX*sizeY);
- snv.pb_int(contList.size());
- for(vector<MoveNC>::iterator it = contList.begin(); it != contList.end(); it++) {
- snv.pb_char(it->x);
- snv.pb_char(it->y);
- snv.pb_char(it->color);
- }
- }
- Pattern::~Pattern() {
- if (initialPos) delete [] initialPos;
- if (finalPos) delete [] finalPos;
- if (contLabels) delete [] contLabels;
- }
- Pattern::Pattern(const Pattern& p) {
- left = p.left;
- right = p.right;
- top = p.top;
- bottom = p.bottom;
- boardsize = p.boardsize;
- sizeX = p.sizeX;
- sizeY = p.sizeY;
- flip = p.flip;
- colorSwitch = p.colorSwitch;
- initialPos = new char[sizeX*sizeY];
- finalPos = new char[sizeX*sizeY];
- if (p.contLabels) contLabels = new char[sizeX*sizeY];
- else contLabels = 0;
- for(int i=0; i<sizeX*sizeY; i++) {
- initialPos[i] = p.initialPos[i];
- finalPos[i] = p.finalPos[i];
- if (p.contLabels) contLabels[i] = p.contLabels[i];
- }
- contList = p.contList;
- }
- Pattern& Pattern::operator=(const Pattern& p) {
- if (&p != this) {
- left = p.left;
- right = p.right;
- top = p.top;
- bottom = p.bottom;
- boardsize = p.boardsize;
- sizeX = p.sizeX;
- sizeY = p.sizeY;
- flip = p.flip;
- colorSwitch = p.colorSwitch;
- if (initialPos) delete [] initialPos;
- if (finalPos) delete [] finalPos;
- if (contLabels) delete [] contLabels;
- initialPos = new char[sizeX*sizeY];
- finalPos = new char[sizeX*sizeY];
- if (p.contLabels) contLabels = new char[sizeX*sizeY];
- else contLabels = 0;
- for(int i=0; i<sizeX*sizeY; i++) {
- initialPos[i] = p.initialPos[i];
- finalPos[i] = p.finalPos[i];
- if (p.contLabels) contLabels[i] = p.contLabels[i];
- }
- contList = p.contList;
- }
- return *this;
- }
- Pattern& Pattern::copy(const Pattern& p) {
- if (&p != this) {
- left = p.left;
- right = p.right;
- top = p.top;
- bottom = p.bottom;
- boardsize = p.boardsize;
- sizeX = p.sizeX;
- sizeY = p.sizeY;
- flip = p.flip;
- colorSwitch = p.colorSwitch;
- if (initialPos) delete [] initialPos;
- if (finalPos) delete [] finalPos;
- initialPos = new char[sizeX*sizeY];
- finalPos = new char[sizeX*sizeY];
- if (p.contLabels) contLabels = new char[sizeX*sizeY];
- else contLabels = 0;
- for(int i=0; i<sizeX*sizeY; i++) {
- initialPos[i] = p.initialPos[i];
- finalPos[i] = p.finalPos[i];
- if (p.contLabels) contLabels[i] = p.contLabels[i];
- }
- contList = p.contList;
- }
- return *this;
- }
- string Pattern::printPattern() {
- string result;
- char buf[100];
- sprintf(buf, "boardsize: %d, area: %d, %d, %d, %d\nsize: %d, %d\n", boardsize, left, right, top, bottom, sizeX, sizeY);
- result += buf;
- for(int i=0; i<sizeY; i++) {
- for(int j=0; j<sizeX; j++) {
- if (initialPos[i*sizeX + j] == 'X' || initialPos[i*sizeX + j] == 'O' || initialPos[i*sizeX + j] == 'x' || initialPos[i*sizeX + j] == 'x' || initialPos[i*sizeX+j] == '*') result += initialPos[i*sizeX+j];
- else result += '.';
- }
- result += "\n";
- }
- result += "\n";
- return result;
- }
- int Pattern::flipsX(int i, int x, int y, int XX, int YY) {
- if (i==0) return x;
- if (i==1) return XX-x;
- if (i==2) return x;
- if (i==3) return XX-x;
- if (i==4) return y;
- if (i==5) return YY-y;
- if (i==6) return y;
- if (i==7) return YY-y;
- return -1;
- }
- int Pattern::flipsY(int i, int x, int y, int XX, int YY) {
- if (i==0) return y;
- if (i==1) return y;
- if (i==2) return YY-y;
- if (i==3) return YY-y;
- if (i==4) return x;
- if (i==5) return x;
- if (i==6) return XX-x;
- if (i==7) return XX-x;
- return -1;
- }
- int Pattern::PatternInvFlip(int i) {
- if (i == 5) return 6;
- if (i == 6) return 5;
- return i;
- }
- const int composition_table[] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 1, 0, 3, 2, 5, 4, 7, 6,
- 2, 3, 0, 1, 6, 7, 4, 5,
- 3, 2, 1, 0, 7, 6, 5, 4,
- 4, 6, 5, 7, 0, 2, 1, 3,
- 5, 7, 4, 6, 1, 3, 0, 2,
- 6, 4, 7, 5, 2, 0, 3, 1,
- 7, 5, 6, 4, 3, 1, 2, 0 };
- int Pattern::compose_flips(int i, int j) {
- return composition_table[j+8*i];
- }
- PatternList::PatternList(Pattern& p, int fColor, int nMove) throw(PatternError) {
- pattern.copy(p);
- fixedColor = fColor;
- nextMove = nMove;
- special = -1;
- flipTable = new int[16];
- for(int i=0; i<16; i++) flipTable[i] = -1; // (patternList() relies on this)
- patternList();
- continuations = new Continuation[pattern.sizeX * pattern.sizeY];
- }
- PatternList::~PatternList() {
- delete [] continuations;
- delete [] flipTable;
- }
- char PatternList::invertColor(char co) {
- if (co == 'X') return 'O';
- if (co == 'x') return 'o';
- if (co == 'O') return 'X';
- if (co == 'o') return 'x';
- return co;
- }
- void PatternList::patternList() {
- vector<Pattern> lCS;
- vector<pair<int,int> > sy;
- int boardsize = pattern.boardsize;
- for(int f = 0; f < 8; f++) {
- int newSizeX = max(Pattern::flipsX(f,0,0,pattern.sizeX,pattern.sizeY),
- Pattern::flipsX(f,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
- int newSizeY = max(Pattern::flipsY(f,0,0,pattern.sizeX,pattern.sizeY),
- Pattern::flipsY(f,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
- int newLeft = min(Pattern::flipsX(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
- Pattern::flipsX(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
- boardsize-1,boardsize-1));
- int newRight = max(Pattern::flipsX(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
- Pattern::flipsX(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
- boardsize-1,boardsize-1)) - (newSizeX-1);
- int newTop = min(Pattern::flipsY(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
- Pattern::flipsY(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
- boardsize-1,boardsize-1));
- int newBottom = max(Pattern::flipsY(f,pattern.left,pattern.top,boardsize-1,boardsize-1),
- Pattern::flipsY(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1,
- boardsize-1,boardsize-1)) - (newSizeY - 1);
- // printf("%d, %d, %d, %d, %d, %d, %d\n", f, newSizeX, newSizeY, newLeft, newRight, newTop, newBottom);
- char* newInitialPos = new char[pattern.sizeX*pattern.sizeY];
- int i=0;
- for(i=0; i<pattern.sizeX; i++) {
- for(int j=0; j<pattern.sizeY; j++) {
- newInitialPos[Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1) + \
- newSizeX*Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1)] = pattern.getInitial(i, j);
- }
- }
- vector<MoveNC> newContList;
- for(i=0; (unsigned int)i<pattern.contList.size(); i++) {
- newContList.push_back(MoveNC(Pattern::flipsX(f, pattern.contList[i].x, pattern.contList[i].y,
- pattern.sizeX-1,pattern.sizeY-1),
- Pattern::flipsY(f, pattern.contList[i].x, pattern.contList[i].y,
- pattern.sizeX-1,pattern.sizeY-1),
- pattern.contList[i].color));
- }
- Pattern pNew(newLeft, newRight, newTop, newBottom, pattern.boardsize, newSizeX, newSizeY,
- newInitialPos, newContList);
- pNew.flip = f;
- // printf("new size %d %d\n", pNew.sizeX, pNew.sizeY);
- delete [] newInitialPos;
- vector<Pattern>::iterator it;
- bool foundNewPattern = true;
- for(it = data.begin(); it != data.end(); it++) {
- if (pNew == *it) {
- foundNewPattern = false;
- flipTable[f] = flipTable[it->flip];
- break;
- }
- }
- if (foundNewPattern) {
- flipTable[f] = data.size();
- data.push_back(pNew);
- }
- if (pNew == pattern) sy.push_back(pair<int,int>(f,0));
- if (nextMove || !fixedColor) {
- char* newInitialPos = new char[pattern.sizeX*pattern.sizeY];
- for(int i=0; i<pattern.sizeX; i++) {
- for(int j=0; j<pattern.sizeY; j++) {
- newInitialPos[Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1) + newSizeX*Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1)] =
- invertColor(pattern.getInitial(i, j));
- }
- }
- vector<MoveNC> newContList;
- {
- for(unsigned int i=0; i<pattern.contList.size(); i++) {
- newContList.push_back(MoveNC(Pattern::flipsX(f, pattern.contList[i].x, pattern.contList[i].y,
- pattern.sizeX-1,pattern.sizeY-1),
- Pattern::flipsY(f, pattern.contList[i].x, pattern.contList[i].y,
- pattern.sizeX-1,pattern.sizeY-1),
- invertColor(pattern.contList[i].color)));
- }
- }
- // printf("new size %d %d", newSizeX, newSizeY);
- Pattern pNew1(newLeft, newRight, newTop, newBottom, pattern.boardsize, newSizeX, newSizeY,
- newInitialPos, newContList);
- pNew1.flip = f;
- pNew1.colorSwitch = 1;
- delete [] newInitialPos;
- if (!fixedColor) {
- bool foundNewPattern = true;
- int lCS_ctr = 0;
- for(vector<Pattern>::iterator it = lCS.begin(); it != lCS.end(); it++) {
- if (pNew1 == *it) {
- foundNewPattern = false;
- flipTable[f+8] = lCS_ctr;
- break;
- }
- lCS_ctr++;
- }
- if (foundNewPattern) {
- lCS.push_back(pNew1);
- }
- }
- if (pNew1 == pattern) {
- if (!fixedColor) sy.push_back(pair<int,int>(f,1));
- if (nextMove) special = Pattern::PatternInvFlip(f);
- }
- }
- }
- int lCS_ctr = 0;
- for(vector<Pattern>::iterator it = lCS.begin(); it != lCS.end(); it++) {
- bool contained_in_l = false;
- for(vector<Pattern>::iterator it_l = data.begin(); it_l != data.end(); it_l++)
- if (*it == *it_l) {
- contained_in_l = true;
- flipTable[8+it->flip] = flipTable[it_l->flip];
- break;
- }
- if (!contained_in_l) {
- flipTable[8+it->flip] = data.size();
- data.push_back(*it);
- }
- for(int ii=it->flip+1; ii<8; ii++)
- if (flipTable[8+ii] == lCS_ctr) flipTable[8+ii] = flipTable[8+it->flip];
- lCS_ctr++;
- }
- Symmetries symm(pattern.sizeX, pattern.sizeY);
- for(int i=0; i<symm.sizeX; i++)
- for(int j=0; j<symm.sizeY; j++)
- symm.set(i,j, i,j,0);
- for(vector<pair<int,int> >::iterator it_s=sy.begin(); it_s!=sy.end(); it_s++) {
- int s = it_s->first;
- int newSizeX = max(Pattern::flipsX(s,0,0,pattern.sizeX,pattern.sizeY),
- Pattern::flipsX(s,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
- int newSizeY = max(Pattern::flipsY(s,0,0,pattern.sizeX,pattern.sizeY),
- Pattern::flipsY(s,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY));
- int c = it_s->second;
- Symmetries symm1(newSizeX, newSizeY);
- for(int i=0; i < pattern.sizeX; i++) {
- for(int j=0; j < pattern.sizeY; j++) {
- int fX = Pattern::flipsX(s, i, j, pattern.sizeX-1, pattern.sizeY-1);
- int fY = Pattern::flipsY(s, i, j, pattern.sizeX-1, pattern.sizeY-1);
- if ((i != fX || j != fY) && !symm1.has_key(fX, fY))
- symm1.set(i,j, fX, fY, c);
- }
- }
- {
- int cs;
- for(int i=0; i<symm.sizeX; i++)
- for(int j=0; j<symm.sizeY; j++)
- if (symm1.has_key(symm.getX(i,j), symm.getY(i,j))) {
- if ((symm1.getCS(symm.getX(i,j),symm.getY(i,j)) || symm.getCS(i,j)) &&
- !(symm1.getCS(symm.getX(i,j),symm.getY(i,j)) && symm.getCS(i,j)))
- cs = 1;
- else cs = 0;
- symm.set(i,j,symm1.getX(symm.getX(i,j),symm.getY(i,j)),
- symm1.getY(symm.getX(i,j),symm.getY(i,j)), cs);
- }
- }
- }
- symmetries.push_back(symm);
- {
- vector<Pattern>::iterator it = data.begin();
- it++;
- for(; it != data.end(); it++) {
- // printf("ne %d, %d\n", it->sizeX, it->sizeY);
- int f = it->flip;
- Symmetries s(it->sizeX, it->sizeY);
- for(int i=0; i<pattern.sizeX; i++) {
- for(int j=0; j<pattern.sizeY; j++) {
- if (!it->colorSwitch) {
- s.set(Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1),
- Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1),
- symm.getX(i,j), symm.getY(i,j), symm.getCS(i,j));
- } else {
- s.set(Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1),
- Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1),
- symm.getX(i,j), symm.getY(i,j), 1-symm.getCS(i,j));
- }
- }
- }
- symmetries.push_back(s);
- }
- }
- }
- Pattern PatternList::get(int i) {
- return data[i];
- }
- int PatternList::size() {
- return data.size();
- }
- char* PatternList::updateContinuations(int index, int x, int y, char co, bool tenuki, char winner) {
- char xx;
- char yy;
- char cSymm;
- char cc;
- xx = symmetries[index].getX(x,y);
- yy = symmetries[index].getY(x,y);
- cSymm = symmetries[index].getCS(x,y);
- if (co == 'X' || co == 'B') {
- if (cSymm) cc = 'W'; else cc = 'B';
- } else {
- if (cSymm) cc = 'B'; else cc = 'W';
- }
- if ((nextMove == 1 && cc == 'W') || (nextMove == 2 && cc == 'B')) {
- if (special != -1) {
- char xx1 = xx;
- // printf("s1 xx %d, yy %d sp %d\n", xx, yy, special);
- xx = Pattern::flipsX(special, xx, yy, pattern.sizeX-1, pattern.sizeY-1);
- yy = Pattern::flipsY(special, xx1, yy, pattern.sizeX-1, pattern.sizeY-1);
- // printf("s2 xx %d, yy %d\n", xx, yy);
- if (cc == 'B') cc = 'W';
- else cc = 'B';
- cSymm = 1-cSymm;
- } else {
- return 0;
- }
- }
- if (cc == 'B') {
- continuations[xx + pattern.sizeX*yy].B++;
- if (tenuki) continuations[xx + pattern.sizeX*yy].tB++;
- if ((winner == 'B' && !cSymm) || (winner == 'W' && cSymm)) continuations[xx + pattern.sizeX*yy].wB++;
- else if ((winner == 'W' && !cSymm) || (winner == 'B' && cSymm)) continuations[xx + pattern.sizeX*yy].lB++;
- } else {
- // printf("xx %d, yy %d\n", xx, yy);
- continuations[xx + pattern.sizeX*yy].W++;
- if (tenuki) continuations[xx + pattern.sizeX*yy].tW++;
- if ((winner == 'B' && !cSymm) || (winner == 'W' && cSymm)) continuations[xx + pattern.sizeX*yy].wW++;
- else if ((winner == 'W' && !cSymm) || (winner ='B' && cSymm)) continuations[xx + pattern.sizeX*yy].lW++;
- }
- char* result = new char[3];
- result[0] = xx;
- result[1] = yy;
- result[2] = cSymm;
- return result;
- }
- char* PatternList::sortContinuations() {
- char* labels = new char[pattern.sizeX*pattern.sizeY+1];
- labels[pattern.sizeX * pattern.sizeY] = 0; // so we can just printf the labels as a string
- for(int i=0; i<pattern.sizeX*pattern.sizeY; i++) {
- if (continuations[i].B || continuations[i].W) labels[i] = '?'; // need to assign label
- else labels[i] = '.';
- }
- string labelList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- unsigned int labelIndex = 0;
- // assign labels which are in the contLabels array passed to the original pattern
- // (these will usually be labels "already present in the SGF file")
-
- if (pattern.contLabels) {
- for(int i=0; i<pattern.sizeX*pattern.sizeY; i++) {
- if (pattern.contLabels[i] != '.') {
- labels[i] = pattern.contLabels[i];
- unsigned int j = labelList.find(pattern.contLabels[i]);
- if (j != string::npos) labelList.erase(j,1);
- }
- }
- }
- // now give labels to the remaining points, starting with the one with
- // most hits
-
- int max_hits = 0;
- int max_hits_index = 0;
- while (max_hits != -1 && labelIndex < labelList.size()) {
- for(int i=0; i<pattern.sizeX*pattern.sizeY; i++) {
- if (labels[i] == '?' && continuations[i].B + continuations[i].W > max_hits) {
- max_hits = continuations[i].B + continuations[i].W;
- max_hits_index = i;
- }
- }
- if (max_hits != 0) { // found another point needing a label
- labels[max_hits_index] = labelList[labelIndex++];
- max_hits = 0;
- } else max_hits = -1; // done
- }
- return labels;
- }
- DBError::DBError() {
- }
- int dbinsert1blob(sqlite3* db, char* sql, int id, char* blob, int size) {
- sqlite3_stmt *ppStmt=0;
- int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0);
- if (rc != SQLITE_OK || ppStmt==0) return rc;
- rc = sqlite3_bind_int(ppStmt, 1, id);
- if (rc != SQLITE_OK) return rc;
- rc = sqlite3_bind_blob(ppStmt, 2, blob, size, SQLITE_TRANSIENT);
- if (rc != SQLITE_OK) return rc;
- rc = sqlite3_step(ppStmt);
- if (rc != SQLITE_DONE) return rc;
- rc = sqlite3_finalize(ppStmt);
- if (rc != SQLITE_OK) return rc;
- return 0; // Success
- }
- int dbinsert2blobs(sqlite3* db, char* sql, int id, char* blob1, int size1, char* blob2, int size2) {
- sqlite3_stmt *ppStmt=0;
- int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0);
- if (rc != SQLITE_OK || ppStmt==0) return rc;
- rc = sqlite3_bind_int(ppStmt, 1, id);
- if (rc != SQLITE_OK) return rc;
- rc = sqlite3_bind_blob(ppStmt, 2, blob1, size1, SQLITE_TRANSIENT);
- if (rc != SQLITE_OK) return rc;
- rc = sqlite3_bind_blob(ppStmt, 3, blob2, size2, SQLITE_TRANSIENT);
- if (rc != SQLITE_OK) return rc;
- rc = sqlite3_step(ppStmt);
- if (rc != SQLITE_DONE) return rc;
- rc = sqlite3_finalize(ppStmt);
- if (rc != SQLITE_OK) return rc;
- return 0; // Success
- }
-
- Algorithm::Algorithm(int bsize) {
- boardsize = bsize;
- db = 0;
- }
- Algorithm::~Algorithm() {}
- void Algorithm::initialize_process(sqlite3* DB) {}
- void Algorithm::newgame_process(int game_id) {}
- void Algorithm::AB_process(int x, int y) {}
- void Algorithm::AW_process(int x, int y) {}
- void Algorithm::AE_process(int x, int y, char removed) {}
- void Algorithm::endOfNode_process() {}
- void Algorithm::move_process(Move m) {}
- void Algorithm::pass_process() {}
- void Algorithm::branchpoint_process() {}
- void Algorithm::endOfVariation_process() {}
- void Algorithm::endgame_process(bool commit) {}
- void Algorithm::finalize_process() {}
- int Algorithm::readDB(sqlite3* DB) { return 0; }
- int Algorithm::search(PatternList& patternList, GameList& gl, SearchOptions& options) {
- return -1;
- }
- Algo_signature::Algo_signature(int bsize) : Algorithm(bsize) {
- main_variation = true;
- }
- Algo_signature::~Algo_signature() {
- }
- void Algo_signature::initialize_process(sqlite3* DB) throw(DBError) {
- db = DB;
- char sql[100];
- sprintf(sql, "create table algo_signature_%d ( id integer primary key, signature varchar(12) );", boardsize);
- int rc = sqlite3_exec(db, sql, 0, 0, 0);
- //if (rc != SQLITE_OK) throw DBError();
- sprintf(sql, "create index sig_idx on algo_signature_%d(signature);", boardsize);
- rc = sqlite3_exec(db, sql, 0, 0, 0);
- //if (rc != SQLITE_OK) throw DBError();
- }
- void Algo_signature::newgame_process(int game_id) {
- main_variation = true;
- counter = 0;
- gid = game_id;
- signature = new char[12];
- for(int i=0; i<12; i++) signature[i] = '?';
- }
- void Algo_signature::AB_process(int x, int y) {
- }
- void Algo_signature::AW_process(int x, int y) {
- }
- void Algo_signature::AE_process(int x, int y, char removed) {
- }
- void Algo_signature::endOfNode_process() {
- }
- void Algo_signature::move_process(Move m) {
- if (!main_variation) return;
- counter++;
- if (counter==20) {
- signature[0] = m.x + 97;
- signature[1] = m.y + 97;
- }
- if (counter==40) {
- signature[2] = m.x + 97;
- signature[3] = m.y + 97;
- }
- if (counter==60) {
- signature[4] = m.x + 97;
- signature[5] = m.y + 97;
- }
- if (counter==31) {
- signature[6] = m.x + 97;
- signature[7] = m.y + 97;
- }
- if (counter==51) {
- signature[8] = m.x + 97;
- signature[9] = m.y + 97;
- }
- if (counter==71) {
- signature[10] = m.x + 97;
- signature[11] = m.y + 97;
- }
- }
- void Algo_signature::pass_process() {
- if (main_variation) move_process(Move(19,19,'p'));
- }
- void Algo_signature::branchpoint_process() {
- }
- void Algo_signature::endOfVariation_process() {
- main_variation = false;
- }
- char* symmetrize(char* signature, int boardsize) {
- // symmetrize signature
- char* min_signature = new char[12];
- for(int i=0; i<12; i++) min_signature[i] = signature[i];
- for (int f=0; f<8; f++) { // for all flips
- // compute flipped signature
- char* next = new char[12];
- for(int i=0; i<6; i++) {
- if ('a' <= signature[2*i] && signature[2*i] <= 's')
- next[2*i] = Pattern::flipsX(f, signature[2*i]-'a', signature[2*i+1]-'a', boardsize-1, boardsize-1)+'a';
- else next[2*i] = signature[2*i];
- if ('a' <= signature[2*i+1] && signature[2*i+1] <= 's')
- next[2*i+1] = Pattern::flipsY(f, signature[2*i]-'a', signature[2*i+1]-'a', boardsize-1, boardsize-1)+'a';
- else next[2*i+1] = signature[2*i+1];
- }
- // if next < min_signature, then swap
- for(int j=0; j<12; j++) {
- if (next[j] > min_signature[j]) break;
- if (next[j] < min_signature[j]) {
- char* help = next;
- next = min_signature;
- min_signature = help;
- break;
- }
- }
- delete [] next;
- }
- return min_signature;
- }
- void Algo_signature::endgame_process(bool commit) throw(DBError) {
- if (commit) {
- char* min_signature = symmetrize(signature, boardsize);
- char sql[100];
- sprintf(sql, "insert into algo_signature_%d (id, signature) values (?,?);", boardsize);
- if (dbinsert1blob(db, sql, gid, min_signature, 12)) throw DBError();
- // for(int i=0; i<12; i++) printf("%c", min_signature[i]); printf("\n");
- delete [] min_signature;
- }
- delete [] signature;
- }
- void Algo_signature::finalize_process() {
- }
- char* Algo_signature::get_current_signature() {
- return symmetrize(signature, boardsize);
- }
- vector<int> Algo_signature::search_signature(char* sig) {
- // to be used during processing! (because we need the db)
- char sql[100];
- sprintf(sql, "select id from algo_signature_%d where signature=? order by id", boardsize);
- sqlite3_stmt *ppStmt=0;
- vector<int> result;
- int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0);
- if (rc != SQLITE_OK || ppStmt==0) throw DBError();
- rc = sqlite3_bind_blob(ppStmt, 1, sig, 12, SQLITE_TRANSIENT);
- if (rc != SQLITE_OK || ppStmt==0) throw DBError();
- do {
- rc = sqlite3_step(ppStmt);
- if (rc != SQLITE_DONE && rc != SQLITE_ROW) throw DBError();
- if (rc == SQLITE_ROW) {
- result.push_back(sqlite3_column_int(ppStmt, 0));
- }
- } while (rc == SQLITE_ROW);
- rc = sqlite3_finalize(ppStmt);
- if (rc != SQLITE_OK) throw DBError();
- return result;
- }
- Algo_finalpos::Algo_finalpos(int bsize) : Algorithm(bsize) {
- fp = 0;
- fpIndex = -1;
- data = 0;
- }
- Algo_finalpos::~Algo_finalpos() {
- if (data) {
- for(map<int, char* >::iterator it = data->begin(); it != data->end(); it++) delete [] it->second;
- delete data;
- }
- }
- void Algo_finalpos::initialize_process(sqlite3* DB) throw(DBError) {
- // printf("init Algo_finalpos\n");
- db = DB;
- char sql[100];
- sprintf(sql, "create table algo_finalpos_%d ( id integer primary key, data blob );", boardsize);
- int rc = sqlite3_exec(db, sql, 0, 0, 0);
- if (rc != SQLITE_OK) {
- //throw DBError();
- }
- // printf("init Algo_finalpos\n");
- }
- void Algo_finalpos::newgame_process(int game_id) {
- gid = game_id;
- fp = new char[100];
- for(int i=0; i<100; i++) fp[i] = 255;
- }
- void Algo_finalpos::AB_process(int x, int y) {
- fp[y/2 + 10*(x/2)] &= ~(1 << (2*(x%2 + 2*(y%2))));
- }
- void Algo_finalpos::AW_process(int x, int y) {
- fp[y/2 + 10*(x/2)] &= ~(1 << (2*(x%2 + 2*(y%2))+1));
- }
- void Algo_finalpos::AE_process(int x, int y, char removed) {
- }
- void Algo_finalpos::endOfNode_process() {
- }
- void Algo_finalpos::move_process(Move m) {
- if (m.color == 'B')
- fp[m.y/2 + 10*(m.x/2)] &= ~(1 << (2*(m.x%2 + 2*(m.y%2))));
- else if (m.color == 'W')
- fp[m.y/2 + 10*(m.x/2)] &= ~(1 << (2*(m.x%2 + 2*(m.y%2))+1));
- }
- void Algo_finalpos::pass_process() {
- }
- void Algo_finalpos::branchpoint_process() {
- }
- void Algo_finalpos::endOfVariation_process() {
- }
- void Algo_finalpos::endgame_process(bool commit) throw(DBError) {
- if (commit) {
- char sql[100];
- sprintf(sql, "insert into algo_finalpos_%d (id, data) values (?,?);", boardsize);
- if (dbinsert1blob(db, sql, gid, fp, 100)) throw DBError();
- }
- delete [] fp;
- }
- void Algo_finalpos::finalize_process() {
- }
- int Algo_finalpos::readDB(sqlite3* DB) {
- db = DB;
- if (data) {
- for(map<int, char* >::iterator it = data->begin(); it != data->end(); it++) delete [] it->second;
- delete data;
- }
- data = new map<int, char* >;
- int rc = sqlite3_exec(db, "begin transaction;", 0, 0, 0);
- if (rc) throw DBError();
- sqlite3_stmt *ppStmt=0;
- char sql[100];
- sprintf(sql, "select id, data from algo_finalpos_%d order by id", boardsize);
- rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0);
- if (rc != SQLITE_OK || ppStmt==0) return rc; // FIXME: catch certain errors, (and/or throw DBError?)
- while (sqlite3_step(ppStmt) == SQLITE_ROW) {
- // printf("step0\n");
- int index = sqlite3_column_int(ppStmt, 0);
- char* d = (char*)sqlite3_column_blob(ppStmt, 1);
- // printf("step1\n");
- char* d1 = new char[100];
- // printf("step2\n");
- for(int i=0; i<100; i++) d1[i] = d[i];
- // printf("step3\n");
- // printf("insert %d %p\n", index, d1);
- data->insert(make_pair(index, d1));
- }
- // printf("done\n");
- rc = sqlite3_finalize(ppStmt);
- if (rc != SQLITE_OK) return rc;
- rc = sqlite3_exec(db, "commit;", 0, 0, 0);
- if (rc != SQLITE_OK) throw DBError();
- return 0;
- }
- int Algo_finalpos::search(PatternList& patternList, GameList& gl, SearchOptions& options) { // progress bar?!
- // Put the pattern into bitmap format, which is the format the final
- // positions are stored in in the database. This makes the comparisons
- // faster.
- int plS = patternList.size();
- char_p** allbits = new char_p*[plS];
- int** allbitlengths = new int*[plS];
- for(int N=0; N<plS; N++) {
- Pattern* pattern = &patternList.data[N];
- allbits[N] = new char_p[4];
- allbitlengths[N] = new int[4];
- for(int i=0; i<2; i++) {
- for(int j=0; j<2; j++) {
- int xBlocks = (pattern->sizeY+i+1)/2;
- int yBlocks = (pattern->sizeX+j+1)/2;
- char* nextBlock = new char[400];
- int nextBlockIndex = 0;
- nextBlock[nextBlockIndex++] = yBlocks;
- for(int k1=0; k1 < yBlocks; k1++) {
- char nlist[400];
- int nlistIndex = 0;
- for(int k2=0; k2 < xBlocks; k2++) {
- int n = 0;
- for(int x=0; x<2; x++) {
- for(int y=0; y<2; y++) {
- int indexX = k1 * 2 + y - j;
- int indexY = k2 * 2 + x - i;
- if (0 <= indexX && indexX < pattern->sizeX && 0 <= indexY && indexY < pattern->sizeY) {
- if (pattern->getFinal(indexX,indexY)=='X')
- n |= 1 << (2*(2*x+y));
- else if (pattern->getFinal(indexX,indexY)=='O')
- n |= 1 << (2*(2*x+y)+1);
- }
- }
- }
- nlist[nlistIndex++] = n;
- }
- int start = 0;
- int end = nlistIndex;
- while (start < end && !nlist[start]) start++;
- while (end > start && !nlist[end-1]) end--;
- nextBlock[nextBlockIndex++] = start;
- nextBlock[nextBlockIndex++] = end-start;
- for(int current=start; current < end; current++)
- nextBlock[nextBlockIndex++] = nlist[current];
- }
- char* nB = new char[nextBlockIndex];
- for(int ii=0; ii<nextBlockIndex; ii++) nB[ii] = nextBlock[ii];
- allbitlengths[N][2*i + j] = nextBlockIndex;
- allbits[N][2*i + j] = nB;
- delete [] nextBlock;
- }
- }
- }
- int index = gl.start();
- // int counter = 0; // to keep track of progress bar
- // printf("%d patterns\n", plS);
- char start;
- char length;
- char x;
- char y;
- while (index != -1) {
- // if (!(counter++ % 1000)) printf("counter: %d, index: %d\n", counter, index);
- // if (progBar && !(counter % 100))
- // progBar.redraw((progEnd-progStart)*counter/len(gl.current) + progStart);
- map<int, char* >::iterator it = data->find(index);
- if (it == data->end()) {
- // printf("skip\n");
- index = gl.next();
- continue;
- }
- char* finalpos = it->second;
- // printf("index %d, %p\n", index, finalpos);
- vector<Candidate* > *matchList = new vector<Candidate* >;;
- for(int N=0; N<plS; N++) {
- Pattern* pattern = &patternList.data[N];
- for(int a0=pattern->left; a0 <= pattern->right; a0++) {
- for(int a1 = pattern->top; a1 <= pattern->bottom; a1++) {
- int matches = 1;
- int pIndex = 2*(a1%2) + (a0%2);
- char* pbits = allbits[N][pIndex];
- int pbIndex = 0;
- int fpIndex = a1/2 + (a0/2)*10;
- for(x=0; x < pbits[0]; x++) {
- start = pbits[++pbIndex];
- length = pbits[++pbIndex];
- fpIndex += start;
- for(y=0; y<length; y++) {
- pbIndex++;
- if (pbits[pbIndex] & finalpos[fpIndex]) {
- matches = 0;
- break;
- }
- fpIndex++;
- }
- if (!matches) break;
- fpIndex += 10 - start - length;
- }
- if (matches) matchList->push_back(new Candidate(a0,a1,N));
- }
- }
- }
- if (matchList->size()) gl.makeCurrentCandidate(matchList);
- else delete matchList;
- index = gl.next();
- }
- {
- for(int N=0; N<plS; N++) {
- delete [] allbitlengths[N];
- for(int i=0; i<4; i++)
- if (allbits[N][i]) delete [] allbits[N][i];
- delete [] allbits[N];
- }
- }
- delete [] allbitlengths;
- delete [] allbits;
- return 0;
- }
- bool Algo_finalpos::equal(unsigned int i1, unsigned int i2) {
- // not to be used during processing
- // i1, i2 correspond to game id's
- sqlite3_stmt *ppStmt=0;
- char sql[100];
- sprintf(sql, "select data from algo_finalpos_%d where id = %d or id = %d", boardsize, i1, i2);
- int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0);
- if (rc != SQLITE_OK || ppStmt==0) return false; // FIXME: catch certain errors, (and/or throw DBError?)
- if (sqlite3_step(ppStmt) == SQLITE_ROW) {
- char* dd1 = (char*)sqlite3_column_blob(ppStmt, 0);
- char* d1 = new char[100];
- for(int i=0; i<100; i++) d1[i] = dd1[i]; // FIXME: is this necessary?
- if (sqlite3_step(ppStmt) == SQLITE_ROW) {
- char* d2 = (char*)sqlite3_column_blob(ppStmt, 0);
- for(int i=0; i<100; i++)
- if (d1[i] != d2[i]) {
- delete [] d1;
- sqlite3_finalize(ppStmt);
- return false;
- }
- delete [] d1;
- sqlite3_finalize(ppStmt);
- return true;
- }
- delete [] d1;
- }
- sqlite3_finalize(ppStmt);
- return false;
- }
- bool Algo_finalpos::equals_current(unsigned int id1) {
- // to be used only during processing
- // id1 here corresponds to a game id
- bool result = true;
- sqlite3_stmt *ppStmt=0;
- char sql[100];
- sprintf(sql, "select data from algo_finalpos_%d where id = %d", boardsize, id1);
- int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0);
- if (rc != SQLITE_OK || ppStmt==0) return false; // FIXME: catch certain errors, (and/or throw DBError?)
- if (sqlite3_step(ppStmt) == SQLITE_ROW) {
- char* d = (char*)sqlite3_column_blob(ppStmt, 0);
- for(int i=0; i<100; i++)
- if (d[i] != fp[i]) {
- result = false;
- break;
- }
- } else result = false;
- sqlite3_finalize(ppStmt);
- return result;
- }
- Algo_movelist::Algo_movelist(int bsize) : Algorithm(bsize) {
- data1 = 0;
- data2 = 0;
- data1l = 0;
- }
- Algo_movelist::~Algo_movelist() {
- if (data1) {
- for(map<int, char* >::iterator it = data1->begin(); it != data1->end(); it++) {
- delete [] it->second;
- }
- delete data1;
- }
- if (data2) {
- for(map<int, char* >::iterator it = data2->begin(); it != data2->end(); it++) {
- delete [] it->second;
- }
- delete data2;
- }
- if (data1l) delete data1l;
- }
- void Algo_movelist::initialize_process(sqlite3* DB) throw(DBError) {
- // printf("init Algo_movelist\n");
- db = DB;
- char sql[100];
- sprintf(sql, "create table algo_movelist_%d ( id integer primary key, movelist blob, fpC blob );", boardsize);
- int rc = sqlite3_exec(db, sql, 0, 0, 0);
- //if (rc != SQLITE_OK) throw DBError();
- // printf("init Algo_movelist\n");
- }
- void Algo_movelist::newgame_process(int game_id) {
- gid = game_id;
- movelist = vector<char>();
- fpC = new char[50];
- for(int i=0; i<50; i++) fpC[i] = 0;
- }
- void Algo_movelist::AB_process(int x, int y) {
- movelist.push_back((char)x);
- movelist.push_back((char)(y | BLACK));
- }
-
- void Algo_movelist::AW_process(int x, int y) {
- movelist.push_back((char)x);
- movelist.push_back((char)(y | WHITE));
- }
- void Algo_movelist::AE_process(int x, int y, char removed) {
- movelist.push_back((char)x);
- if (removed == 'B') movelist.push_back((char)(y | REMOVE | BLACK));
- else if (removed == 'W') movelist.push_back((char)(y | REMOVE | WHITE));
- }
- void Algo_movelist::endOfNode_process() {
- if (movelist.size()>1) {
- if (movelist[movelist.size()-2] & (ENDOFNODE | BRANCHPOINT | ENDOFVARIATION)) {
- movelist.push_back(ENDOFNODE);
- movelist.push_back(0);
- } else {
- movelist[movelist.size()-2] |= ENDOFNODE;
- }
- } else {
- movelist.push_back(ENDOFNODE);
- movelist.push_back(0);
- }
- }
- void Algo_movelist::move_process(Move m) {
- if (!movelist.size()) {
- movelist.push_back(ENDOFNODE);
- movelist.push_back(0);
- }
- movelist.push_back(m.x);
- if (m.color=='B') movelist.push_back(m.y | BLACK);
- else movelist.push_back(m.y | WHITE);
- if (m.captures) {
- vector<p_cc>::iterator it;
- for(it = m.captures->begin(); it != m.captures->end(); it++) {
- int xx = it->first;
- int yy = it->second;
- movelist.push_back(xx);
- if (m.color=='B') movelist.push_back(yy | REMOVE | WHITE);
- else movelist.push_back(yy | REMOVE | BLACK);
- fpC[yy/4 + 5*(xx/2)] |= 1 << (xx%2 + 2*(yy%4));
- }
- }
- }
- void Algo_movelist::pass_process() {
- movelist.push_back(19);
- movelist.push_back(19);
- }
- void Algo_movelist::branchpoint_process() {
- movelist.push_back(BRANCHPOINT);
- movelist.push_back(0);
- }
- void Algo_movelist::endOfVariation_process() {
- movelist.push_back(ENDOFVARIATION);
- movelist.push_back(0);
- }
- void Algo_movelist::endgame_process(bool commit) throw(DBError) {
- if (commit) {
- char* ml = new char[movelist.size()];
- int mlIndex = 0;
- for(vector<char>::iterator it = movelist.begin(); it != movelist.end(); it++) {
- ml[mlIndex++] = *it;
- }
- char sql[100];
- sprintf(sql, "insert into algo_movelist_%d (id, movelist, fpC) values (?, ?, ?);", boardsize);
- if (dbinsert2blobs(db, sql, gid, ml, mlIndex, fpC, 50)) throw DBError();
- delete [] ml;
- }
- delete [] fpC;
- }
- void Algo_movelist::finalize_process() {
- }
- int Algo_movelist::readDB(sqlite3* DB) {
- if (data1) {
- for(map<int, char* >::iterator it = data1->begin(); it != data1->end(); it++) delete [] it->second;
- delete data1;
- }
- data1 = new map<int, char* >;
- if (data1l) delete data1l;
- data1l = new map<int, int >;
- if (data2) {
- for(map<int, char* >::iterator it = data2->begin(); it != data2->end(); it++) delete [] it->second;
- delete data2;
- }
- data2 = new map<int, char* >;
- db = DB;
- int rc = sqlite3_exec(db, "begin transaction;", 0, 0, 0);
- if (rc) throw DBError();
- sqlite3_stmt *ppStmt=0;
- char sql[100];
- sprintf(sql, "select movelist,fpC,id from algo_movelist_%d order by id", boardsize);
- rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0);
- if (rc != SQLITE_OK || ppStmt==0) return rc; // FIXME: catch certain errors, (and/or throw DBError?)
- while (sqlite3_step(ppStmt) == SQLITE_ROW) {
- int l = sqlite3_column_bytes(ppStmt,0);
- // printf("len movelist: %d\n", l);
- char* d = (char*)sqlite3_column_blob(ppStmt, 0);
- char* d1 = new char[l];
- for(int i=0; i<l; i++) {
- d1[i] = d[i];
- // printf("%c", (d[i] & 31)+97);
- }
- int index = sqlite3_column_int(ppStmt, 2);
- // printf("\n");
- data1->insert(make_pair(index, d1));
- data1l->insert(make_pair(index, l));
- d = (char*)sqlite3_column_blob(ppStmt, 1);
- d1 = new char[50];
- {
- for(int i=0; i<50; i++) d1[i] = d[i];
- }
- data2->insert(make_pair(index, d1));
- }
- rc = sqlite3_finalize(ppStmt);
- if (rc != SQLITE_OK) return rc;
- rc = sqlite3_exec(db, "commit;", 0, 0, 0);
- if (rc != SQLITE_OK) throw DBError();
- // printf("data sizes %d, %d, %d\n", data1->size(), data1l->size(), data2->size());
- return 0;
- }
- MovelistCand::MovelistCand(Pattern* P, int ORIENTATION, char* DICTS, int NO, char X, char Y) {
- orientation = ORIENTATION;
- p = P;
- mx = X;
- my = Y;
- Xinterv = make_pair(mx, mx+p->sizeX);
- Yinterv = make_pair(my, my+p->sizeY);
- dicts = DICTS;
- dictsNO = NO;
- contListIndex = 0;
- dictsFound = false;
- dictsFoundInitial = false;
- dictsDR = false;
- contList = p->contList; // FIXME
- }
- MovelistCand::~MovelistCand() {
- delete [] dicts;
- }
- char MovelistCand::dictsget(char x, char y) {
- return dicts[x-mx + p->sizeX*(y-my)];
- }
- void MovelistCand::dictsset(char x, char y, char d) {
- dicts[x-mx + p->sizeX*(y-my)] = d;
- }
- bool MovelistCand::in_relevant_region(char x, char y) {
- return (mx <= x && x < mx + p->sizeX && my <= y && y < my + p->sizeY);
- }
- VecMC::VecMC() : vector<MovelistCand* >() {
- candssize = 0;
- }
- VecMC::~VecMC() {
- for(VecMC::iterator it = begin(); it != end(); it++) {
- if (*it) delete *it;
- }
- }
- VecMC* VecMC::deepcopy(ExtendedMoveNumber& COUNTER, int CANDSSIZE) {
- VecMC* result = new VecMC;
- result->candssize = CANDSSIZE;
- result->counter = COUNTER;
- for(VecMC::iterator it = begin(); it != end(); it++) {
- MovelistCand* mlc = 0;
- if (*it) {
- char* DICTS = new char[(*it)->p->sizeX * (*it)->p->sizeY];
- for (int i=0; i < (*it)->p->sizeX * (*it)->p->sizeY; i++) DICTS[i] = (*it)->dicts[i];
- mlc = new MovelistCand((*it)->p, (*it)->orientation, DICTS, (*it)->dictsNO, (*it)->mx, (*it)->my);
- mlc->contListIndex = (*it)->contListIndex;
- mlc->dictsFound = (*it)->dictsFound;
- mlc->dictsF = (*it)->dictsF;
- mlc->dictsFoundInitial = (*it)->dictsFoundInitial;
- mlc->dictsFI = (*it)->dictsFI;
- mlc->dictsDR = (*it)->dictsDR;
- mlc->contL…
Large files files are truncated, but you can click here to view the full file