root/06/devel-old/abstractBoard.cc

Revision 154, 11.7 kB (checked in by ug, 4 years ago)

Typo in abstractBoard.cc

Line 
1 // File: abstractBoard.cc
2
3 //   Copyright (C) 2001-4 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
24
25 #include "abstractBoard.h"
26 #include <stdio.h>
27 #include <cstring>
28
29
30 BoardError::BoardError() {}
31
32 Move::Move(char xx, char yy, char cc) {
33   x = xx;
34   y = yy;
35   c = cc;
36   captures = 0;
37 }
38
39 Move::Move(const Move& m) {
40   x = m.x;
41   y = m.y;
42   c = m.c;
43   if (m.captures) {
44     captures = new vector<p_cc>;
45     vector<p_cc>::iterator it;
46     for(it = m.captures->begin(); it != m.captures->end(); it++)
47       captures->push_back(*it);
48   }
49   else captures = 0;
50 }
51
52 Move::~Move() {
53   if (captures) delete captures;
54 }
55
56
57 Move& Move::copy(const Move& m) {
58   if (this != &m) {
59     x = m.x;
60     y = m.y;
61     c = m.c;
62     if (captures) delete captures;
63     if (m.captures) {
64       captures = new vector<p_cc>;
65       vector<p_cc>::iterator it;
66       for(it = m.captures->begin(); it != m.captures->end(); it++)
67         captures->push_back(*it);
68     }
69     else captures = 0;
70   }
71   return *this;
72 }
73
74
75 abstractBoard::abstractBoard(int bs) throw(BoardError) {
76   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(int) 0\n");
77   boardsize = bs;
78   if (boardsize < 3) throw BoardError();
79   status = new char[boardsize*boardsize+1];
80   for (int i = 0; i < boardsize*boardsize; i++)
81       status[i] = ' ';
82   status[boardsize*boardsize] = 0;
83   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(int) 100\n");
84 }
85
86
87 abstractBoard::abstractBoard(const abstractBoard& ab) {
88   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(abstractBoard) 0\n");
89   printf("copy constructor\n");
90   boardsize = ab.boardsize;
91   status = new char[boardsize*boardsize+1];
92   for (int i = 0; i < boardsize*boardsize; i++)
93       status[i] = ab.status[i];
94   status[boardsize*boardsize] = 0;
95   undostack = stack<Move>(ab.undostack);
96   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(abstractBoard) 100\n");
97 }
98
99
100 abstractBoard::~abstractBoard() {
101   if (DEBUG_ABSTRACTBOARD) printf("AB::~abstractBoard 0\n");
102   delete []status;
103   if (DEBUG_ABSTRACTBOARD) printf("AB::~abstractBoard 100\n");
104 }
105
106 abstractBoard& abstractBoard::copy(const abstractBoard& ab) {
107   if (DEBUG_ABSTRACTBOARD) printf("AB::copy 0\n");
108   printf("copy assignment operator\n");
109   if (this != &ab) {
110     delete status;
111     boardsize = ab.boardsize;
112     status = new char[boardsize*boardsize+1];
113     for (int i = 0; i < boardsize*boardsize; i++)
114       status[i] = ab.status[i];
115     status[boardsize*boardsize] = 0;
116     undostack = ab.undostack;
117   }
118   if (DEBUG_ABSTRACTBOARD) printf("AB::copy 100\n");
119   return *this;
120 }
121
122 char abstractBoard::getStatus(int x, int y) {
123   if (DEBUG_ABSTRACTBOARD) printf("AB::getStatus 0\n");
124   return status[boardsize*x + y];
125 }
126
127
128 void abstractBoard::setStatus(int x, int y, char val) {
129   if (DEBUG_ABSTRACTBOARD) printf("AB::setStatus 0\n");
130   if (val=='b' || val=='B') status[boardsize*x + y] = 'B';
131   else if (val=='w' || val=='W') status[boardsize*x + y] = 'W';
132   else status[boardsize*x + y] = val;
133   if (DEBUG_ABSTRACTBOARD) printf("AB::setStatus 100\n");
134 }
135
136
137 int abstractBoard::len_cap_last() {
138   if (DEBUG_ABSTRACTBOARD) printf("AB::len_cap_last 0\n");
139   if (!undostack.size()) {
140     return -1;
141     printf("Error len_cap_last\n"); // FIXME
142   }
143   Move m = undostack.top();
144   if (m.captures) return m.captures->size();
145   else return 0;
146 }
147
148 PyObject* abstractBoard::get_cap_last() {
149   if (DEBUG_ABSTRACTBOARD) printf("AB::get_cap_last 0\n");
150   if (!undostack.size()) {
151     Py_INCREF(Py_None);
152     return Py_None;
153   }
154   Move m = undostack.top();
155   PyObject* cap = PyList_New(0);
156   if (!m.captures) return cap;
157   vector<p_cc>::iterator it;
158   for(it = m.captures->begin(); it != m.captures->end(); it++)
159     PyList_Append(cap, Py_BuildValue("(ii)", it->first, it->second));
160   if (DEBUG_ABSTRACTBOARD) printf("AB::get_cap_last 100\n");
161   return cap;
162 }
163
164 PyObject* abstractBoard::undostack_pop() {
165   if (DEBUG_ABSTRACTBOARD) printf("AB::undostack_pop 0\n");
166   if (!undostack.size()) {
167     Py_INCREF(Py_None);
168     return Py_None;
169   }
170   Move m = undostack.top();
171   undostack.pop();
172   PyObject* cap = PyList_New(0);
173   if (m.captures) {
174     vector<p_cc>::iterator it;
175     for(it = m.captures->begin(); it != m.captures->end(); it++)
176       PyList_Append(cap, Py_BuildValue("(ii)", it->first, it->second));
177   }
178   if (DEBUG_ABSTRACTBOARD) printf("AB::undostack_pop 100\n");
179   return Py_BuildValue("(ii)cO", m.x, m.y, m.c, cap);
180 }
181
182 void abstractBoard::undostack_append_pass() {
183   if (DEBUG_ABSTRACTBOARD) printf("AB::undostack_append_pass 0\n");
184   undostack.push(Move(20,20,'-'));
185   if (DEBUG_ABSTRACTBOARD) printf("AB::undostack_append_pass 100\n");
186 }
187
188 int abstractBoard::len_undostack() {
189   if (DEBUG_ABSTRACTBOARD) printf("AB::len_undostack 0\n");
190   return undostack.size();
191 }
192
193
194
195 int* abstractBoard::neighbors(int x, int y) {
196   int* result = new int[5];
197   char resultIndex = 1;
198   if (x-1 >= 0) result[resultIndex++]=(x-1) * boardsize + y;
199   if (x+1 < boardsize) result[resultIndex++]=(x+1) * boardsize + y;
200   if (y-1 >= 0) result[resultIndex++]=x * boardsize + y-1;
201   if (y+1 < boardsize) result[resultIndex++]=x*boardsize + y+1;
202   result[0] = resultIndex-1;
203   return result;
204 }
205
206
207 void abstractBoard::clear() {
208   for(int i=0; i<boardsize*boardsize; i++) status[i]=' ';
209   undostack = stack<Move>();
210 }
211
212
213 int abstractBoard::play(PyObject* pos, char* color) throw(BoardError) {
214   if (DEBUG_ABSTRACTBOARD) printf("AB::play(PyObject*,char*) 0\n");
215   int x = PyInt_AsLong(PyTuple_GetItem(pos,0));
216   int y = PyInt_AsLong(PyTuple_GetItem(pos,1));
217   return play(x, y, color);
218 }
219
220
221 int abstractBoard::play(int x, int y, char* color) throw (BoardError) {
222   if (DEBUG_ABSTRACTBOARD) printf("AB::play(int,int,char*) 0\n");
223   if (x<0 || x>=boardsize || y<0 || y>=boardsize) return 0;
224   if (status[boardsize*x+y] != ' ') {
225     return 0;
226   }
227
228   //  if (color[0]!='B' && color[0]!='W') printf("%c\n", color[0]);
229
230   vector<p_cc>* captures = legal(x, y, color[0]);
231   if (captures) {
232     vector<p_cc>::iterator it;
233     for(it=captures->begin(); it!=captures->end(); it++)
234       status[boardsize*it->first + it->second] = ' '; // remove captured stones, if any
235     Move m(x, y, color[0]);
236     if (captures->size()) m.captures = captures;
237     else delete captures;
238     undostack.push(m);
239     if (DEBUG_ABSTRACTBOARD) printf("AB::play(int,int,char*) ret1 100\n");
240     return 1;
241   }
242   if (DEBUG_ABSTRACTBOARD) printf("AB::play(int,int,char*) ret0 200\n");
243   return 0;
244 }
245
246
247 vector<p_cc>* abstractBoard::legal(int x, int y, char color) {
248   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 0\n");
249   vector<p_cc>* c = new vector<p_cc>;
250   int* nb = neighbors(x,y);
251   for(int i=1; i<=nb[0]; i++) {
252     int x1 = nb[i] / boardsize;
253     int y1 = nb[i] % boardsize;
254     if (status[boardsize*x1 + y1] == invert(color)) {
255       vector<p_cc>* d = hasNoLibExcP(x1, y1, x*boardsize+y);
256       if (DEBUG_ABSTRACTBOARD) printf("AB::legal 39\n");
257       if (DEBUG_ABSTRACTBOARD) printf("AB::legal 40, %d\n", d->size());
258       vector<p_cc>::iterator it;
259       for(it = d->begin(); it != d->end(); it++) c->push_back(*it);
260       if (DEBUG_ABSTRACTBOARD) printf("AB::legal 41\n");
261       delete d;
262     }
263   }
264   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 42\n");
265   setStatus(x,y,color);
266
267   if (c->size()) {
268     vector<p_cc>* captures = new vector<p_cc>();
269     while (c->size()) {
270       p_cc ctop = (*c)[0];
271       bool contained = false;
272       vector<p_cc>::iterator it;
273       for(it = captures->begin(); it != captures->end(); it++) {
274         if (ctop.first == it->first && ctop.second == it->second) {
275           contained = true;
276           break;
277         }
278       }
279       if (!contained) captures->push_back(ctop);
280       c->erase(c->begin());
281     }
282     delete c;
283     if (DEBUG_ABSTRACTBOARD) printf("AB::legal 98\n");
284     return captures;
285   }
286   delete c;
287   vector<p_cc>* d = hasNoLibExcP(x, y);
288   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 49\n");
289   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 50, %d\n", d->size());
290   if (d->size()) {
291     delete d;
292     status[boardsize*x + y] = ' ';
293     if (DEBUG_ABSTRACTBOARD) printf("AB::legal 99\n");
294     return 0;
295   }
296   else {
297     delete d;
298     vector<p_cc>* ret = new vector<p_cc>();
299     if (DEBUG_ABSTRACTBOARD) printf("AB::legal 100\n");
300     return ret;
301   }
302 }
303
304 vector<p_cc>* abstractBoard::hasNoLibExcP(int x1, int y1, int exc) {
305   if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 0\n");
306   vector<p_cc>* st = new vector<p_cc>;
307   vector<p_cc>* newlyFound = new vector<p_cc>;
308   newlyFound->push_back(p_cc(x1, y1));
309   vector<p_cc>* n;
310   int foundNew = 1;
311        
312   while (foundNew) {
313     foundNew = 0;
314     n = new vector<p_cc>;
315     vector<p_cc>::iterator it1;
316     for(it1=newlyFound->begin(); it1!=newlyFound->end(); it1++) {
317       int x = it1->first;
318       int y = it1->second;
319       int* nbs = neighbors(x,y);
320       if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 7 (%d,%d) %d\n",x, y,nbs[0]);
321       for (int j=1; j <= nbs[0]; j++) {
322         int yy1 = nbs[j];
323         if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 99\n");
324         if (status[yy1] == ' ' && yy1 != exc) {
325           delete [] nbs;
326           return new vector<p_cc>;
327         }
328         else {
329           if (status[yy1]==status[x*boardsize+y]) {
330             p_cc yy(yy1/boardsize, yy1%boardsize);
331             int foundNewHere = 1;
332             vector<p_cc>::iterator it;
333             for(it = st->begin(); it!=st->end(); it++) {
334               if (it->first==yy.first && it->second==yy.second) {
335                 foundNewHere = 0;
336                 break;
337               }
338             }
339             if (foundNewHere) {
340               for(it=newlyFound->begin(); it!=newlyFound->end(); it++) {
341                 if (it->first==yy.first && it->second==yy.second) {
342                   foundNewHere = 0;
343                   break;
344                 }
345               }
346             }
347             if (foundNewHere) {
348               n->push_back(yy);
349               foundNew = 1;
350             }
351           }
352         }
353       }
354       delete [] nbs;
355     }
356    
357     vector<p_cc>::iterator it;
358     for(it=newlyFound->begin(); it!=newlyFound->end(); it++) {
359       if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 10, (%d,%d)\n", it->first, it->second);
360       st->push_back(*it);
361     }
362     delete newlyFound;
363     newlyFound = n;
364   }
365   if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 100\n");
366   delete n;
367   return st;
368 }
369
370
371 void abstractBoard::undo(int n) {
372   if (DEBUG_ABSTRACTBOARD) printf("AB::undo 0\n");
373   for(int i=0; i<n; i++) {
374     if (DEBUG_ABSTRACTBOARD) printf("AB::undo 1 %d\n", i);
375     if (undostack.size()) {
376       Move tuple = undostack.top();
377       undostack.pop();
378      
379       char color = tuple.c;
380       vector<p_cc>* captures = tuple.captures;
381       int x = tuple.x;
382       int y = tuple.y;
383
384       status[x*boardsize+y] = ' ';
385       if (captures) {
386         for(unsigned int i=0; i < captures->size(); i++) {
387           p_cc t = (*captures)[i];
388           setStatus(t.first, t.second, invert(color));
389         }
390       }
391     }
392   } 
393   if (DEBUG_ABSTRACTBOARD) printf("AB::undo 100\n");
394 }
395
396
397 void abstractBoard::remove(int x, int y) {
398   if (DEBUG_ABSTRACTBOARD) printf("AB::remove 0\n");
399   PyObject* l = PyList_New(0);
400   PyList_Append(l, Py_BuildValue("(ii)", x, y));
401   undostack.push(Move(-1, -1, invert(status[boardsize*x+y])));
402   status[boardsize*x+y] = ' ';
403   if (DEBUG_ABSTRACTBOARD) printf("AB::remove 100\n");
404 }
405
406
407 char abstractBoard::invert(char color) {
408   if (color == 'B' || color == 'b') return 'W';
409   if (color == 'W' || color == 'w') return 'B';
410   return ' ';
411 }
412
Note: See TracBrowser for help on using the browser.