Support for g++-4.1.
[gf1.git] / board2.cxx
blob7b90f773f29a5df663058aad721fd80a9f65479a
1 /*
2 ** board.c
3 ** $Id$
4 **
5 ** logging will only occur if the log-flag for a board is different from NULL
6 **
7 ** the original of this file was board.c
8 ** but because I had to add c++ code I had to rename it
9 */
11 ** Copyright (C) 1998 Kurt Van den Branden
13 ** This program is free software; you can redistribute it and/or modify
14 ** it under the terms of the GNU General Public License as published by
15 ** the Free Software Foundation; either version 2 of the License, or
16 ** (at your option) any later version.
17 **
18 ** This program is distributed in the hope that it will be useful,
19 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ** GNU General Public License for more details.
22 **
23 ** You should have received a copy of the GNU General Public License
24 ** along with this program; if not, write to the Free Software
25 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <stdlib.h>
28 #include <string.h>
29 #include "board.h"
31 #undef WINGIPF
32 #ifdef WINGIPF
33 extern void waitremrow (board * oldb, rem_row * row, board * newb);
34 extern void waitremgipf (board * oldb, position * gipf, board * newb);
36 extern void animatemove (board * oldb, listheader * pieces, board * newb);
38 typedef struct {
39 char piece;
40 position from;
41 position to;
42 } piecemove;
43 #endif
45 int _colsize[] = {0, 5, 6, 7, 8, 7, 6, 5, 0};
47 char _colchar[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'};
49 /* 42 different possible moves, without gipf-pieces */
50 fromto allmovesn[] = {
51 {"b1","b2",'n'}, {"a1","b2",'n'}, {"a2","b2",'n'},
52 {"a2","b3",'n'}, {"a3","b3",'n'},
53 {"a3","b4",'n'}, {"a4","b4",'n'},
54 {"a4","b5",'n'}, {"a5","b5",'n'}, {"b6","b5",'n'},
55 {"b6","c6",'n'}, {"c7","c6",'n'},
56 {"c7","d7",'n'}, {"d8","d7",'n'},
57 {"d8","e8",'n'}, {"e9","e8",'n'}, {"f8","e8",'n'},
58 {"f8","f7",'n'}, {"g7","f7",'n'},
59 {"g7","g6",'n'}, {"h6","g6",'n'},
60 {"h6","h5",'n'}, {"i5","h5",'n'}, {"i4","h5",'n'},
61 {"i4","h4",'n'}, {"i3","h4",'n'},
62 {"i3","h3",'n'}, {"i2","h3",'n'},
63 {"i2","h2",'n'}, {"i1","h2",'n'}, {"h1","h2",'n'},
64 {"h1","g2",'n'}, {"g1","g2",'n'},
65 {"g1","f2",'n'}, {"f1","f2",'n'},
66 {"f1","e2",'n'}, {"e1","e2",'n'}, {"d1","e2",'n'},
67 {"d1","d2",'n'}, {"c1","d2",'n'},
68 {"c1","c2",'n'}, {"b1","c2",'n'}
71 /* 84 different possible moves, with gipf-pieces */
72 fromto allmovesg[] = {
73 {"b1","b2",'g'}, {"a1","b2",'g'}, {"a2","b2",'g'},
74 {"a2","b3",'g'}, {"a3","b3",'g'},
75 {"a3","b4",'g'}, {"a4","b4",'g'},
76 {"a4","b5",'g'}, {"a5","b5",'g'}, {"b6","b5",'g'},
77 {"b6","c6",'g'}, {"c7","c6",'g'},
78 {"c7","d7",'g'}, {"d8","d7",'g'},
79 {"d8","e8",'g'}, {"e9","e8",'g'}, {"f8","e8",'g'},
80 {"f8","f7",'g'}, {"g7","f7",'g'},
81 {"g7","g6",'g'}, {"h6","g6",'g'},
82 {"h6","h5",'g'}, {"i5","h5",'g'}, {"i4","h5",'g'},
83 {"i4","h4",'g'}, {"i3","h4",'g'},
84 {"i3","h3",'g'}, {"i2","h3",'g'},
85 {"i2","h2",'g'}, {"i1","h2",'g'}, {"h1","h2",'g'},
86 {"h1","g2",'g'}, {"g1","g2",'g'},
87 {"g1","f2",'g'}, {"f1","f2",'g'},
88 {"f1","e2",'g'}, {"e1","e2",'g'}, {"d1","e2",'g'},
89 {"d1","d2",'g'}, {"c1","d2",'g'},
90 {"c1","c2",'g'}, {"b1","c2",'g'},
91 {"b1","b2",'n'}, {"a1","b2",'n'}, {"a2","b2",'n'},
92 {"a2","b3",'n'}, {"a3","b3",'n'},
93 {"a3","b4",'n'}, {"a4","b4",'n'},
94 {"a4","b5",'n'}, {"a5","b5",'n'}, {"b6","b5",'n'},
95 {"b6","c6",'n'}, {"c7","c6",'n'},
96 {"c7","d7",'n'}, {"d8","d7",'n'},
97 {"d8","e8",'n'}, {"e9","e8",'n'}, {"f8","e8",'n'},
98 {"f8","f7",'n'}, {"g7","f7",'n'},
99 {"g7","g6",'n'}, {"h6","g6",'n'},
100 {"h6","h5",'n'}, {"i5","h5",'n'}, {"i4","h5",'n'},
101 {"i4","h4",'n'}, {"i3","h4",'n'},
102 {"i3","h3",'n'}, {"i2","h3",'n'},
103 {"i2","h2",'n'}, {"i1","h2",'n'}, {"h1","h2",'n'},
104 {"h1","g2",'n'}, {"g1","g2",'n'},
105 {"g1","f2",'n'}, {"f1","f2",'n'},
106 {"f1","e2",'n'}, {"e1","e2",'n'}, {"d1","e2",'n'},
107 {"d1","d2",'n'}, {"c1","d2",'n'},
108 {"c1","c2",'n'}, {"b1","c2",'n'}
113 ** list of all the neighbours of a board-position
115 ** 3
116 ** 1 5
117 ** pos
118 ** 0 4
119 ** 2
121 unsigned char b_buren[9][9][6][2] = {
122 {{{0}}/* row a */},
123 {/* row b */
124 {{0}},
125 {{0}},
126 {{0, 0}, {0, 0}, {0, 0}, {1, 3}, {2, 2}, {2, 3}}, /* b2 */
127 {{0, 0}, {0, 0}, {1, 2}, {1, 4}, {2, 3}, {2, 4}}, /* b3 */
128 {{0, 0}, {0, 0}, {1, 3}, {1, 5}, {2, 4}, {2, 5}}, /* b4 */
129 {{0, 0}, {0, 0}, {1, 4}, {0, 0}, {2, 5}, {2, 6}} /* b5 */
131 {/* row c */
132 {{0}},
133 {{0}},
134 {{0, 0}, {1, 2}, {0, 0}, {2, 3}, {3, 2}, {3, 3}}, /* c2 */
135 {{1, 2}, {1, 3}, {2, 2}, {2, 4}, {3, 3}, {3, 4}}, /* c3 */
136 {{1, 3}, {1, 4}, {2, 3}, {2, 5}, {3, 4}, {3, 5}}, /* c4 */
137 {{1, 4}, {1, 5}, {2, 4}, {2, 6}, {3, 5}, {3, 6}}, /* c5 */
138 {{1, 5}, {0, 0}, {2, 5}, {0, 0}, {3, 6}, {3, 7}} /* c6 */
140 {/* row d */
141 {{0}},
142 {{0}},
143 {{0, 0}, {2, 2}, {0, 0}, {3, 3}, {4, 2}, {4, 3}}, /* d2 */
144 {{2, 2}, {2, 3}, {3, 2}, {3, 4}, {4, 3}, {4, 4}}, /* d3 */
145 {{2, 3}, {2, 4}, {3, 3}, {3, 5}, {4, 4}, {4, 5}}, /* d4 */
146 {{2, 4}, {2, 5}, {3, 4}, {3, 6}, {4, 5}, {4, 6}}, /* d5 */
147 {{2, 5}, {2, 6}, {3, 5}, {3, 7}, {4, 6}, {4, 7}}, /* d6 */
148 {{2, 6}, {0, 0}, {3, 6}, {0, 0}, {4, 7}, {4, 8}} /* d7 */
150 {/* row e */
151 {{0}},
152 {{0}},
153 {{0, 0}, {3, 2}, {0, 0}, {4, 3}, {0, 0}, {5, 2}}, /* e2 */
154 {{3, 2}, {3, 3}, {4, 2}, {4, 4}, {5, 2}, {5, 3}}, /* e3 */
155 {{3, 3}, {3, 4}, {4, 3}, {4, 5}, {5, 3}, {5, 4}}, /* e4 */
156 {{3, 4}, {3, 5}, {4, 4}, {4, 6}, {5, 4}, {5, 5}}, /* e5 */
157 {{3, 5}, {3, 6}, {4, 5}, {4, 7}, {5, 5}, {5, 6}}, /* e6 */
158 {{3, 6}, {3, 7}, {4, 6}, {4, 8}, {5, 6}, {5, 7}}, /* e7 */
159 {{3, 7}, {0, 0}, {4, 7}, {0, 0}, {5, 7}, {0, 0}} /* e8 */
161 {/* row f */
162 {{0}},
163 {{0}},
164 {{4, 2}, {4, 3}, {0, 0}, {5, 3}, {0, 0}, {6, 2}}, /* f2 */
165 {{4, 3}, {4, 4}, {5, 2}, {5, 4}, {6, 2}, {6, 3}}, /* f3 */
166 {{4, 4}, {4, 5}, {5, 3}, {5, 5}, {6, 3}, {6, 4}}, /* f4 */
167 {{4, 5}, {4, 6}, {5, 4}, {5, 6}, {6, 4}, {6, 5}}, /* f5 */
168 {{4, 6}, {4, 7}, {5, 5}, {5, 7}, {6, 5}, {6, 6}}, /* f6 */
169 {{4, 7}, {4, 8}, {5, 6}, {0, 0}, {6, 6}, {0, 0}} /* f7 */
171 {/* row g */
172 {{0}},
173 {{0}},
174 {{5, 2}, {5, 3}, {0, 0}, {6, 3}, {0, 0}, {7, 2}}, /* g2 */
175 {{5, 3}, {5, 4}, {6, 2}, {6, 4}, {7, 2}, {7, 3}}, /* g3 */
176 {{5, 4}, {5, 5}, {6, 3}, {6, 5}, {7, 3}, {7, 4}}, /* g4 */
177 {{5, 5}, {5, 6}, {6, 4}, {6, 6}, {7, 4}, {7, 5}}, /* g5 */
178 {{5, 6}, {5, 7}, {6, 5}, {0, 0}, {7, 5}, {0, 0}} /* g6 */
180 {/* row h */
181 {{0}},
182 {{0}},
183 {{6, 2}, {6, 3}, {0, 0}, {7, 3}, {0, 0}, {0, 0}}, /* h2 */
184 {{6, 3}, {6, 4}, {7, 2}, {7, 4}, {0, 0}, {0, 0}}, /* h3 */
185 {{6, 4}, {6, 5}, {7, 3}, {7, 5}, {0, 0}, {0, 0}}, /* h4 */
186 {{6, 5}, {6, 6}, {7, 4}, {0, 0}, {0, 0}, {0, 0}} /* h5 */
188 {{{0}}/* row i */}
193 ** each item of the list contains:
194 ** - middle point for the row
195 ** - first direction for this row (second direction = 5 - first direction)
196 ** - second direction
197 ** - minimum nr of pieces necessary in the first direction
199 int rowlist[][5] = {
200 {2, 2, 1, 4, 2},
201 {3, 3, 1, 4, 2},
202 {4, 4, 1, 4, 2},
203 {4, 5, 1, 4, 1},
204 {5, 5, 1, 4, 2},
205 {5, 6, 1, 4, 2},
206 {5, 7, 1, 4, 2},
207 {1, 3, 2, 3, 2},
208 {2, 4, 2, 3, 2},
209 {3, 5, 2, 3, 2},
210 {4, 5, 2, 3, 1},
211 {5, 5, 2, 3, 2},
212 {6, 4, 2, 3, 2},
213 {7, 3, 2, 3, 2},
214 {5, 2, 0, 5, 2},
215 {5, 3, 0, 5, 2},
216 {5, 4, 0, 5, 2},
217 {4, 5, 0, 5, 1},
218 {4, 6, 0, 5, 2},
219 {3, 6, 0, 5, 2},
220 {2, 6, 0, 5, 2}
225 board * b_new (int board_type)
227 board * board_ref;
228 int i, j;
230 board_ref = b_newboard();
231 for (i = 0; i < 8; i++)
232 for (j = 0; j < 9; j++)
233 board_ref->pieces[i][j] = '.';
235 board_ref->status = S_NORMAL;
236 board_ref->nextpiece = 'o';
237 board_ref->gipfextra = NULL;
238 board_ref->rowextraw = NULL;
239 board_ref->rowextrab = NULL;
240 board_ref->white = 18;
241 board_ref->lostwhite = 0;
242 board_ref->gipfwhite = 0;
243 board_ref->typewhite = 'n';
244 board_ref->black = 18;
245 board_ref->lostblack = 0;
246 board_ref->gipfblack = 0;
247 board_ref->typeblack = 'n';
248 board_ref->winner = '.';
249 board_ref->checkfour = 'n';
250 board_ref->log = NULL;
251 board_ref->movecounter = 0;
252 #ifdef WINGIPF
253 board_ref->removewait = 0;
254 board_ref->animate = 0;
255 #endif
257 if (board_type == T_BASIC)
259 board_ref->white = 12;
260 board_ref->black = 12;
261 board_ref->pieces[1][5] = 'o';
262 board_ref->pieces[7][5] = 'o';
263 board_ref->pieces[4][2] = 'o';
264 board_ref->pieces[1][2] = 'x';
265 board_ref->pieces[4][8] = 'x';
266 board_ref->pieces[7][2] = 'x';
267 board_ref->gipfwhite = -1;
268 board_ref->gipfblack = -1;
270 else if (board_type == T_STANDARD)
272 board_ref->white = 12;
273 board_ref->black = 12;
274 board_ref->pieces[1][5] = 'O';
275 board_ref->pieces[7][5] = 'O';
276 board_ref->pieces[4][2] = 'O';
277 board_ref->pieces[1][2] = 'X';
278 board_ref->pieces[4][8] = 'X';
279 board_ref->pieces[7][2] = 'X';
280 board_ref->gipfwhite = 3;
281 board_ref->gipfblack = 3;
283 else
284 { /* tournament */
285 board_ref->typewhite = 'g';
286 board_ref->typeblack = 'g';
289 return (board_ref);
292 board * b_copy (board * orig_board)
294 board * new_board;
295 int i, j;
297 if (orig_board == NULL)
298 return (NULL);
300 new_board = b_newboard();
302 #define MEMCPY 1
303 #ifndef MEMCPY
304 for (i = 1; i < 8; i++)
305 for (j = 2; j <= b_colsize (i); j++)
306 new_board->pieces[i][j] = orig_board->pieces[i][j];
308 new_board->status = orig_board->status;
309 new_board->nextpiece = orig_board->nextpiece;
310 new_board->winner = orig_board->winner;
311 new_board->checkfour = orig_board->checkfour;
312 new_board->log = orig_board->log;
313 new_board->movecounter = orig_board->movecounter;
315 new_board->white = orig_board->white;
316 new_board->typewhite = orig_board->typewhite;
317 new_board->lostwhite = orig_board->lostwhite;
318 new_board->gipfwhite = orig_board->gipfwhite;
319 new_board->black = orig_board->black;
320 new_board->typeblack = orig_board->typeblack;
321 new_board->lostblack = orig_board->lostblack;
322 new_board->gipfblack = orig_board->gipfblack;
323 #else
324 memcpy (new_board, orig_board, sizeof (board));
325 #endif
327 if (orig_board->gipfextra != NULL)
329 new_board->gipfextra = copy_rem_gipf_row (orig_board->gipfextra);
331 if (orig_board->rowextraw != NULL)
333 new_board->rowextraw = copy_rem_row_row (orig_board->rowextraw);
335 if (orig_board->rowextrab != NULL)
337 new_board->rowextrab = copy_rem_row_row (orig_board->rowextrab);
339 return (new_board);
343 void b_print (board * boardp)
345 #ifndef WINGIPF
346 if (boardp == NULL)
348 printf ("\nERROR: the boardp-pointer is NULL (b_print)\n\n");
349 return;
352 printf ("A B C D E F G H I\n");
353 printf ("5 6 7 8 9 8 7 6 5\n\n");
354 printf (" *\n");
355 printf (" * *\n");
356 printf (" * %c *\n", boardp->pieces[4][8]);
357 printf (" * %c %c *\n",
358 boardp->pieces[3][7], boardp->pieces[5][7]);
359 printf ("* %c %c %c *\n",
360 boardp->pieces[2][6], boardp->pieces[4][7], boardp->pieces[6][6]);
361 printf (" %c %c %c %c\n",
362 boardp->pieces[1][5], boardp->pieces[3][6],
363 boardp->pieces[5][6], boardp->pieces[7][5]);
364 printf ("* %c %c %c *\n",
365 boardp->pieces[2][5], boardp->pieces[4][6], boardp->pieces[6][5]);
366 printf (" %c %c %c %c\n",
367 boardp->pieces[1][4], boardp->pieces[3][5],
368 boardp->pieces[5][5], boardp->pieces[7][4]);
369 printf ("* %c %c %c *\n",
370 boardp->pieces[2][4], boardp->pieces[4][5], boardp->pieces[6][4]);
371 printf (" %c %c %c %c\n",
372 boardp->pieces[1][3], boardp->pieces[3][4],
373 boardp->pieces[5][4], boardp->pieces[7][3]);
374 printf ("* %c %c %c *\n",
375 boardp->pieces[2][3], boardp->pieces[4][4], boardp->pieces[6][3]);
376 printf (" %c %c %c %c\n",
377 boardp->pieces[1][2], boardp->pieces[3][3],
378 boardp->pieces[5][3], boardp->pieces[7][2]);
379 printf ("* %c %c %c *\n",
380 boardp->pieces[2][2], boardp->pieces[4][3], boardp->pieces[6][2]);
381 printf (" * %c %c *\n",
382 boardp->pieces[3][2], boardp->pieces[5][2]);
383 printf (" * %c *\n", boardp->pieces[4][2]);
384 printf (" * *\n");
385 printf (" * white: %d\n",
386 boardp->white);
387 printf (" lostwhite: %d\n",
388 boardp->lostwhite);
389 printf ("1 1 1 1 1 1 1 1 1 black: %d\n",
390 boardp->black);
391 printf ("A B C D E F G H I lostblack: %d\n",
392 boardp->lostblack);
393 #endif
394 return;
398 void b_del (board * dboard)
400 if (dboard != NULL)
402 if (dboard->gipfextra != NULL)
404 emptyll (dboard->gipfextra, del_rem_gipf);
405 free (dboard->gipfextra);
407 if (dboard->rowextraw != NULL)
409 emptyll (dboard->rowextraw, del_rem_row);
410 free (dboard->rowextraw);
412 if (dboard->rowextrab != NULL)
414 emptyll (dboard->rowextrab, del_rem_row);
415 free (dboard->rowextrab);
417 free (dboard);
420 return;
425 ** b_move : move a piece on a gipf-board
427 ** parameters:
428 ** oboard : pointer to original board
429 ** from : string with from-position
430 ** to : string with to-position
431 ** npiece: piece to add to the board (o, O, x, X)
433 ** returns:
434 ** pointer to a new board
435 ** NULL
437 board * b_move (board * oboard, char * from, char * to, char npiece)
439 position * from_p,
440 * to_p,
441 * next_p;
442 int row_dif,
443 col_dif;
444 board * nboard,
445 * new_board;
446 char save_piece,
447 piece,
448 tempstr[80],
449 * lastmoved = NULL;
450 #ifdef WINGIPF
451 listheader * pmoves;
452 piecemove * piecem;
453 #endif
455 /* check if oboard is in the correct state */
456 if (oboard->status == S_REMOVEROW)
457 { /* wrong status */
458 return (NULL);
460 if ((npiece != oboard->nextpiece) &&
461 (b_otherpiece (npiece) != oboard->nextpiece))
462 { /* wrong player */
463 return (NULL);
466 /* check if the player has pieces left */
467 if ((npiece == 'o') || (npiece == 'O'))
469 if (oboard->white <= 0)
471 return (NULL);
474 else if (oboard->black <= 0)
476 return (NULL);
479 /* if the player wants to place a gipf, check if this is allowed */
480 if ((npiece == 'O') && (oboard->typewhite != 'g'))
482 return (NULL);
484 else if ((npiece == 'X') && (oboard->typeblack != 'g'))
486 return (NULL);
489 /* move the piece */
490 from_p = strtopos (from);
491 to_p = strtopos (to);
492 if ((from_p == NULL) || (to_p == NULL))
493 { /* invalid from or to position */
494 del_position (from_p);
495 del_position (to_p);
496 return (NULL);
498 next_p = (position *) copy_position ((void *) to_p);
499 row_dif = to_p->row - from_p->row;
500 col_dif = to_p->col - from_p->col;
502 /* valid to-position ? */
503 if (((to_p->col < 1) || (to_p->col > 7)) ||
504 ((to_p->col != 1) && (to_p->col != 7) &&
505 (to_p->row != 2) && (to_p->row != b_colsize (to_p->col))) ||
506 (((to_p->col == 1) | (to_p->col == 7)) &&
507 ((to_p->row <2) || (to_p->row >5))))
509 #ifndef WINGIPF
510 printf ("invalid move (to): (%s, %s)\n", from, to);
511 #endif
512 del_position (from_p);
513 del_position (to_p);
514 del_position (next_p);
515 return (NULL);
518 /* valid from-position ? */
519 if ((abs (row_dif) > 1) ||
520 (abs (col_dif) > 1) ||
521 (((from_p->col == 0) || (from_p->col == 8)) && (row_dif < 0)) ||
522 (( from_p->row == 1) && (((from_p->col < 5) && (col_dif < 0)) ||
523 ((from_p->col > 3) && (col_dif > 0)))) ||
524 ((from_p->col > 0) && (from_p->col < 8) &&
525 (from_p->row != 1) && (from_p->row != b_colsize (from_p->col) + 1)))
527 #ifndef WINGIPF
528 printf ("invalid move (from): (%s, %s)\n", from, to);
529 #endif
530 del_position (from_p);
531 del_position (to_p);
532 del_position (next_p);
533 return (NULL);
536 nboard = b_copy (oboard);
537 if (nboard->gipfextra != NULL)
539 emptyll (nboard->gipfextra, del_rem_gipf);
540 free (nboard->gipfextra);
541 nboard->gipfextra = NULL;
544 nboard->status = S_NORMAL;
545 if (oboard->nextpiece == 'o')
547 nboard->movecounter++;
550 #ifdef WINGIPF
551 pmoves = (listheader *) malloc (sizeof (listheader));
552 newlist (pmoves);
554 piecem = (piecemove *) malloc (sizeof (piecemove));
555 piecem->piece = npiece;
556 piecem->from.col = from_p->col;
557 piecem->from.row = from_p->row;
558 piecem->to.col = to_p->col;
559 piecem->to.row = to_p->row;
560 pushll (pmoves, (void *) piecem);
561 #endif
563 save_piece = nboard->pieces[to_p->col][to_p->row];
564 nboard->pieces[to_p->col][to_p->row] = npiece;
565 while (save_piece != '.')
567 #ifdef WINGIPF
568 piecem = (piecemove *) malloc (sizeof (piecemove));
569 piecem->piece = save_piece;
570 piecem->from.col = next_p->col;
571 piecem->from.row = next_p->row;
572 #endif
573 if (col_dif != 0)
574 { /* going diagonally */
575 if (next_p->col == 4)
576 { /* going over the middle line */
577 row_dif--;
579 next_p->col += col_dif;
581 next_p->row += row_dif;
582 if ((next_p->col == 0) ||
583 (next_p->col == 8) ||
584 (next_p->row < 2) ||
585 (next_p->row > b_colsize (next_p->col)))
586 { /* the row is full, no pieces can be added */
587 del_position (from_p);
588 del_position (next_p);
589 del_position (to_p);
590 b_del (nboard);
591 #ifdef WINGIPF
592 free (piecem);
593 while ((piecem = (piecemove *) llrembynr (pmoves, 1)) != NULL)
595 free (piecem);
597 free (pmoves);
598 #endif
599 return (NULL);
601 #ifdef WINGIPF
602 piecem->to.col = next_p->col;
603 piecem->to.row = next_p->row;
604 pushll (pmoves, (void *) piecem);
605 #endif
606 piece = save_piece;
607 save_piece = nboard->pieces[next_p->col][next_p->row];
608 nboard->pieces[next_p->col][next_p->row] = piece;
610 lastmoved = postostr (next_p); /* just for logging-purposes */
612 if (npiece == 'o')
614 nboard->white -= 1;
615 nboard->typewhite = 'n';
617 else if (npiece == 'O')
619 nboard->white -= 2;
620 nboard->gipfwhite++;
622 else if (npiece == 'x')
624 nboard->black -= 1;
625 nboard->typeblack = 'n';
627 else
629 nboard->black -= 2;
630 nboard->gipfblack++;
632 nboard->nextpiece = b_opponent (nboard->nextpiece);
634 if (nboard->log)
636 sprintf (tempstr, "%c:%2s:%2s", npiece, from, lastmoved);
637 addtolog (nboard->log, LOGMOVE, tempstr);
639 free (lastmoved);
641 #ifdef WINGIPF
642 /* animate move */
643 if (nboard->animate)
645 animatemove (oboard, pmoves, nboard);
648 while ((piecem = (piecemove *) llrembynr (pmoves, 1)) != NULL)
650 free (piecem);
652 free (pmoves);
653 #endif
655 /* check for 4 in a row */
656 nboard->checkfour = 'y';
657 new_board = b_checkfour (nboard);
659 /* cleanup memory */
660 del_position (from_p);
661 del_position (next_p);
662 del_position (to_p);
663 b_del (nboard);
665 return (new_board);
670 ** b_remove_row: remove a row from the playing field, adapt the different
671 ** counters
673 ** parameters:
674 ** oboard : pointer to gipf-board
675 ** rownr : nr of the row to be removed from gipfextra
677 ** returns:
678 ** pointer to a new gipf-board
679 ** NULL
681 board * b_remove_row (board * oboard, int rownr)
683 rem_row * row_ptr,
684 * n_row;
685 board * nboard,
686 * new_board;
687 listheader * glist,
688 * plist,
689 * rowextra_o,
690 * rowextra_n;
691 int nrg = 0,
692 counter,
693 str_offset;
694 position * coor;
695 char winpiece,
696 piece,
697 colour,
698 tempstr[80],
699 * strpos,
700 * start,
701 * end;
702 rem_gipf * gipf_ptr;
704 if ((oboard->rowextraw != NULL) &&
705 ((oboard->nextpiece == 'x') || (oboard->rowextrab == NULL)))
707 colour = 'o';
708 rowextra_o = oboard->rowextraw;
710 else if (oboard->rowextrab != NULL)
712 colour = 'x';
713 rowextra_o = oboard->rowextrab;
715 else
717 return (NULL);
720 row_ptr = (rem_row *) llitembynr (rowextra_o, rownr);
721 /* this shouldn't happen */
722 if (row_ptr == NULL)
724 return (NULL);
727 glist = (listheader *) malloc (sizeof (listheader));
728 newlist (glist);
729 nboard = b_copy (oboard);
730 if (nboard->gipfextra != NULL)
732 emptyll (nboard->gipfextra, del_rem_gipf);
733 free (nboard->gipfextra);
734 nboard->gipfextra = NULL;
737 nboard->status = S_NORMAL;
738 plist = row_ptr->piecelist;
739 winpiece = row_owner (row_ptr);
741 if (nboard->log)
743 start = postostr (row_start (row_ptr));
744 end = postostr (row_end (row_ptr));
745 sprintf (tempstr, "%c:%s:%s:", winpiece, start, end);
746 free (start);
747 free (end);
748 str_offset = 8;
751 counter = 1;
752 while ((coor = (position *) llitembynr (plist, counter)) != NULL)
754 counter++;
756 piece = nboard->pieces[coor->col][coor->row];
757 if ((piece == 'O') || (piece == 'X'))
759 nrg++;
760 gipf_ptr = new_rem_gipf ();
761 gipf_ptr->pos = (position *) copy_position ((void *) coor);
762 gipf_ptr->owner = winpiece;
763 pushll (glist, (void *) gipf_ptr);
764 continue;
767 if (nboard->log)
769 strpos = postostr (coor);
770 sprintf (tempstr + str_offset, "%2s%c:", strpos, piece);
771 free (strpos);
772 str_offset += 4;
775 if (piece == 'o')
777 if (piece == winpiece)
779 nboard->white++;
781 else
783 nboard->lostwhite++;
786 else
788 if (piece == winpiece)
790 nboard->black++;
792 else
794 nboard->lostblack++;
798 nboard->pieces[coor->col][coor->row] = '.';
801 if (nboard->log)
803 addtolog (nboard->log, LOGREMROW, tempstr);
806 #ifdef WINGIPF
807 if (nboard->removewait)
809 waitremrow (oboard, row_ptr, nboard);
811 #endif
814 ** remove the row that was just removed from rowextra
815 ** and check if the other rows are still complete
817 /* check white rowlist */
818 if (nboard->rowextraw != NULL)
820 /* check if all rows are still valid */
821 emptyll (nboard->rowextraw, del_rem_row);/* I now have an empty list */
823 counter = 1;
824 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextraw, counter))
825 != NULL)
827 counter++;
828 if ((colour == 'o') && ((counter - 1) == rownr))
830 continue;
832 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
834 pushll (nboard->rowextraw, n_row);
838 if (llitembynr (nboard->rowextraw, 1) == NULL)
840 free (nboard->rowextraw);
841 nboard->rowextraw = NULL;
845 /* check black rowlist */
846 if (nboard->rowextrab != NULL)
848 /* check if all rows are still valid */
850 emptyll (nboard->rowextrab, del_rem_row);/* I now have an empty list */
852 counter = 1;
853 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextrab, counter))
854 != NULL)
856 counter++;
857 if ((colour == 'x') && ((counter - 1) == rownr))
859 continue;
861 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
863 pushll (nboard->rowextrab, n_row);
867 if (llitembynr (nboard->rowextrab, 1) == NULL)
869 free (nboard->rowextrab);
870 nboard->rowextrab = NULL;
874 if ((nboard->rowextraw == NULL) && (nboard->rowextrab == NULL))
876 nboard->checkfour = 'n';
879 if (nrg != 0)
881 nboard->gipfextra = glist;
882 nboard->status = S_REMOVEGIPF;
883 return (nboard);
885 else if (nboard->checkfour == 'y')
887 free (glist);
888 new_board = b_checkfour (nboard);
889 b_del (nboard);
890 return (new_board);
892 else
894 free (glist);
895 return (nboard);
901 ** remove a gipf from the board and add the retrieved pieces to the
902 ** correct counter
904 ** parameters:
905 ** oboard: pointer to gipf-board
907 ** returns:
908 ** pointer to new board
909 ** NULL
911 board * b_remove_gipf (board * oboard, rem_gipf * rgipf)
913 board * nboard;
914 char piece,
915 winpiece,
916 tempstr[80],
917 * strpos;
918 rem_row * row_ptr,
919 * n_row;
920 int counter;
922 piece = oboard->pieces[rgipf->pos->col][rgipf->pos->row];
923 winpiece = b_otherpiece (rgipf->owner);
925 if ((piece != 'O') && (piece != 'X'))
927 return (NULL);
930 nboard = b_copy (oboard);
932 if (nboard->gipfextra != NULL)
934 emptyll (nboard->gipfextra, del_rem_gipf);
935 free (nboard->gipfextra);
936 nboard->gipfextra = NULL;
939 nboard->status = S_NORMAL;
941 nboard->pieces[rgipf->pos->col][rgipf->pos->row] = '.';
943 if (nboard->log)
945 strpos = postostr (rgipf->pos);
946 sprintf (tempstr, "%c:%2s%c", rgipf->owner, strpos, piece);
947 free (strpos);
948 addtolog (nboard->log, LOGREMGIPF, tempstr);
951 if (piece == 'O')
953 nboard->gipfwhite--;
954 if (piece == winpiece)
956 nboard->white += 2;
958 else
960 nboard->lostwhite += 2;
963 else
965 nboard->gipfblack--;
966 if (piece == winpiece)
968 nboard->black += 2;
970 else
972 nboard->lostblack += 2;
976 /* check white rowlist */
977 if (nboard->rowextraw != NULL)
979 /* check if all rows are still valid */
980 emptyll (nboard->rowextraw, del_rem_row);/* I now have an empty list */
982 counter = 1;
983 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextraw, counter))
984 != NULL)
986 counter++;
987 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
989 pushll (nboard->rowextraw, n_row);
993 if (llitembynr (nboard->rowextraw, 1) == NULL)
995 free (nboard->rowextraw);
996 nboard->rowextraw = NULL;
1000 /* check black rowlist */
1001 if (nboard->rowextrab != NULL)
1003 /* check if all rows are still valid */
1005 emptyll (nboard->rowextrab, del_rem_row);/* I now have an empty list */
1007 counter = 1;
1008 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextrab, counter))
1009 != NULL)
1011 counter++;
1012 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
1014 pushll (nboard->rowextrab, n_row);
1018 if (llitembynr (nboard->rowextrab, 1) == NULL)
1020 free (nboard->rowextrab);
1021 nboard->rowextrab = NULL;
1025 if ((nboard->rowextraw == NULL) && (nboard->rowextrab == NULL))
1027 nboard->checkfour = 'n';
1030 #ifdef WINGIPF
1031 if (nboard->removewait)
1033 waitremgipf (oboard, rgipf->pos, nboard);
1035 #endif
1037 return (nboard);
1042 ** b_checkfour: check for 4 in a row
1044 ** parameters:
1045 ** oboard: pointer to gipf-board
1047 ** returns:
1048 ** pointer to a new gipf-board
1050 board * b_checkfour (board * oboard)
1052 board * nboard,
1053 * new_board;
1054 int inrow4_w = 0,
1055 inrow4_b = 0,
1056 rownr,
1057 countrow,
1058 save_col,
1059 dir;
1060 listheader * row4list_w = NULL,
1061 * row4list_b = NULL;
1062 position base,
1063 next;
1064 char base_piece,
1065 base_piece2,
1066 piece;
1067 rem_row * rowp;
1069 if (oboard->checkfour == 'n')
1071 nboard = b_copy (oboard);
1072 nboard->status = S_NORMAL;
1073 return (nboard);
1075 if ((oboard->rowextraw != NULL) &&
1076 ((oboard->nextpiece == 'x') || (oboard->rowextrab == NULL)))
1078 if (llitembynr (oboard->rowextraw, 2) == NULL)
1080 nboard = b_remove_row (oboard, 1);
1081 return (nboard);
1083 else
1085 nboard = b_copy (oboard);
1086 nboard->status = S_REMOVEROW;
1087 return (nboard);
1090 else if (oboard->rowextrab != NULL)
1092 if (llitembynr (oboard->rowextrab, 2) == NULL)
1094 nboard = b_remove_row (oboard, 1);
1095 return (nboard);
1097 else
1099 nboard = b_copy (oboard);
1100 nboard->status = S_REMOVEROW;
1101 return (nboard);
1105 /* base = new_position ();
1106 next = new_position ();*/
1108 for (rownr=0; rownr<21; rownr++)
1110 base.col = rowlist[rownr][0];
1111 base.row = rowlist[rownr][1];
1113 if (oboard->pieces[base.col][base.row] == '.')
1115 continue;
1118 countrow = 1;
1120 base_piece = oboard->pieces[base.col][base.row];
1121 base_piece2 = b_otherpiece (base_piece);
1123 /* first direction */
1124 dir = rowlist[rownr][2];
1126 /* next.col = base.col;
1127 next.row = base.row;
1129 save_col = next.col;
1130 next.col = b_buren[save_col][next.row][dir][0];
1131 next.row = b_buren[save_col][next.row][dir][1];*/
1132 next.col = b_buren[base.col][base.row][dir][0];
1133 next.row = b_buren[base.col][base.row][dir][1];
1135 piece = oboard->pieces[next.col][next.row];
1136 while ((next.col != 0) && (piece != '.'))
1138 if ((piece == base_piece) || (piece == base_piece2))
1140 countrow++;
1142 else
1144 break;
1146 save_col = next.col;
1147 next.col = b_buren[save_col][next.row][dir][0];
1148 next.row = b_buren[save_col][next.row][dir][1];
1150 piece = oboard->pieces[next.col][next.row];
1153 if (countrow < rowlist[rownr][4])
1154 { /* not possible to get 4 in a row anymore */
1155 continue;
1158 /* second direction */
1159 /*dir = rowlist[rownr][3];*/
1160 dir = 5 - dir;
1162 /* next.col = base.col;
1163 next.row = base.row;
1165 save_col = next.col;
1166 next.col = b_buren[save_col][next.row][dir][0];
1167 next.row = b_buren[save_col][next.row][dir][1];*/
1168 next.col = b_buren[base.col][base.row][dir][0];
1169 next.row = b_buren[base.col][base.row][dir][1];
1171 piece = oboard->pieces[next.col][next.row];
1172 while ((next.col != 0) && (piece != '.'))
1174 if ((piece == base_piece) || (piece == base_piece2))
1176 countrow++;
1178 else
1180 break;
1182 save_col = next.col;
1183 next.col = b_buren[save_col][next.row][dir][0];
1184 next.row = b_buren[save_col][next.row][dir][1];
1186 piece = oboard->pieces[next.col][next.row];
1189 if (countrow > 3)
1191 rowp = b_rowoffour (oboard, rownr);
1193 if ((base_piece == 'o') || (base_piece == 'O'))
1195 inrow4_w++;
1196 if (row4list_w == NULL)
1198 row4list_w = (listheader *) malloc (sizeof (listheader));
1199 newlist (row4list_w);
1201 pushll (row4list_w, rowp);
1203 else
1205 inrow4_b++;
1206 if (row4list_b == NULL)
1208 row4list_b = (listheader *) malloc (sizeof (listheader));
1209 newlist (row4list_b);
1211 pushll (row4list_b, rowp);
1216 /* del_position (base);
1217 del_position (next);*/
1219 nboard = b_copy (oboard);
1221 if (inrow4_w != 0)
1223 nboard->rowextraw = row4list_w;
1225 if (inrow4_b != 0)
1227 nboard->rowextrab = row4list_b;
1230 if ((inrow4_w == 0) && (inrow4_b == 0))
1232 nboard->status = S_NORMAL;
1233 nboard->checkfour = 'n';
1234 return (nboard);
1236 if ((nboard->rowextraw != NULL) &&
1237 ((nboard->nextpiece == 'x') || (nboard->rowextrab == NULL)))
1239 if (inrow4_w == 1)
1241 new_board = b_remove_row (nboard, 1);
1242 b_del (nboard);
1243 return (new_board);
1245 else
1247 nboard->status = S_REMOVEROW;
1248 return (nboard);
1251 else
1253 if (inrow4_b == 1)
1255 new_board = b_remove_row (nboard, 1);
1256 b_del (nboard);
1257 return (new_board);
1259 else
1261 nboard->status = S_REMOVEROW;
1262 return (nboard);
1269 ** b_rowoffour: check if a certain row has four in a row
1271 ** parameters:
1272 ** oboard: pointer to gipf-board
1273 ** rownr: nr of row in rowlist
1275 ** returns:
1276 ** pointer to rem_row-structure
1277 ** NULL (if no 4 in a row found)
1279 rem_row * b_rowoffour (board * oboard, int rownr)
1281 int countrow,
1282 dir,
1283 save_col,
1284 count;
1285 listheader * temprow;
1286 position * start,
1287 * end,
1288 * base,
1289 * next;
1290 char base_piece,
1291 base_piece2,
1292 piece;
1293 rem_row * rowp;
1295 temprow = (listheader *) malloc (sizeof (listheader));
1296 newlist (temprow);
1297 countrow = 1;
1299 base = new_position();
1300 base->col = rowlist[rownr][0];
1301 base->row = rowlist[rownr][1];
1302 start = (position *) copy_position ((void *) base);
1303 end = (position *) copy_position ((void *) base);
1304 next = (position *) copy_position ((void *) base);
1306 if (oboard->pieces[base->col][base->row] == '.')
1308 /* cleanup */
1309 free (temprow);
1310 del_position ((void *) base);
1311 del_position ((void *) start);
1312 del_position ((void *) end);
1313 del_position ((void *) next);
1314 return (NULL);
1317 base_piece = oboard->pieces[base->col][base->row];
1318 base_piece2 = b_otherpiece (base_piece);
1319 pushll (temprow, copy_position ((void *) base));
1321 /* first direction */
1322 dir = rowlist[rownr][2];
1324 count = 1;
1325 /* b_moveto (next, col_dif, &row_dif);*/
1326 save_col = next->col;
1327 next->col = b_buren[save_col][next->row][dir][0];
1328 next->row = b_buren[save_col][next->row][dir][1];
1330 piece = oboard->pieces[next->col][next->row];
1331 while ((next->col != 0) && (piece != '.'))
1333 pushll (temprow, copy_position ((void *) next));
1334 if ((count == 1) &&
1335 ((piece == base_piece) || (piece == base_piece2)))
1337 countrow++;
1338 start->col = next->col;
1339 start->row = next->row;
1341 else
1343 count = 0;
1345 /* b_moveto (next, col_dif, &row_dif);*/
1346 save_col = next->col;
1347 next->col = b_buren[save_col][next->row][dir][0];
1348 next->row = b_buren[save_col][next->row][dir][1];
1350 piece = oboard->pieces[next->col][next->row];
1353 /* second direction */
1354 /*dir = rowlist[rownr][3];*/
1355 dir = 5 - dir;
1357 next->col = base->col;
1358 next->row = base->row;
1360 count = 1;
1361 /* b_moveto (next, col_dif, &row_dif);*/
1362 save_col = next->col;
1363 next->col = b_buren[save_col][next->row][dir][0];
1364 next->row = b_buren[save_col][next->row][dir][1];
1366 piece = oboard->pieces[next->col][next->row];
1367 while ((next->col != 0) && (piece != '.'))
1369 pushll (temprow, copy_position ((void *) next));
1370 if ((count == 1) &&
1371 ((piece == base_piece) || (piece == base_piece2)))
1373 countrow++;
1374 end->col = next->col;
1375 end->row = next->row;
1377 else
1379 count = 0;
1381 /* b_moveto (next, col_dif, &row_dif);*/
1382 save_col = next->col;
1383 next->col = b_buren[save_col][next->row][dir][0];
1384 next->row = b_buren[save_col][next->row][dir][1];
1386 piece = oboard->pieces[next->col][next->row];
1389 if (countrow > 3)
1391 rowp = new_rem_row ();
1392 rowp->startpos = start;
1393 rowp->endpos = end;
1394 rowp->piecelist = temprow;
1395 rowp->rowindex = rownr;
1396 if ((base_piece == 'o') || (base_piece == 'x'))
1398 rowp->owner = base_piece;
1400 else
1402 rowp->owner = base_piece2;
1405 else
1407 emptyll (temprow, del_position_f);
1408 free (temprow);
1409 del_position (start);
1410 del_position (end);
1411 rowp = NULL;
1413 del_position (base);
1414 del_position (next);
1416 return (rowp);
1419 #if 0
1421 ** b_moveto: give coor of new position
1423 ** parameters:
1424 ** pos: startpos, endpos after run
1425 ** col_dif: column difference
1426 ** row_dif: row difference
1428 inline void b_moveto (position * pos, int col_dif, int * row_dif)
1430 if (col_dif != 0)
1432 if (pos->col == 4)
1434 (*row_dif)--;
1436 pos->col += col_dif;
1439 pos->row += (*row_dif);
1440 if ((pos->col == 0) ||
1441 (pos->col == 8) ||
1442 (pos->row < 2) ||
1443 (pos->row > b_colsize(pos->col)))
1445 pos->col = 0;
1446 pos->row = 0;
1448 return;
1453 ** b_colour: return the number of available pieces for a colour
1455 ** parameters:
1456 ** oboard : pointer to gipf-board
1457 ** colour : o, O, x, X
1459 ** returns:
1460 ** nr of pieces
1462 int b_colour (board * oboard, char colour)
1464 if ((colour == 'o') || (colour == 'O'))
1466 return (oboard->white);
1468 else if ((colour == 'x') || (colour == 'X'))
1470 return (oboard->black);
1472 return (-1);
1477 ** b_colour_gipf: return the number of gipfpieces for a colour
1479 ** parameters:
1480 ** oboard : pointer to gipf-board
1481 ** colour : o, O, x, X
1483 ** returns:
1484 ** nr of pieces
1486 int b_colour_gipf (board * oboard, char colour)
1488 if ((colour == 'o') || (colour == 'O'))
1490 return (oboard->gipfwhite);
1492 else if ((colour == 'x') || (colour == 'X'))
1494 return (oboard->gipfblack);
1496 return (-1);
1501 ** b_colour_lost: return the number of lost pieces for a colour
1503 ** parameters:
1504 ** oboard : pointer to gipf-board
1505 ** colour : o, O, x, X
1507 ** returns:
1508 ** nr of pieces
1510 int b_colour_lost (board * oboard, char colour)
1512 if ((colour == 'o') || (colour == 'O'))
1514 return (oboard->lostwhite);
1516 else if ((colour == 'x') || (colour == 'X'))
1518 return (oboard->lostblack);
1520 return (-1);
1525 ** b_colour_type: return the type of pieces this colour can place
1527 ** parameters:
1528 ** oboard : pointer to gipf-board
1529 ** colour : o, O, x, X
1531 ** returns:
1532 ** n or g
1534 char b_colour_type (board * oboard, char colour)
1536 if ((colour == 'o') || (colour == 'O'))
1538 return (oboard->typewhite);
1540 else if ((colour == 'x') || (colour == 'X'))
1542 return (oboard->typeblack);
1544 return (' ');
1546 #endif
1549 ** b_piece: return piece at position
1551 ** parameters:
1552 ** oboard: pointer to gipf-board
1553 ** pos: position-string (ex. b4)
1555 ** returns:
1556 ** piece
1558 char b_piece (board * oboard, char * strpos)
1560 position * pos;
1561 char piece;
1563 pos = strtopos (strpos);
1564 piece = oboard->pieces[pos->col][pos->row];
1565 del_position (pos);
1567 return (piece);
1572 ** b_game_finished : check if game is finished
1574 ** parameters:
1575 ** oboard: gipf-board
1577 ** returns:
1578 ** 0: game not finished
1579 ** 1: game finished
1581 ** REMARK: only do this if no more rows can be removed from the board
1583 int b_game_finished (board * oboard)
1586 ** check if a player has no gipf-pieces left
1587 ** but only do this at the second move
1589 if ((oboard->movecounter > 0) &&
1590 (oboard->gipfwhite == 0))
1592 oboard->status = S_FINISHED;
1593 oboard->winner = 'x';
1594 return (1);
1597 if (((oboard->movecounter > 1) ||
1598 ((oboard->nextpiece == 'o') && (oboard->movecounter == 1))) &&
1599 (oboard->gipfblack == 0))
1601 oboard->status = S_FINISHED;
1602 oboard->winner = 'o';
1603 return (1);
1606 /* check if the next player has pieces left */
1607 if (b_colour (oboard, oboard->nextpiece) == 0)
1609 oboard->status = S_FINISHED;
1610 oboard->winner = b_opponent (oboard->nextpiece);
1611 return (1);
1614 return (0);
1619 ** b_compare: compare the contents of 2 gipf-boards
1621 ** parameters:
1622 ** board1
1623 ** board2
1625 ** returns:
1626 ** 0: equal
1627 ** 1: different
1629 int b_compare (board * board1, board * board2)
1631 int i,
1634 /* sanity check */
1635 if ((board1 == NULL) || (board2 == NULL))
1637 return (1);
1640 /* compare the different counters */
1641 if ((board1->nextpiece != board2->nextpiece) ||
1642 (board1->movecounter != board2->movecounter) ||
1643 (board1->white != board2->white) ||
1644 (board1->lostwhite != board2->lostwhite) ||
1645 (board1->gipfwhite != board2->gipfwhite) ||
1646 (board1->typewhite != board2->typewhite) ||
1647 (board1->black != board2->black) ||
1648 (board1->lostblack != board2->lostblack) ||
1649 (board1->gipfblack != board2->gipfblack) ||
1650 (board1->typeblack != board2->typeblack))
1652 return (1);
1655 #define MEMCMP 1
1656 #ifndef MEMCMP
1657 /* compare board-contents */
1658 for (i = 1; i < 8; i++)
1659 for (j = 2; j <= b_colsize (i); j++)
1660 if (board1->pieces[i][j] != board2->pieces[i][j])
1661 return (1);
1662 #else
1663 if (memcmp (&(board1->pieces), &(board2->pieces), 72) != 0)
1665 return (1);
1667 #endif
1669 return (0);
1673 listheader * b_row_extra (board * oboard)
1675 if ((oboard->rowextraw != NULL) &&
1676 ((oboard->nextpiece == 'x') || (oboard->rowextrab == NULL)))
1678 return (oboard->rowextraw);
1680 else
1682 return (oboard->rowextrab);
1688 ** replace the piece at position 'pos' with 'piece'
1689 ** try to adapt the counters
1691 ** returns:
1692 ** NULL: error
1694 board * b_edit_piece (board * oboard, position * pos, char piece)
1696 board * nboard;
1698 nboard = b_copy (oboard);
1700 if (nboard->pieces[pos->col][pos->row] == piece)
1702 return (nboard);
1705 /* remove piece */
1706 switch (nboard->pieces[pos->col][pos->row])
1708 case 'o':
1709 nboard->white += 1;
1710 break;
1711 case 'O':
1712 nboard->white += 2;
1713 nboard->gipfwhite -= 1;
1714 break;
1715 case 'x':
1716 nboard->black += 1;
1717 break;
1718 case 'X':
1719 nboard->black += 2;
1720 nboard->gipfblack -= 1;
1721 break;
1722 default:
1723 break;
1726 /* add piece */
1727 switch (piece)
1729 case 'o':
1730 if (nboard->white == 0)
1732 b_del (nboard);
1733 return (NULL);
1735 nboard->white -= 1;
1736 break;
1737 case 'O':
1738 if (nboard->white < 2)
1740 b_del (nboard);
1741 return (NULL);
1743 nboard->white -= 2;
1744 nboard->gipfwhite += 1;
1745 break;
1746 case 'x':
1747 if (nboard->black == 0)
1749 b_del (nboard);
1750 return (NULL);
1752 nboard->black -= 1;
1753 break;
1754 case 'X':
1755 if (nboard->black < 2)
1757 b_del (nboard);
1758 return (NULL);
1760 nboard->black -= 2;
1761 nboard->gipfblack += 1;
1762 break;
1763 default:
1764 break;
1767 nboard->pieces[pos->col][pos->row] = piece;
1769 return (nboard);
1773 board * b_edit_lostwhite (board * oboard, int newval)
1775 board * nboard;
1777 if ((oboard->white + oboard->lostwhite - newval) < 0)
1779 return (NULL);
1782 nboard = b_copy (oboard);
1783 nboard->white = nboard->white + nboard->lostwhite - newval;
1784 nboard->lostwhite = newval;
1786 return (nboard);
1790 board * b_edit_lostblack (board * oboard, int newval)
1792 board * nboard;
1794 if ((oboard->black + oboard->lostblack - newval) < 0)
1796 return (NULL);
1799 nboard = b_copy (oboard);
1800 nboard->black = nboard->black + nboard->lostblack - newval;
1801 nboard->lostblack = newval;
1803 return (nboard);
1807 board * b_from_xml (xmlite_entity * root)
1809 xmlite_entity *x1, *x2, *x3;
1810 char tempstr[100],
1811 piece;
1812 board * nboard;
1813 int counter,
1814 counter2;
1815 position * temppos;
1816 rem_row * row_ptr;
1817 rem_gipf * gipf_ptr;
1819 if (root->getname() != "board")
1820 { // very wrong
1821 return (NULL);
1824 nboard = b_new (T_TOURNAMENT);
1826 // white player
1827 nboard->white =
1828 atoi (root->getcontentbyname("whitepieces")->getvalue().c_str());
1829 nboard->lostwhite =
1830 atoi (root->getcontentbyname("whitelost")->getvalue().c_str());
1831 nboard->gipfwhite =
1832 atoi (root->getcontentbyname("whitegipf")->getvalue().c_str());
1833 nboard->typewhite =
1834 root->getcontentbyname("whitetype")->getvalue()[0];
1836 // black player
1837 nboard->black =
1838 atoi (root->getcontentbyname("blackpieces")->getvalue().c_str());
1839 nboard->lostblack =
1840 atoi (root->getcontentbyname("blacklost")->getvalue().c_str());
1841 nboard->gipfblack =
1842 atoi (root->getcontentbyname("blackgipf")->getvalue().c_str());
1843 nboard->typeblack =
1844 root->getcontentbyname("blacktype")->getvalue()[0];
1846 nboard->nextpiece =
1847 root->getcontentbyname("nextplayer")->getvalue() == "white" ? 'o':'x';
1849 // pieces
1850 counter = 0;
1851 while ((x1 = root->getcontentbyname ("position", counter)) != NULL)
1853 counter++;
1855 piece = x1->getattribute ("color") == "white" ? 'o' : 'x';
1856 if (x1->getattribute ("type") == "gipf")
1857 piece = b_otherpiece (piece);
1859 temppos = strtopos (x1->getvalue().c_str());
1860 nboard->pieces[temppos->col][temppos->row] = piece;
1861 del_position (temppos);
1864 // white rows
1865 if ((x1 = root->getcontentbyname ("rowextrawhite")) != NULL)
1867 nboard->status = S_REMOVEROW;
1868 nboard->rowextraw = (listheader *) malloc (sizeof (listheader));
1869 newlist (nboard->rowextraw);
1871 counter = 0;
1872 while ((x2 = x1->getcontentbyname ("remrow", counter)) != NULL)
1874 counter++;
1876 row_ptr = new_rem_row ();
1877 pushll (nboard->rowextraw, row_ptr);
1878 row_start (row_ptr) =
1879 strtopos (x2->getattribute ("startposition").c_str());
1880 row_end (row_ptr) =
1881 strtopos (x2->getattribute ("endposition").c_str());
1882 row_owner (row_ptr) =
1883 x2->getattribute ("owner").c_str()[0];
1884 row_ptr->rowindex = atoi (x2->getattribute ("rowindex").c_str());
1886 row_ptr->piecelist = (listheader *) malloc (sizeof (listheader));
1887 newlist (row_ptr->piecelist);
1888 counter2 = 0;
1889 while ((x3 = x2->getcontentbyname ("position", counter2)) != NULL)
1891 counter2++;
1892 temppos = strtopos (x3->getvalue ().c_str());
1893 pushll (row_ptr->piecelist, temppos);
1898 // black rows
1899 if ((x1 = root->getcontentbyname ("rowextrablack")) != NULL)
1901 nboard->status = S_REMOVEROW;
1902 nboard->rowextrab = (listheader *) malloc (sizeof (listheader));
1903 newlist (nboard->rowextrab);
1905 counter = 0;
1906 while ((x2 = x1->getcontentbyname ("remrow", counter)) != NULL)
1908 counter++;
1910 row_ptr = new_rem_row ();
1911 pushll (nboard->rowextrab, row_ptr);
1912 row_start (row_ptr) =
1913 strtopos (x2->getattribute ("startposition").c_str());
1914 row_end (row_ptr) =
1915 strtopos (x2->getattribute ("endposition").c_str());
1916 row_owner (row_ptr) =
1917 x2->getattribute ("owner").c_str()[0];
1918 row_ptr->rowindex = atoi (x2->getattribute ("rowindex").c_str());
1920 row_ptr->piecelist = (listheader *) malloc (sizeof (listheader));
1921 newlist (row_ptr->piecelist);
1922 counter2 = 0;
1923 while ((x3 = x2->getcontentbyname ("position", counter2)) != NULL)
1925 counter2++;
1926 temppos = strtopos (x3->getvalue ().c_str());
1927 pushll (row_ptr->piecelist, temppos);
1932 // gipf pieces that can be removed
1933 if ((x1 = root->getcontentbyname ("gipfextra")) != NULL)
1935 nboard->status = S_REMOVEGIPF;
1936 nboard->gipfextra = (listheader *) malloc (sizeof (listheader));
1937 newlist (nboard->gipfextra);
1939 counter = 0;
1940 while ((x2 = x1->getcontentbyname ("remgipf", counter)) != NULL)
1942 counter++;
1944 gipf_ptr = new_rem_gipf ();
1945 pushll (nboard->gipfextra, gipf_ptr);
1947 gipf_ptr->owner = x2->getattribute ("owner")[0];
1948 gipf_ptr->pos = strtopos (x2->getvalue ().c_str());
1952 return (nboard);
1956 xmlite_entity * b_to_xml (board * oboard)
1958 position * temppos;
1959 xmlite_entity *x1, *x2, *x3, *x4;
1960 char tempstr[100],
1961 * strptr,
1962 tempc;
1963 int counter,
1964 counter2,
1965 i, j;
1967 x1 = new xmlite_entity ("board");
1969 // white player
1970 x2 = new xmlite_entity ("whitepieces");
1971 sprintf (tempstr, "%d", oboard->white);
1972 x2->setvalue (tempstr);
1973 x1->addcontent (x2);
1974 x2 = new xmlite_entity ("whitelost");
1975 sprintf (tempstr, "%d", oboard->lostwhite);
1976 x2->setvalue (tempstr);
1977 x1->addcontent (x2);
1978 x2 = new xmlite_entity ("whitegipf");
1979 sprintf (tempstr, "%d", oboard->gipfwhite);
1980 x2->setvalue (tempstr);
1981 x1->addcontent (x2);
1982 x2 = new xmlite_entity ("whitetype");
1983 sprintf (tempstr, "%c", oboard->typewhite);
1984 x2->setvalue (tempstr);
1985 x1->addcontent (x2);
1987 // black player
1988 x2 = new xmlite_entity ("blackpieces");
1989 sprintf (tempstr, "%d", oboard->black);
1990 x2->setvalue (tempstr);
1991 x1->addcontent (x2);
1992 x2 = new xmlite_entity ("blacklost");
1993 sprintf (tempstr, "%d", oboard->lostblack);
1994 x2->setvalue (tempstr);
1995 x1->addcontent (x2);
1996 x2 = new xmlite_entity ("blackgipf");
1997 sprintf (tempstr, "%d", oboard->gipfblack);
1998 x2->setvalue (tempstr);
1999 x1->addcontent (x2);
2000 x2 = new xmlite_entity ("blacktype");
2001 sprintf (tempstr, "%c", oboard->typeblack);
2002 x2->setvalue (tempstr);
2003 x1->addcontent (x2);
2005 x2 = new xmlite_entity ("nextplayer");
2006 x2->setvalue (oboard->nextpiece == 'o' ? "white" : "black");
2007 x1->addcontent (x2);
2009 // pieces on the board
2010 temppos = (position *) malloc (sizeof (position));
2011 for (i = 1; i < 8; i++)
2013 temppos->col = i;
2014 for (j = 2; j <= b_colsize (i); j++)
2016 temppos->row = j;
2017 tempc = b_ppiece (oboard, temppos);
2018 if (tempc != '.')
2020 x2 = new xmlite_entity ("position");
2021 if ((tempc == 'o') || (tempc == 'x'))
2022 x2->addattribute ("type", "piece");
2023 else
2024 x2->addattribute ("type", "gipf");
2025 if ((tempc == 'o') || (tempc == 'O'))
2026 x2->addattribute ("color", "white");
2027 else
2028 x2->addattribute ("color", "black");
2030 strptr = postostr (temppos);
2031 x2->setvalue (strptr);
2032 delete (strptr);
2033 x1->addcontent (x2);
2037 free (temppos);
2039 // gipfextra
2040 if (oboard->gipfextra != NULL)
2042 rem_gipf * gipf_ptr;
2044 x2 = new xmlite_entity ("gipfextra");
2045 x1->addcontent (x2);
2047 counter = 1;
2048 while ((gipf_ptr = (rem_gipf *)
2049 llitembynr (oboard->gipfextra, counter)) != NULL)
2051 counter++;
2053 x3 = new xmlite_entity ("remgipf");
2054 x2->addcontent (x3);
2055 sprintf (tempstr, "%c", gipf_ptr->owner);
2056 x3->addattribute ("owner", tempstr);
2057 strptr = postostr (gipf_ptr->pos);
2058 x3->setvalue (strptr);
2059 delete (strptr);
2063 // rowextrawhite
2064 if (oboard->rowextraw != NULL)
2066 rem_row * row_ptr;
2067 position * pos_ptr;
2069 x2 = new xmlite_entity ("rowextrawhite");
2070 x1->addcontent (x2);
2072 counter = 1;
2073 while ((row_ptr = (rem_row *)
2074 llitembynr (oboard->rowextraw, counter)) != NULL)
2076 counter++;
2078 x3 = new xmlite_entity ("remrow");
2079 x2->addcontent (x3);
2080 strptr = postostr (row_start(row_ptr));
2081 x3->addattribute ("startposition", strptr);
2082 delete (strptr);
2083 strptr = postostr (row_end(row_ptr));
2084 x3->addattribute ("endposition", strptr);
2085 delete (strptr);
2086 sprintf (tempstr, "%c", row_owner (row_ptr));
2087 x3->addattribute ("owner", tempstr);
2088 sprintf (tempstr, "%d", row_ptr->rowindex);
2089 x3->addattribute ("rowindex", tempstr);
2091 counter2 = 1;
2092 while ((pos_ptr = (position *)
2093 llitembynr (row_ptr->piecelist, counter2)) != NULL)
2095 counter2++;
2097 x4 = new xmlite_entity ("position");
2098 x3->addcontent (x4);
2099 strptr = postostr (pos_ptr);
2100 x4->setvalue (strptr);
2101 delete (strptr);
2106 // rowextrablack
2107 if (oboard->rowextrab != NULL)
2109 rem_row * row_ptr;
2110 position * pos_ptr;
2112 x2 = new xmlite_entity ("rowextrablack");
2113 x1->addcontent (x2);
2115 counter = 1;
2116 while ((row_ptr = (rem_row *)
2117 llitembynr (oboard->rowextrab, counter)) != NULL)
2119 counter++;
2121 x3 = new xmlite_entity ("remrow");
2122 x2->addcontent (x3);
2123 strptr = postostr (row_start(row_ptr));
2124 x3->addattribute ("startposition", strptr);
2125 delete (strptr);
2126 strptr = postostr (row_end(row_ptr));
2127 x3->addattribute ("endposition", strptr);
2128 delete (strptr);
2129 sprintf (tempstr, "%c", row_owner (row_ptr));
2130 x3->addattribute ("owner", tempstr);
2131 sprintf (tempstr, "%d", row_ptr->rowindex);
2132 x3->addattribute ("rowindex", tempstr);
2134 counter2 = 1;
2135 while ((pos_ptr = (position *)
2136 llitembynr (row_ptr->piecelist, counter2)) != NULL)
2138 counter2++;
2140 x4 = new xmlite_entity ("position");
2141 x3->addcontent (x4);
2142 strptr = postostr (pos_ptr);
2143 x4->setvalue (strptr);
2144 delete (strptr);
2149 return (x1);
2153 ** REMARK:
2154 ** Don't use this anymore
2155 ** use the new b_to_xml
2158 ** write a boardsituation to a file
2159 ** use a format that can be read by b_from_file
2160 ** (should also be readable by gipfdraw, so you can easily
2161 ** make gif's from a board-position)
2163 ** returns -1 on failure, otherwise 0
2165 ** REMARK: the board must be in a stable state (S_NORMAL or S_FINISHED)
2166 ** otherwise the save will fail
2168 int b_to_file (board * oboard, FILE * fp)
2170 int i, j;
2171 position * temppos;
2172 char * tempstr;
2174 if (oboard == NULL)
2175 return (-1);
2177 if ((oboard->status != S_NORMAL) && (oboard->status != S_FINISHED))
2179 return (-1);
2182 fprintf (fp, "whitepieces:%d\n", oboard->white);
2183 fprintf (fp, "whitelost:%d\n", oboard->lostwhite);
2185 fprintf (fp, "blackpieces:%d\n", oboard->black);
2186 fprintf (fp, "blacklost:%d\n", oboard->lostblack);
2188 fprintf (fp, "nextplayer:%c\n", oboard->nextpiece);
2190 temppos = (position *) malloc (sizeof (position));
2191 for (i = 1; i < 8; i++)
2193 temppos->col = i;
2194 for (j = 2; j <= b_colsize (i); j++)
2196 temppos->row = j;
2197 if (b_ppiece (oboard, temppos) != '.')
2199 tempstr = postostr (temppos);
2200 fprintf (fp, "%c:%2s\n",
2201 b_ppiece (oboard, temppos), tempstr);
2202 free (tempstr);
2206 free (temppos);
2208 fprintf (fp, "# end of board\n");
2210 return (0);
2215 ** read a boardsituation from a file and store it in a
2216 ** board-structure.
2218 ** returns NULL on failure
2220 board * b_from_file (FILE * fp)
2222 char buffer[100]="",
2223 tempchar,
2224 tempstr[100];
2225 board * nboard;
2226 int tempnr;
2227 position * temppos;
2229 nboard = b_new (T_TOURNAMENT);
2230 nboard->typewhite = 'n';
2231 nboard->typeblack = 'n';
2233 while (strncmp (buffer, "# end of board", 14) != 0)
2235 if (fgets (buffer, 100, fp) == NULL)
2237 b_del (nboard);
2238 return (NULL);
2241 if (sscanf (buffer, "whitepieces:%d", &tempnr) == 1)
2243 nboard->white = tempnr;
2245 else if (sscanf (buffer, "whitelost:%d", &tempnr) == 1)
2247 nboard->lostwhite = tempnr;
2249 else if (sscanf (buffer, "blackpieces:%d", &tempnr) == 1)
2251 nboard->black = tempnr;
2253 else if (sscanf (buffer, "blacklost:%d", &tempnr) == 1)
2255 nboard->lostblack = tempnr;
2257 else if (sscanf (buffer, "nextplayer:%c", &tempchar) == 1)
2259 nboard->nextpiece = tempchar;
2261 else if (sscanf (buffer, "%c:%s", &tempchar, tempstr) == 2)
2263 temppos = strtopos (tempstr);
2264 nboard->pieces[temppos->col][temppos->row] = tempchar;
2265 switch (tempchar)
2267 case 'O':
2268 nboard->gipfwhite += 1;
2269 break;
2270 case 'X':
2271 nboard->gipfblack += 1;
2272 break;
2274 del_position (temppos);
2278 if ((nboard->gipfwhite == 0) && (nboard->gipfblack == 0))
2280 nboard->gipfwhite = -1;
2281 nboard->gipfblack = -1;
2284 return (nboard);