root/06/libkombilo-branches/hash_center_makedb/abstractboard.cpp

Revision 225, 11.5 kB (checked in by ug, 2 years ago)

Fix some of the small FIXME\'s

Line 
1 // File: abstractboard.cpp
2 // part of libkombilo, http://www.u-go.net/kombilo/
3
4 // Copyright (c) 2006-7 Ulrich Goertz <u@g0ertz.de>
5
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of
7 // this software and associated documentation files (the "Software"), to deal in
8 // the Software without restriction, including without limitation the rights to
9 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10 // of the Software, and to permit persons to whom the Software is furnished to do
11 // so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23
24 #include "abstractboard.h"
25 using std::stack;
26 using std::vector;
27
28 BoardError::BoardError() {}
29
30 MoveNC::MoveNC() {
31   x = -1;
32   y = -1;
33   color = ' ';
34 }
35
36 // coordinates used here: top left = (0,0) - bottom right = (boardsize-1,boardsize-1)
37 MoveNC::MoveNC(char X, char Y, char COLOR) {
38   x = X;
39   y = Y;
40   color = COLOR;
41 }
42
43 bool MoveNC::operator==(const MoveNC& mnc) const {
44   if (x == mnc.x && y == mnc.y && color == mnc.color) return true;
45   else return false;
46 }
47
48 Move::Move(char xx, char yy, char cc) : MoveNC(xx, yy, cc) {
49   captures = 0;
50 }
51
52 Move::Move(const Move& m) : MoveNC(m.x, m.y, m.color) {
53   if (m.captures) {
54     captures = new vector<p_cc>;
55     vector<p_cc>::iterator it;
56     for(it = m.captures->begin(); it != m.captures->end(); it++)
57       captures->push_back(*it);
58   }
59   else captures = 0;
60 }
61
62 Move::~Move() {
63   if (captures) delete captures;
64 }
65
66 Move& Move::operator=(const Move& m) {
67   if (this != &m) {
68     x = m.x;
69     y = m.y;
70     color = m.color;
71     if (captures) delete captures;
72     if (m.captures) {
73       captures = new vector<p_cc>;
74       vector<p_cc>::iterator it;
75       for(it = m.captures->begin(); it != m.captures->end(); it++)
76         captures->push_back(*it);
77     }
78     else captures = 0;
79   }
80   return *this;
81 }
82
83 abstractBoard::abstractBoard(int bs) throw(BoardError) {
84   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(int) 0\n");
85   boardsize = bs;
86   if (boardsize < 3) throw BoardError();
87   status = new char[boardsize*boardsize+1];
88   for (int i = 0; i < boardsize*boardsize; i++)
89       status[i] = ' ';
90   status[boardsize*boardsize] = 0;
91   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(int) 100\n");
92 }
93
94 abstractBoard::abstractBoard(const abstractBoard& ab) {
95   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(abstractBoard) 0\n");
96   boardsize = ab.boardsize;
97   status = new char[boardsize*boardsize+1];
98   for (int i = 0; i < boardsize*boardsize; i++)
99       status[i] = ab.status[i];
100   status[boardsize*boardsize] = 0;
101   undostack = stack<Move>(ab.undostack);
102   if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(abstractBoard) 100\n");
103 }
104
105 abstractBoard& abstractBoard::operator=(const abstractBoard& ab) {
106   if (DEBUG_ABSTRACTBOARD) printf("AB::operator= 0\n");
107   if (this != &ab) {
108     boardsize = ab.boardsize;
109     delete [] status;
110     status = new char[boardsize*boardsize+1];
111     for (int i = 0; i < boardsize*boardsize; i++)
112       status[i] = ab.status[i];
113     status[boardsize*boardsize] = 0;
114     undostack = stack<Move>(ab.undostack);
115     if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(abstractBoard) 100\n");
116   }
117   return *this;
118 }
119
120 abstractBoard::~abstractBoard() {
121   if (DEBUG_ABSTRACTBOARD) printf("AB::~abstractBoard 0\n");
122   delete [] status;
123   if (DEBUG_ABSTRACTBOARD) printf("AB::~abstractBoard 100\n");
124 }
125
126 // abstractBoard& abstractBoard::copy(const abstractBoard& ab) {
127 //   if (DEBUG_ABSTRACTBOARD) printf("AB::copy 0\n");
128 //   printf("copy assignment operator\n");
129 //   if (this != &ab) {
130 //     delete status;
131 //     boardsize = ab.boardsize;
132 //     status = new char[boardsize*boardsize+1];
133 //     for (int i = 0; i < boardsize*boardsize; i++)
134 //       status[i] = ab.status[i];
135 //     status[boardsize*boardsize] = 0;
136 //     undostack = ab.undostack;
137 //   }
138 //   if (DEBUG_ABSTRACTBOARD) printf("AB::copy 100\n");
139 //   return *this;
140 // }
141
142 char abstractBoard::getStatus(int x, int y) {
143   if (DEBUG_ABSTRACTBOARD) printf("AB::getStatus 0\n");
144   return status[boardsize*x + y];
145 }
146
147 void abstractBoard::setStatus(int x, int y, char val) {
148   if (DEBUG_ABSTRACTBOARD) printf("AB::setStatus 0\n");
149   if (val=='b' || val=='B') status[boardsize*x + y] = 'B';
150   else if (val=='w' || val=='W') status[boardsize*x + y] = 'W';
151   else status[boardsize*x + y] = val;
152   if (DEBUG_ABSTRACTBOARD) printf("AB::setStatus 100\n");
153 }
154
155 int abstractBoard::len_cap_last() throw(BoardError) {
156   if (DEBUG_ABSTRACTBOARD) printf("AB::len_cap_last 0\n");
157   if (!undostack.size()) throw BoardError();
158   Move m = undostack.top();
159   if (m.captures) return m.captures->size();
160   else return 0;
161 }
162
163 void abstractBoard::undostack_append_pass() {
164   if (DEBUG_ABSTRACTBOARD) printf("AB::undostack_append_pass 0\n");
165   undostack.push(Move(19,19,'-'));
166   if (DEBUG_ABSTRACTBOARD) printf("AB::undostack_append_pass 100\n");
167 }
168
169 int* abstractBoard::neighbors(int x, int y) {
170   int* result = new int[5];
171   char resultIndex = 1;
172   if (x-1 >= 0) result[resultIndex++]=(x-1) * boardsize + y;
173   if (x+1 < boardsize) result[resultIndex++]=(x+1) * boardsize + y;
174   if (y-1 >= 0) result[resultIndex++]=x * boardsize + y-1;
175   if (y+1 < boardsize) result[resultIndex++]=x*boardsize + y+1;
176   result[0] = resultIndex-1;
177   return result;
178 }
179
180 void abstractBoard::clear() {
181   for(int i=0; i<boardsize*boardsize; i++) status[i]=' ';
182   undostack = stack<Move>();
183 }
184
185 int abstractBoard::play(int x, int y, char* color) throw (BoardError) {
186   if (DEBUG_ABSTRACTBOARD) printf("AB::play(int,int,char*) 0\n");
187   if (x<0 || x>=boardsize || y<0 || y>=boardsize) return 0;
188   if (status[boardsize*x+y] != ' ') {
189     return 0;
190   }
191
192   vector<p_cc>* captures = legal(x, y, color[0]);
193   if (captures) {
194     vector<p_cc>::iterator it;
195     for(it=captures->begin(); it!=captures->end(); it++)
196       status[boardsize*it->first + it->second] = ' '; // remove captured stones, if any
197     Move m(x, y, color[0]);
198     if (captures->size()) m.captures = captures;
199     else delete captures;
200     undostack.push(m);
201     if (DEBUG_ABSTRACTBOARD) printf("AB::play(int,int,char*) ret1 100\n");
202     return 1;
203   }
204   if (DEBUG_ABSTRACTBOARD) printf("AB::play(int,int,char*) ret0 200\n");
205   return 0;
206 }
207
208 vector<p_cc>* abstractBoard::legal(int x, int y, char color) {
209   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 0\n");
210   vector<p_cc>* c = new vector<p_cc>;
211   int* nb = neighbors(x,y);
212   for(int i=1; i<=nb[0]; i++) {
213     int x1 = nb[i] / boardsize;
214     int y1 = nb[i] % boardsize;
215     if (status[boardsize*x1 + y1] == invert(color)) {
216       vector<p_cc>* d = hasNoLibExcP(x1, y1, x*boardsize+y);
217       if (DEBUG_ABSTRACTBOARD) printf("AB::legal 39\n");
218       if (DEBUG_ABSTRACTBOARD) printf("AB::legal 40, %d\n", d->size());
219       vector<p_cc>::iterator it;
220       for(it = d->begin(); it != d->end(); it++) c->push_back(*it);
221       if (DEBUG_ABSTRACTBOARD) printf("AB::legal 41\n");
222       delete d;
223     }
224   }
225   delete [] nb;
226   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 42\n");
227   setStatus(x,y,color);
228
229   if (c->size()) {
230     vector<p_cc>* captures = new vector<p_cc>();
231     while (c->size()) {
232       p_cc ctop = (*c)[0];
233       bool contained = false;
234       vector<p_cc>::iterator it;
235       for(it = captures->begin(); it != captures->end(); it++) {
236         if (ctop.first == it->first && ctop.second == it->second) {
237           contained = true;
238           break;
239         }
240       }
241       if (!contained) captures->push_back(ctop);
242       c->erase(c->begin());
243     }
244     delete c;
245     if (DEBUG_ABSTRACTBOARD) printf("AB::legal 98\n");
246     return captures;
247   }
248   delete c;
249   vector<p_cc>* d = hasNoLibExcP(x, y);
250   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 49\n");
251   if (DEBUG_ABSTRACTBOARD) printf("AB::legal 50, %d\n", d->size());
252   if (d->size()) {
253     delete d;
254     status[boardsize*x + y] = ' ';
255     if (DEBUG_ABSTRACTBOARD) printf("AB::legal 99\n");
256     return 0;
257   }
258   else {
259     delete d;
260     vector<p_cc>* ret = new vector<p_cc>();
261     if (DEBUG_ABSTRACTBOARD) printf("AB::legal 100\n");
262     return ret;
263   }
264 }
265
266 vector<p_cc>* abstractBoard::hasNoLibExcP(int x1, int y1, int exc) {
267   if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 0\n");
268   vector<p_cc>* st = new vector<p_cc>;
269   vector<p_cc>* newlyFound = new vector<p_cc>;
270   newlyFound->push_back(p_cc(x1, y1));
271   vector<p_cc>* n;
272   int foundNew = 1;
273
274   while (foundNew) {
275     foundNew = 0;
276     n = new vector<p_cc>;
277     vector<p_cc>::iterator it1;
278     for(it1=newlyFound->begin(); it1!=newlyFound->end(); it1++) {
279       int x = it1->first;
280       int y = it1->second;
281       int* nbs = neighbors(x,y);
282       if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 7 (%d,%d) %d\n",x, y,nbs[0]);
283       for (int j=1; j <= nbs[0]; j++) {
284         int yy1 = nbs[j];
285         if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 99\n");
286         if (status[yy1] == ' ' && yy1 != exc) {
287           delete [] nbs;
288           delete st;
289           delete newlyFound;
290           delete n;
291           return new vector<p_cc>;
292         }
293         else {
294           if (status[yy1]==status[x*boardsize+y]) {
295             p_cc yy(yy1/boardsize, yy1%boardsize);
296             int foundNewHere = 1;
297             vector<p_cc>::iterator it;
298             for(it=n->begin(); it!=n->end(); it++) {
299               if (it->first==yy.first && it->second==yy.second) {
300                 foundNewHere = 0;
301                 break;
302               }
303             }
304             if (foundNewHere) {
305               for(it = st->begin(); it!=st->end(); it++) {
306                 if (it->first==yy.first && it->second==yy.second) {
307                   foundNewHere = 0;
308                   break;
309                 }
310               }
311             }
312             if (foundNewHere) {
313               n->push_back(yy);
314               foundNew = 1;
315             }
316           }
317         }
318       }
319       delete [] nbs;
320     }
321
322     vector<p_cc>::iterator it;
323     for(it=newlyFound->begin(); it!=newlyFound->end(); it++) {
324       if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 10, (%d,%d)\n", it->first, it->second);
325       st->push_back(*it);
326     }
327     delete newlyFound;
328     newlyFound = n;
329   }
330   if (DEBUG_ABSTRACTBOARD) printf("AB::hasNoLibExcP 100\n");
331   delete n;
332   return st;
333 }
334
335 void abstractBoard::undo(int n) {
336   if (DEBUG_ABSTRACTBOARD) printf("AB::undo 0\n");
337   for(int i=0; i<n; i++) {
338     if (DEBUG_ABSTRACTBOARD) printf("AB::undo 1 %d\n", i);
339     if (undostack.size()) {
340       Move tuple = undostack.top();
341       undostack.pop();
342      
343       char color = tuple.color;
344       vector<p_cc>* captures = tuple.captures;
345       int x = tuple.x;
346       int y = tuple.y;
347
348       status[x*boardsize+y] = ' ';
349       if (captures) {
350   for(unsigned int i=0; i < captures->size(); i++) {
351     p_cc t = (*captures)[i];
352     setStatus(t.first, t.second, invert(color));
353   }
354       }
355     }
356   } 
357   if (DEBUG_ABSTRACTBOARD) printf("AB::undo 100\n");
358 }
359
360 void abstractBoard::remove(int x, int y) {
361   if (DEBUG_ABSTRACTBOARD) printf("AB::remove 0\n");
362   undostack.push(Move(-1, -1, invert(status[boardsize*x+y])));
363   status[boardsize*x+y] = ' ';
364   if (DEBUG_ABSTRACTBOARD) printf("AB::remove 100\n");
365 }
366
367 char abstractBoard::invert(char color) {
368   if (color == 'B' || color == 'b') return 'W';
369   if (color == 'W' || color == 'w') return 'B';
370   return ' ';
371 }
372
Note: See TracBrowser for help on using the browser.