(Temporarily) set "animate" to "none" by default (broken feature).
[gf1.git] / board.c
blob45a199ff2cb3559ee88a293f9f08494bbf2bdd2c
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 /*
8 ** Copyright (C) 1998 Kurt Van den Branden
9 **
10 ** This program is free software; you can redistribute it and/or modify
11 ** it under the terms of the GNU General Public License as published by
12 ** the Free Software Foundation; either version 2 of the License, or
13 ** (at your option) any later version.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program; if not, write to the Free Software
22 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <stdlib.h>
25 #include <string.h>
26 #include "board.h"
28 #undef WINGIPF
29 #ifdef WINGIPF
30 extern void waitremrow (board * oldb, rem_row * row, board * newb);
31 extern void waitremgipf (board * oldb, position * gipf, board * newb);
33 extern void animatemove (board * oldb, listheader * pieces, board * newb);
35 typedef struct {
36 char piece;
37 position from;
38 position to;
39 } piecemove;
40 #endif
42 int _colsize[] = {0, 5, 6, 7, 8, 7, 6, 5, 0};
44 char _colchar[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'};
46 /* 42 different possible moves, without gipf-pieces */
47 fromto allmovesn[] = {
48 {"b1","b2",'n'}, {"a1","b2",'n'}, {"a2","b2",'n'},
49 {"a2","b3",'n'}, {"a3","b3",'n'},
50 {"a3","b4",'n'}, {"a4","b4",'n'},
51 {"a4","b5",'n'}, {"a5","b5",'n'}, {"b6","b5",'n'},
52 {"b6","c6",'n'}, {"c7","c6",'n'},
53 {"c7","d7",'n'}, {"d8","d7",'n'},
54 {"d8","e8",'n'}, {"e9","e8",'n'}, {"f8","e8",'n'},
55 {"f8","f7",'n'}, {"g7","f7",'n'},
56 {"g7","g6",'n'}, {"h6","g6",'n'},
57 {"h6","h5",'n'}, {"i5","h5",'n'}, {"i4","h5",'n'},
58 {"i4","h4",'n'}, {"i3","h4",'n'},
59 {"i3","h3",'n'}, {"i2","h3",'n'},
60 {"i2","h2",'n'}, {"i1","h2",'n'}, {"h1","h2",'n'},
61 {"h1","g2",'n'}, {"g1","g2",'n'},
62 {"g1","f2",'n'}, {"f1","f2",'n'},
63 {"f1","e2",'n'}, {"e1","e2",'n'}, {"d1","e2",'n'},
64 {"d1","d2",'n'}, {"c1","d2",'n'},
65 {"c1","c2",'n'}, {"b1","c2",'n'}
68 /* 84 different possible moves, with gipf-pieces */
69 fromto allmovesg[] = {
70 {"b1","b2",'g'}, {"a1","b2",'g'}, {"a2","b2",'g'},
71 {"a2","b3",'g'}, {"a3","b3",'g'},
72 {"a3","b4",'g'}, {"a4","b4",'g'},
73 {"a4","b5",'g'}, {"a5","b5",'g'}, {"b6","b5",'g'},
74 {"b6","c6",'g'}, {"c7","c6",'g'},
75 {"c7","d7",'g'}, {"d8","d7",'g'},
76 {"d8","e8",'g'}, {"e9","e8",'g'}, {"f8","e8",'g'},
77 {"f8","f7",'g'}, {"g7","f7",'g'},
78 {"g7","g6",'g'}, {"h6","g6",'g'},
79 {"h6","h5",'g'}, {"i5","h5",'g'}, {"i4","h5",'g'},
80 {"i4","h4",'g'}, {"i3","h4",'g'},
81 {"i3","h3",'g'}, {"i2","h3",'g'},
82 {"i2","h2",'g'}, {"i1","h2",'g'}, {"h1","h2",'g'},
83 {"h1","g2",'g'}, {"g1","g2",'g'},
84 {"g1","f2",'g'}, {"f1","f2",'g'},
85 {"f1","e2",'g'}, {"e1","e2",'g'}, {"d1","e2",'g'},
86 {"d1","d2",'g'}, {"c1","d2",'g'},
87 {"c1","c2",'g'}, {"b1","c2",'g'},
88 {"b1","b2",'n'}, {"a1","b2",'n'}, {"a2","b2",'n'},
89 {"a2","b3",'n'}, {"a3","b3",'n'},
90 {"a3","b4",'n'}, {"a4","b4",'n'},
91 {"a4","b5",'n'}, {"a5","b5",'n'}, {"b6","b5",'n'},
92 {"b6","c6",'n'}, {"c7","c6",'n'},
93 {"c7","d7",'n'}, {"d8","d7",'n'},
94 {"d8","e8",'n'}, {"e9","e8",'n'}, {"f8","e8",'n'},
95 {"f8","f7",'n'}, {"g7","f7",'n'},
96 {"g7","g6",'n'}, {"h6","g6",'n'},
97 {"h6","h5",'n'}, {"i5","h5",'n'}, {"i4","h5",'n'},
98 {"i4","h4",'n'}, {"i3","h4",'n'},
99 {"i3","h3",'n'}, {"i2","h3",'n'},
100 {"i2","h2",'n'}, {"i1","h2",'n'}, {"h1","h2",'n'},
101 {"h1","g2",'n'}, {"g1","g2",'n'},
102 {"g1","f2",'n'}, {"f1","f2",'n'},
103 {"f1","e2",'n'}, {"e1","e2",'n'}, {"d1","e2",'n'},
104 {"d1","d2",'n'}, {"c1","d2",'n'},
105 {"c1","c2",'n'}, {"b1","c2",'n'}
110 ** list of all the neighbours of a board-position
112 ** 3
113 ** 1 5
114 ** pos
115 ** 0 4
116 ** 2
118 unsigned char b_buren[9][9][6][2] = {
119 {{{0}}/* row a */},
120 {/* row b */
121 {{0}},
122 {{0}},
123 {{0, 0}, {0, 0}, {0, 0}, {1, 3}, {2, 2}, {2, 3}}, /* b2 */
124 {{0, 0}, {0, 0}, {1, 2}, {1, 4}, {2, 3}, {2, 4}}, /* b3 */
125 {{0, 0}, {0, 0}, {1, 3}, {1, 5}, {2, 4}, {2, 5}}, /* b4 */
126 {{0, 0}, {0, 0}, {1, 4}, {0, 0}, {2, 5}, {2, 6}} /* b5 */
128 {/* row c */
129 {{0}},
130 {{0}},
131 {{0, 0}, {1, 2}, {0, 0}, {2, 3}, {3, 2}, {3, 3}}, /* c2 */
132 {{1, 2}, {1, 3}, {2, 2}, {2, 4}, {3, 3}, {3, 4}}, /* c3 */
133 {{1, 3}, {1, 4}, {2, 3}, {2, 5}, {3, 4}, {3, 5}}, /* c4 */
134 {{1, 4}, {1, 5}, {2, 4}, {2, 6}, {3, 5}, {3, 6}}, /* c5 */
135 {{1, 5}, {0, 0}, {2, 5}, {0, 0}, {3, 6}, {3, 7}} /* c6 */
137 {/* row d */
138 {{0}},
139 {{0}},
140 {{0, 0}, {2, 2}, {0, 0}, {3, 3}, {4, 2}, {4, 3}}, /* d2 */
141 {{2, 2}, {2, 3}, {3, 2}, {3, 4}, {4, 3}, {4, 4}}, /* d3 */
142 {{2, 3}, {2, 4}, {3, 3}, {3, 5}, {4, 4}, {4, 5}}, /* d4 */
143 {{2, 4}, {2, 5}, {3, 4}, {3, 6}, {4, 5}, {4, 6}}, /* d5 */
144 {{2, 5}, {2, 6}, {3, 5}, {3, 7}, {4, 6}, {4, 7}}, /* d6 */
145 {{2, 6}, {0, 0}, {3, 6}, {0, 0}, {4, 7}, {4, 8}} /* d7 */
147 {/* row e */
148 {{0}},
149 {{0}},
150 {{0, 0}, {3, 2}, {0, 0}, {4, 3}, {0, 0}, {5, 2}}, /* e2 */
151 {{3, 2}, {3, 3}, {4, 2}, {4, 4}, {5, 2}, {5, 3}}, /* e3 */
152 {{3, 3}, {3, 4}, {4, 3}, {4, 5}, {5, 3}, {5, 4}}, /* e4 */
153 {{3, 4}, {3, 5}, {4, 4}, {4, 6}, {5, 4}, {5, 5}}, /* e5 */
154 {{3, 5}, {3, 6}, {4, 5}, {4, 7}, {5, 5}, {5, 6}}, /* e6 */
155 {{3, 6}, {3, 7}, {4, 6}, {4, 8}, {5, 6}, {5, 7}}, /* e7 */
156 {{3, 7}, {0, 0}, {4, 7}, {0, 0}, {5, 7}, {0, 0}} /* e8 */
158 {/* row f */
159 {{0}},
160 {{0}},
161 {{4, 2}, {4, 3}, {0, 0}, {5, 3}, {0, 0}, {6, 2}}, /* f2 */
162 {{4, 3}, {4, 4}, {5, 2}, {5, 4}, {6, 2}, {6, 3}}, /* f3 */
163 {{4, 4}, {4, 5}, {5, 3}, {5, 5}, {6, 3}, {6, 4}}, /* f4 */
164 {{4, 5}, {4, 6}, {5, 4}, {5, 6}, {6, 4}, {6, 5}}, /* f5 */
165 {{4, 6}, {4, 7}, {5, 5}, {5, 7}, {6, 5}, {6, 6}}, /* f6 */
166 {{4, 7}, {4, 8}, {5, 6}, {0, 0}, {6, 6}, {0, 0}} /* f7 */
168 {/* row g */
169 {{0}},
170 {{0}},
171 {{5, 2}, {5, 3}, {0, 0}, {6, 3}, {0, 0}, {7, 2}}, /* g2 */
172 {{5, 3}, {5, 4}, {6, 2}, {6, 4}, {7, 2}, {7, 3}}, /* g3 */
173 {{5, 4}, {5, 5}, {6, 3}, {6, 5}, {7, 3}, {7, 4}}, /* g4 */
174 {{5, 5}, {5, 6}, {6, 4}, {6, 6}, {7, 4}, {7, 5}}, /* g5 */
175 {{5, 6}, {5, 7}, {6, 5}, {0, 0}, {7, 5}, {0, 0}} /* g6 */
177 {/* row h */
178 {{0}},
179 {{0}},
180 {{6, 2}, {6, 3}, {0, 0}, {7, 3}, {0, 0}, {0, 0}}, /* h2 */
181 {{6, 3}, {6, 4}, {7, 2}, {7, 4}, {0, 0}, {0, 0}}, /* h3 */
182 {{6, 4}, {6, 5}, {7, 3}, {7, 5}, {0, 0}, {0, 0}}, /* h4 */
183 {{6, 5}, {6, 6}, {7, 4}, {0, 0}, {0, 0}, {0, 0}} /* h5 */
185 {{{0}}/* row i */}
190 ** each item of the list contains:
191 ** - middle point for the row
192 ** - first direction for this row (second direction = 5 - first direction)
193 ** - second direction
194 ** - minimum nr of pieces necessary in the first direction
196 int rowlist[][5] = {
197 {2, 2, 1, 4, 2},
198 {3, 3, 1, 4, 2},
199 {4, 4, 1, 4, 2},
200 {4, 5, 1, 4, 1},
201 {5, 5, 1, 4, 2},
202 {5, 6, 1, 4, 2},
203 {5, 7, 1, 4, 2},
204 {1, 3, 2, 3, 2},
205 {2, 4, 2, 3, 2},
206 {3, 5, 2, 3, 2},
207 {4, 5, 2, 3, 1},
208 {5, 5, 2, 3, 2},
209 {6, 4, 2, 3, 2},
210 {7, 3, 2, 3, 2},
211 {5, 2, 0, 5, 2},
212 {5, 3, 0, 5, 2},
213 {5, 4, 0, 5, 2},
214 {4, 5, 0, 5, 1},
215 {4, 6, 0, 5, 2},
216 {3, 6, 0, 5, 2},
217 {2, 6, 0, 5, 2}
222 board * b_new (int board_type)
224 board * board_ref;
225 int i, j;
227 board_ref = b_newboard();
228 for (i = 0; i < 8; i++)
229 for (j = 0; j < 9; j++)
230 board_ref->pieces[i][j] = '.';
232 board_ref->status = S_NORMAL;
233 board_ref->nextpiece = 'o';
234 board_ref->gipfextra = NULL;
235 board_ref->rowextraw = NULL;
236 board_ref->rowextrab = NULL;
237 board_ref->white = 18;
238 board_ref->lostwhite = 0;
239 board_ref->gipfwhite = 0;
240 board_ref->typewhite = 'n';
241 board_ref->black = 18;
242 board_ref->lostblack = 0;
243 board_ref->gipfblack = 0;
244 board_ref->typeblack = 'n';
245 board_ref->winner = '.';
246 board_ref->checkfour = 'n';
247 board_ref->log = NULL;
248 board_ref->movecounter = 0;
249 #ifdef WINGIPF
250 board_ref->removewait = 0;
251 board_ref->animate = 0;
252 #endif
254 if (board_type == T_BASIC)
256 board_ref->white = 12;
257 board_ref->black = 12;
258 board_ref->pieces[1][5] = 'o';
259 board_ref->pieces[7][5] = 'o';
260 board_ref->pieces[4][2] = 'o';
261 board_ref->pieces[1][2] = 'x';
262 board_ref->pieces[4][8] = 'x';
263 board_ref->pieces[7][2] = 'x';
264 board_ref->gipfwhite = -1;
265 board_ref->gipfblack = -1;
267 else if (board_type == T_STANDARD)
269 board_ref->white = 12;
270 board_ref->black = 12;
271 board_ref->pieces[1][5] = 'O';
272 board_ref->pieces[7][5] = 'O';
273 board_ref->pieces[4][2] = 'O';
274 board_ref->pieces[1][2] = 'X';
275 board_ref->pieces[4][8] = 'X';
276 board_ref->pieces[7][2] = 'X';
277 board_ref->gipfwhite = 3;
278 board_ref->gipfblack = 3;
280 else
281 { /* tournament */
282 board_ref->typewhite = 'g';
283 board_ref->typeblack = 'g';
286 return (board_ref);
289 board * b_copy (board * orig_board)
291 board * new_board;
292 int i, j;
294 if (orig_board == NULL)
295 return (NULL);
297 new_board = b_newboard();
299 #define MEMCPY 1
300 #ifndef MEMCPY
301 for (i = 1; i < 8; i++)
302 for (j = 2; j <= b_colsize (i); j++)
303 new_board->pieces[i][j] = orig_board->pieces[i][j];
305 new_board->status = orig_board->status;
306 new_board->nextpiece = orig_board->nextpiece;
307 new_board->winner = orig_board->winner;
308 new_board->checkfour = orig_board->checkfour;
309 new_board->log = orig_board->log;
310 new_board->movecounter = orig_board->movecounter;
312 new_board->white = orig_board->white;
313 new_board->typewhite = orig_board->typewhite;
314 new_board->lostwhite = orig_board->lostwhite;
315 new_board->gipfwhite = orig_board->gipfwhite;
316 new_board->black = orig_board->black;
317 new_board->typeblack = orig_board->typeblack;
318 new_board->lostblack = orig_board->lostblack;
319 new_board->gipfblack = orig_board->gipfblack;
320 #else
321 memcpy (new_board, orig_board, sizeof (board));
322 #endif
324 if (orig_board->gipfextra != NULL)
326 new_board->gipfextra = copy_rem_gipf_row (orig_board->gipfextra);
328 if (orig_board->rowextraw != NULL)
330 new_board->rowextraw = copy_rem_row_row (orig_board->rowextraw);
332 if (orig_board->rowextrab != NULL)
334 new_board->rowextrab = copy_rem_row_row (orig_board->rowextrab);
336 return (new_board);
340 void b_print (board * boardp)
342 #ifndef WINGIPF
343 if (boardp == NULL)
345 printf ("\nERROR: the boardp-pointer is NULL (b_print)\n\n");
346 return;
349 printf ("A B C D E F G H I\n");
350 printf ("5 6 7 8 9 8 7 6 5\n\n");
351 printf (" *\n");
352 printf (" * *\n");
353 printf (" * %c *\n", boardp->pieces[4][8]);
354 printf (" * %c %c *\n",
355 boardp->pieces[3][7], boardp->pieces[5][7]);
356 printf ("* %c %c %c *\n",
357 boardp->pieces[2][6], boardp->pieces[4][7], boardp->pieces[6][6]);
358 printf (" %c %c %c %c\n",
359 boardp->pieces[1][5], boardp->pieces[3][6],
360 boardp->pieces[5][6], boardp->pieces[7][5]);
361 printf ("* %c %c %c *\n",
362 boardp->pieces[2][5], boardp->pieces[4][6], boardp->pieces[6][5]);
363 printf (" %c %c %c %c\n",
364 boardp->pieces[1][4], boardp->pieces[3][5],
365 boardp->pieces[5][5], boardp->pieces[7][4]);
366 printf ("* %c %c %c *\n",
367 boardp->pieces[2][4], boardp->pieces[4][5], boardp->pieces[6][4]);
368 printf (" %c %c %c %c\n",
369 boardp->pieces[1][3], boardp->pieces[3][4],
370 boardp->pieces[5][4], boardp->pieces[7][3]);
371 printf ("* %c %c %c *\n",
372 boardp->pieces[2][3], boardp->pieces[4][4], boardp->pieces[6][3]);
373 printf (" %c %c %c %c\n",
374 boardp->pieces[1][2], boardp->pieces[3][3],
375 boardp->pieces[5][3], boardp->pieces[7][2]);
376 printf ("* %c %c %c *\n",
377 boardp->pieces[2][2], boardp->pieces[4][3], boardp->pieces[6][2]);
378 printf (" * %c %c *\n",
379 boardp->pieces[3][2], boardp->pieces[5][2]);
380 printf (" * %c *\n", boardp->pieces[4][2]);
381 printf (" * *\n");
382 printf (" * white: %d\n",
383 boardp->white);
384 printf (" lostwhite: %d\n",
385 boardp->lostwhite);
386 printf ("1 1 1 1 1 1 1 1 1 black: %d\n",
387 boardp->black);
388 printf ("A B C D E F G H I lostblack: %d\n",
389 boardp->lostblack);
390 #endif
391 return;
395 void b_del (board * dboard)
397 if (dboard != NULL)
399 if (dboard->gipfextra != NULL)
401 emptyll (dboard->gipfextra, del_rem_gipf);
402 free (dboard->gipfextra);
404 if (dboard->rowextraw != NULL)
406 emptyll (dboard->rowextraw, del_rem_row);
407 free (dboard->rowextraw);
409 if (dboard->rowextrab != NULL)
411 emptyll (dboard->rowextrab, del_rem_row);
412 free (dboard->rowextrab);
414 free (dboard);
417 return;
422 ** b_move : move a piece on a gipf-board
424 ** parameters:
425 ** oboard : pointer to original board
426 ** from : string with from-position
427 ** to : string with to-position
428 ** npiece: piece to add to the board (o, O, x, X)
430 ** returns:
431 ** pointer to a new board
432 ** NULL
434 board * b_move (board * oboard, char * from, char * to, char npiece)
436 position * from_p,
437 * to_p,
438 * next_p;
439 int row_dif,
440 col_dif;
441 board * nboard,
442 * new_board;
443 char save_piece,
444 piece,
445 tempstr[80],
446 * lastmoved = NULL;
447 #ifdef WINGIPF
448 listheader * pmoves;
449 piecemove * piecem;
450 #endif
452 /* check if oboard is in the correct state */
453 if (oboard->status == S_REMOVEROW)
454 { /* wrong status */
455 return (NULL);
457 if ((npiece != oboard->nextpiece) &&
458 (b_otherpiece (npiece) != oboard->nextpiece))
459 { /* wrong player */
460 return (NULL);
463 /* check if the player has pieces left */
464 if ((npiece == 'o') || (npiece == 'O'))
466 if (oboard->white <= 0)
468 return (NULL);
471 else if (oboard->black <= 0)
473 return (NULL);
476 /* if the player wants to place a gipf, check if this is allowed */
477 if ((npiece == 'O') && (oboard->typewhite != 'g'))
479 return (NULL);
481 else if ((npiece == 'X') && (oboard->typeblack != 'g'))
483 return (NULL);
486 /* move the piece */
487 from_p = strtopos (from);
488 to_p = strtopos (to);
489 if ((from_p == NULL) || (to_p == NULL))
490 { /* invalid from or to position */
491 del_position (from_p);
492 del_position (to_p);
493 return (NULL);
495 next_p = (position *) copy_position ((void *) to_p);
496 row_dif = to_p->row - from_p->row;
497 col_dif = to_p->col - from_p->col;
499 /* valid to-position ? */
500 if (((to_p->col < 1) || (to_p->col > 7)) ||
501 ((to_p->col != 1) && (to_p->col != 7) &&
502 (to_p->row != 2) && (to_p->row != b_colsize (to_p->col))) ||
503 (((to_p->col == 1) | (to_p->col == 7)) &&
504 ((to_p->row <2) || (to_p->row >5))))
506 #ifndef WINGIPF
507 printf ("invalid move (to): (%s, %s)\n", from, to);
508 #endif
509 del_position (from_p);
510 del_position (to_p);
511 del_position (next_p);
512 return (NULL);
515 /* valid from-position ? */
516 if ((abs (row_dif) > 1) ||
517 (abs (col_dif) > 1) ||
518 (((from_p->col == 0) || (from_p->col == 8)) && (row_dif < 0)) ||
519 (( from_p->row == 1) && (((from_p->col < 5) && (col_dif < 0)) ||
520 ((from_p->col > 3) && (col_dif > 0)))) ||
521 ((from_p->col > 0) && (from_p->col < 8) &&
522 (from_p->row != 1) && (from_p->row != b_colsize (from_p->col) + 1)))
524 #ifndef WINGIPF
525 printf ("invalid move (from): (%s, %s)\n", from, to);
526 #endif
527 del_position (from_p);
528 del_position (to_p);
529 del_position (next_p);
530 return (NULL);
533 nboard = b_copy (oboard);
534 if (nboard->gipfextra != NULL)
536 emptyll (nboard->gipfextra, del_rem_gipf);
537 free (nboard->gipfextra);
538 nboard->gipfextra = NULL;
541 nboard->status = S_NORMAL;
542 if (oboard->nextpiece == 'o')
544 nboard->movecounter++;
547 #ifdef WINGIPF
548 pmoves = (listheader *) malloc (sizeof (listheader));
549 newlist (pmoves);
551 piecem = (piecemove *) malloc (sizeof (piecemove));
552 piecem->piece = npiece;
553 piecem->from.col = from_p->col;
554 piecem->from.row = from_p->row;
555 piecem->to.col = to_p->col;
556 piecem->to.row = to_p->row;
557 pushll (pmoves, (void *) piecem);
558 #endif
560 save_piece = nboard->pieces[to_p->col][to_p->row];
561 nboard->pieces[to_p->col][to_p->row] = npiece;
562 while (save_piece != '.')
564 #ifdef WINGIPF
565 piecem = (piecemove *) malloc (sizeof (piecemove));
566 piecem->piece = save_piece;
567 piecem->from.col = next_p->col;
568 piecem->from.row = next_p->row;
569 #endif
570 if (col_dif != 0)
571 { /* going diagonally */
572 if (next_p->col == 4)
573 { /* going over the middle line */
574 row_dif--;
576 next_p->col += col_dif;
578 next_p->row += row_dif;
579 if ((next_p->col == 0) ||
580 (next_p->col == 8) ||
581 (next_p->row < 2) ||
582 (next_p->row > b_colsize (next_p->col)))
583 { /* the row is full, no pieces can be added */
584 del_position (from_p);
585 del_position (next_p);
586 del_position (to_p);
587 b_del (nboard);
588 #ifdef WINGIPF
589 free (piecem);
590 while ((piecem = (piecemove *) llrembynr (pmoves, 1)) != NULL)
592 free (piecem);
594 free (pmoves);
595 #endif
596 return (NULL);
598 #ifdef WINGIPF
599 piecem->to.col = next_p->col;
600 piecem->to.row = next_p->row;
601 pushll (pmoves, (void *) piecem);
602 #endif
603 piece = save_piece;
604 save_piece = nboard->pieces[next_p->col][next_p->row];
605 nboard->pieces[next_p->col][next_p->row] = piece;
607 lastmoved = postostr (next_p); /* just for logging-purposes */
609 if (npiece == 'o')
611 nboard->white -= 1;
612 nboard->typewhite = 'n';
614 else if (npiece == 'O')
616 nboard->white -= 2;
617 nboard->gipfwhite++;
619 else if (npiece == 'x')
621 nboard->black -= 1;
622 nboard->typeblack = 'n';
624 else
626 nboard->black -= 2;
627 nboard->gipfblack++;
629 nboard->nextpiece = b_opponent (nboard->nextpiece);
631 if (nboard->log)
633 sprintf (tempstr, "%c:%2s:%2s", npiece, from, lastmoved);
634 addtolog (nboard->log, LOGMOVE, tempstr);
636 free (lastmoved);
638 #ifdef WINGIPF
639 /* animate move */
640 if (nboard->animate)
642 animatemove (oboard, pmoves, nboard);
645 while ((piecem = (piecemove *) llrembynr (pmoves, 1)) != NULL)
647 free (piecem);
649 free (pmoves);
650 #endif
652 /* check for 4 in a row */
653 nboard->checkfour = 'y';
654 new_board = b_checkfour (nboard);
656 /* cleanup memory */
657 del_position (from_p);
658 del_position (next_p);
659 del_position (to_p);
660 b_del (nboard);
662 return (new_board);
667 ** b_remove_row: remove a row from the playing field, adapt the different
668 ** counters
670 ** parameters:
671 ** oboard : pointer to gipf-board
672 ** rownr : nr of the row to be removed from gipfextra
674 ** returns:
675 ** pointer to a new gipf-board
676 ** NULL
678 board * b_remove_row (board * oboard, int rownr)
680 rem_row * row_ptr,
681 * n_row;
682 board * nboard,
683 * new_board;
684 listheader * glist,
685 * plist,
686 * rowextra_o,
687 * rowextra_n;
688 int nrg = 0,
689 counter,
690 str_offset;
691 position * coor;
692 char winpiece,
693 piece,
694 colour,
695 tempstr[80],
696 * strpos,
697 * start,
698 * end;
699 rem_gipf * gipf_ptr;
701 if ((oboard->rowextraw != NULL) &&
702 ((oboard->nextpiece == 'x') || (oboard->rowextrab == NULL)))
704 colour = 'o';
705 rowextra_o = oboard->rowextraw;
707 else if (oboard->rowextrab != NULL)
709 colour = 'x';
710 rowextra_o = oboard->rowextrab;
712 else
714 return (NULL);
717 row_ptr = (rem_row *) llitembynr (rowextra_o, rownr);
718 /* this shouldn't happen */
719 if (row_ptr == NULL)
721 return (NULL);
724 glist = (listheader *) malloc (sizeof (listheader));
725 newlist (glist);
726 nboard = b_copy (oboard);
727 if (nboard->gipfextra != NULL)
729 emptyll (nboard->gipfextra, del_rem_gipf);
730 free (nboard->gipfextra);
731 nboard->gipfextra = NULL;
734 nboard->status = S_NORMAL;
735 plist = row_ptr->piecelist;
736 winpiece = row_owner (row_ptr);
738 if (nboard->log)
740 start = postostr (row_start (row_ptr));
741 end = postostr (row_end (row_ptr));
742 sprintf (tempstr, "%c:%s:%s:", winpiece, start, end);
743 free (start);
744 free (end);
745 str_offset = 8;
748 counter = 1;
749 while ((coor = (position *) llitembynr (plist, counter)) != NULL)
751 counter++;
753 piece = nboard->pieces[coor->col][coor->row];
754 if ((piece == 'O') || (piece == 'X'))
756 nrg++;
757 gipf_ptr = new_rem_gipf ();
758 gipf_ptr->pos = (position *) copy_position ((void *) coor);
759 gipf_ptr->owner = winpiece;
760 pushll (glist, (void *) gipf_ptr);
761 continue;
764 if (nboard->log)
766 strpos = postostr (coor);
767 sprintf (tempstr + str_offset, "%2s%c:", strpos, piece);
768 free (strpos);
769 str_offset += 4;
772 if (piece == 'o')
774 if (piece == winpiece)
776 nboard->white++;
778 else
780 nboard->lostwhite++;
783 else
785 if (piece == winpiece)
787 nboard->black++;
789 else
791 nboard->lostblack++;
795 nboard->pieces[coor->col][coor->row] = '.';
798 if (nboard->log)
800 addtolog (nboard->log, LOGREMROW, tempstr);
803 #ifdef WINGIPF
804 if (nboard->removewait)
806 waitremrow (oboard, row_ptr, nboard);
808 #endif
811 ** remove the row that was just removed from rowextra
812 ** and check if the other rows are still complete
814 /* check white rowlist */
815 if (nboard->rowextraw != NULL)
817 /* check if all rows are still valid */
818 emptyll (nboard->rowextraw, del_rem_row);/* I now have an empty list */
820 counter = 1;
821 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextraw, counter))
822 != NULL)
824 counter++;
825 if ((colour == 'o') && ((counter - 1) == rownr))
827 continue;
829 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
831 pushll (nboard->rowextraw, n_row);
835 if (llitembynr (nboard->rowextraw, 1) == NULL)
837 free (nboard->rowextraw);
838 nboard->rowextraw = NULL;
842 /* check black rowlist */
843 if (nboard->rowextrab != NULL)
845 /* check if all rows are still valid */
847 emptyll (nboard->rowextrab, del_rem_row);/* I now have an empty list */
849 counter = 1;
850 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextrab, counter))
851 != NULL)
853 counter++;
854 if ((colour == 'x') && ((counter - 1) == rownr))
856 continue;
858 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
860 pushll (nboard->rowextrab, n_row);
864 if (llitembynr (nboard->rowextrab, 1) == NULL)
866 free (nboard->rowextrab);
867 nboard->rowextrab = NULL;
871 if ((nboard->rowextraw == NULL) && (nboard->rowextrab == NULL))
873 nboard->checkfour = 'n';
876 if (nrg != 0)
878 nboard->gipfextra = glist;
879 nboard->status = S_REMOVEGIPF;
880 return (nboard);
882 else if (nboard->checkfour == 'y')
884 free (glist);
885 new_board = b_checkfour (nboard);
886 b_del (nboard);
887 return (new_board);
889 else
891 free (glist);
892 return (nboard);
898 ** remove a gipf from the board and add the retrieved pieces to the
899 ** correct counter
901 ** parameters:
902 ** oboard: pointer to gipf-board
904 ** returns:
905 ** pointer to new board
906 ** NULL
908 board * b_remove_gipf (board * oboard, rem_gipf * rgipf)
910 board * nboard;
911 char piece,
912 winpiece,
913 tempstr[80],
914 * strpos;
915 rem_row * row_ptr,
916 * n_row;
917 int counter;
919 piece = oboard->pieces[rgipf->pos->col][rgipf->pos->row];
920 winpiece = b_otherpiece (rgipf->owner);
922 if ((piece != 'O') && (piece != 'X'))
924 return (NULL);
927 nboard = b_copy (oboard);
929 if (nboard->gipfextra != NULL)
931 emptyll (nboard->gipfextra, del_rem_gipf);
932 free (nboard->gipfextra);
933 nboard->gipfextra = NULL;
936 nboard->status = S_NORMAL;
938 nboard->pieces[rgipf->pos->col][rgipf->pos->row] = '.';
940 if (nboard->log)
942 strpos = postostr (rgipf->pos);
943 sprintf (tempstr, "%c:%2s%c", rgipf->owner, strpos, piece);
944 free (strpos);
945 addtolog (nboard->log, LOGREMGIPF, tempstr);
948 if (piece == 'O')
950 nboard->gipfwhite--;
951 if (piece == winpiece)
953 nboard->white += 2;
955 else
957 nboard->lostwhite += 2;
960 else
962 nboard->gipfblack--;
963 if (piece == winpiece)
965 nboard->black += 2;
967 else
969 nboard->lostblack += 2;
973 /* check white rowlist */
974 if (nboard->rowextraw != NULL)
976 /* check if all rows are still valid */
977 emptyll (nboard->rowextraw, del_rem_row);/* I now have an empty list */
979 counter = 1;
980 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextraw, counter))
981 != NULL)
983 counter++;
984 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
986 pushll (nboard->rowextraw, n_row);
990 if (llitembynr (nboard->rowextraw, 1) == NULL)
992 free (nboard->rowextraw);
993 nboard->rowextraw = NULL;
997 /* check black rowlist */
998 if (nboard->rowextrab != NULL)
1000 /* check if all rows are still valid */
1002 emptyll (nboard->rowextrab, del_rem_row);/* I now have an empty list */
1004 counter = 1;
1005 while ((row_ptr = (rem_row *) llitembynr (oboard->rowextrab, counter))
1006 != NULL)
1008 counter++;
1009 if ((n_row = b_rowoffour (nboard, row_ptr->rowindex)) != NULL)
1011 pushll (nboard->rowextrab, n_row);
1015 if (llitembynr (nboard->rowextrab, 1) == NULL)
1017 free (nboard->rowextrab);
1018 nboard->rowextrab = NULL;
1022 if ((nboard->rowextraw == NULL) && (nboard->rowextrab == NULL))
1024 nboard->checkfour = 'n';
1027 #ifdef WINGIPF
1028 if (nboard->removewait)
1030 waitremgipf (oboard, rgipf->pos, nboard);
1032 #endif
1034 return (nboard);
1039 ** b_checkfour: check for 4 in a row
1041 ** parameters:
1042 ** oboard: pointer to gipf-board
1044 ** returns:
1045 ** pointer to a new gipf-board
1047 board * b_checkfour (board * oboard)
1049 board * nboard,
1050 * new_board;
1051 int inrow4_w = 0,
1052 inrow4_b = 0,
1053 rownr,
1054 countrow,
1055 save_col,
1056 dir;
1057 listheader * row4list_w = NULL,
1058 * row4list_b = NULL;
1059 position base,
1060 next;
1061 char base_piece,
1062 base_piece2,
1063 piece;
1064 rem_row * rowp;
1066 if (oboard->checkfour == 'n')
1068 nboard = b_copy (oboard);
1069 nboard->status = S_NORMAL;
1070 return (nboard);
1072 if ((oboard->rowextraw != NULL) &&
1073 ((oboard->nextpiece == 'x') || (oboard->rowextrab == NULL)))
1075 if (llitembynr (oboard->rowextraw, 2) == NULL)
1077 nboard = b_remove_row (oboard, 1);
1078 return (nboard);
1080 else
1082 nboard = b_copy (oboard);
1083 nboard->status = S_REMOVEROW;
1084 return (nboard);
1087 else if (oboard->rowextrab != NULL)
1089 if (llitembynr (oboard->rowextrab, 2) == NULL)
1091 nboard = b_remove_row (oboard, 1);
1092 return (nboard);
1094 else
1096 nboard = b_copy (oboard);
1097 nboard->status = S_REMOVEROW;
1098 return (nboard);
1102 /* base = new_position ();
1103 next = new_position ();*/
1105 for (rownr=0; rownr<21; rownr++)
1107 base.col = rowlist[rownr][0];
1108 base.row = rowlist[rownr][1];
1110 if (oboard->pieces[base.col][base.row] == '.')
1112 continue;
1115 countrow = 1;
1117 base_piece = oboard->pieces[base.col][base.row];
1118 base_piece2 = b_otherpiece (base_piece);
1120 /* first direction */
1121 dir = rowlist[rownr][2];
1123 /* next.col = base.col;
1124 next.row = base.row;
1126 save_col = next.col;
1127 next.col = b_buren[save_col][next.row][dir][0];
1128 next.row = b_buren[save_col][next.row][dir][1];*/
1129 next.col = b_buren[base.col][base.row][dir][0];
1130 next.row = b_buren[base.col][base.row][dir][1];
1132 piece = oboard->pieces[next.col][next.row];
1133 while ((next.col != 0) && (piece != '.'))
1135 if ((piece == base_piece) || (piece == base_piece2))
1137 countrow++;
1139 else
1141 break;
1143 save_col = next.col;
1144 next.col = b_buren[save_col][next.row][dir][0];
1145 next.row = b_buren[save_col][next.row][dir][1];
1147 piece = oboard->pieces[next.col][next.row];
1150 if (countrow < rowlist[rownr][4])
1151 { /* not possible to get 4 in a row anymore */
1152 continue;
1155 /* second direction */
1156 /*dir = rowlist[rownr][3];*/
1157 dir = 5 - dir;
1159 /* next.col = base.col;
1160 next.row = base.row;
1162 save_col = next.col;
1163 next.col = b_buren[save_col][next.row][dir][0];
1164 next.row = b_buren[save_col][next.row][dir][1];*/
1165 next.col = b_buren[base.col][base.row][dir][0];
1166 next.row = b_buren[base.col][base.row][dir][1];
1168 piece = oboard->pieces[next.col][next.row];
1169 while ((next.col != 0) && (piece != '.'))
1171 if ((piece == base_piece) || (piece == base_piece2))
1173 countrow++;
1175 else
1177 break;
1179 save_col = next.col;
1180 next.col = b_buren[save_col][next.row][dir][0];
1181 next.row = b_buren[save_col][next.row][dir][1];
1183 piece = oboard->pieces[next.col][next.row];
1186 if (countrow > 3)
1188 rowp = b_rowoffour (oboard, rownr);
1190 if ((base_piece == 'o') || (base_piece == 'O'))
1192 inrow4_w++;
1193 if (row4list_w == NULL)
1195 row4list_w = (listheader *) malloc (sizeof (listheader));
1196 newlist (row4list_w);
1198 pushll (row4list_w, rowp);
1200 else
1202 inrow4_b++;
1203 if (row4list_b == NULL)
1205 row4list_b = (listheader *) malloc (sizeof (listheader));
1206 newlist (row4list_b);
1208 pushll (row4list_b, rowp);
1213 /* del_position (base);
1214 del_position (next);*/
1216 nboard = b_copy (oboard);
1218 if (inrow4_w != 0)
1220 nboard->rowextraw = row4list_w;
1222 if (inrow4_b != 0)
1224 nboard->rowextrab = row4list_b;
1227 if ((inrow4_w == 0) && (inrow4_b == 0))
1229 nboard->status = S_NORMAL;
1230 nboard->checkfour = 'n';
1231 return (nboard);
1233 if ((nboard->rowextraw != NULL) &&
1234 ((nboard->nextpiece == 'x') || (nboard->rowextrab == NULL)))
1236 if (inrow4_w == 1)
1238 new_board = b_remove_row (nboard, 1);
1239 b_del (nboard);
1240 return (new_board);
1242 else
1244 nboard->status = S_REMOVEROW;
1245 return (nboard);
1248 else
1250 if (inrow4_b == 1)
1252 new_board = b_remove_row (nboard, 1);
1253 b_del (nboard);
1254 return (new_board);
1256 else
1258 nboard->status = S_REMOVEROW;
1259 return (nboard);
1266 ** b_rowoffour: check if a certain row has four in a row
1268 ** parameters:
1269 ** oboard: pointer to gipf-board
1270 ** rownr: nr of row in rowlist
1272 ** returns:
1273 ** pointer to rem_row-structure
1274 ** NULL (if no 4 in a row found)
1276 rem_row * b_rowoffour (board * oboard, int rownr)
1278 int countrow,
1279 dir,
1280 save_col,
1281 count;
1282 listheader * temprow;
1283 position * start,
1284 * end,
1285 * base,
1286 * next;
1287 char base_piece,
1288 base_piece2,
1289 piece;
1290 rem_row * rowp;
1292 temprow = (listheader *) malloc (sizeof (listheader));
1293 newlist (temprow);
1294 countrow = 1;
1296 base = new_position();
1297 base->col = rowlist[rownr][0];
1298 base->row = rowlist[rownr][1];
1299 start = (position *) copy_position ((void *) base);
1300 end = (position *) copy_position ((void *) base);
1301 next = (position *) copy_position ((void *) base);
1303 if (oboard->pieces[base->col][base->row] == '.')
1305 /* cleanup */
1306 free (temprow);
1307 del_position ((void *) base);
1308 del_position ((void *) start);
1309 del_position ((void *) end);
1310 del_position ((void *) next);
1311 return (NULL);
1314 base_piece = oboard->pieces[base->col][base->row];
1315 base_piece2 = b_otherpiece (base_piece);
1316 pushll (temprow, copy_position ((void *) base));
1318 /* first direction */
1319 dir = rowlist[rownr][2];
1321 count = 1;
1322 /* b_moveto (next, col_dif, &row_dif);*/
1323 save_col = next->col;
1324 next->col = b_buren[save_col][next->row][dir][0];
1325 next->row = b_buren[save_col][next->row][dir][1];
1327 piece = oboard->pieces[next->col][next->row];
1328 while ((next->col != 0) && (piece != '.'))
1330 pushll (temprow, copy_position ((void *) next));
1331 if ((count == 1) &&
1332 ((piece == base_piece) || (piece == base_piece2)))
1334 countrow++;
1335 start->col = next->col;
1336 start->row = next->row;
1338 else
1340 count = 0;
1342 /* b_moveto (next, col_dif, &row_dif);*/
1343 save_col = next->col;
1344 next->col = b_buren[save_col][next->row][dir][0];
1345 next->row = b_buren[save_col][next->row][dir][1];
1347 piece = oboard->pieces[next->col][next->row];
1350 /* second direction */
1351 /*dir = rowlist[rownr][3];*/
1352 dir = 5 - dir;
1354 next->col = base->col;
1355 next->row = base->row;
1357 count = 1;
1358 /* b_moveto (next, col_dif, &row_dif);*/
1359 save_col = next->col;
1360 next->col = b_buren[save_col][next->row][dir][0];
1361 next->row = b_buren[save_col][next->row][dir][1];
1363 piece = oboard->pieces[next->col][next->row];
1364 while ((next->col != 0) && (piece != '.'))
1366 pushll (temprow, copy_position ((void *) next));
1367 if ((count == 1) &&
1368 ((piece == base_piece) || (piece == base_piece2)))
1370 countrow++;
1371 end->col = next->col;
1372 end->row = next->row;
1374 else
1376 count = 0;
1378 /* b_moveto (next, col_dif, &row_dif);*/
1379 save_col = next->col;
1380 next->col = b_buren[save_col][next->row][dir][0];
1381 next->row = b_buren[save_col][next->row][dir][1];
1383 piece = oboard->pieces[next->col][next->row];
1386 if (countrow > 3)
1388 rowp = new_rem_row ();
1389 rowp->startpos = start;
1390 rowp->endpos = end;
1391 rowp->piecelist = temprow;
1392 rowp->rowindex = rownr;
1393 if ((base_piece == 'o') || (base_piece == 'x'))
1395 rowp->owner = base_piece;
1397 else
1399 rowp->owner = base_piece2;
1402 else
1404 emptyll (temprow, del_position_f);
1405 free (temprow);
1406 del_position (start);
1407 del_position (end);
1408 rowp = NULL;
1410 del_position (base);
1411 del_position (next);
1413 return (rowp);
1416 #if 0
1418 ** b_moveto: give coor of new position
1420 ** parameters:
1421 ** pos: startpos, endpos after run
1422 ** col_dif: column difference
1423 ** row_dif: row difference
1425 inline void b_moveto (position * pos, int col_dif, int * row_dif)
1427 if (col_dif != 0)
1429 if (pos->col == 4)
1431 (*row_dif)--;
1433 pos->col += col_dif;
1436 pos->row += (*row_dif);
1437 if ((pos->col == 0) ||
1438 (pos->col == 8) ||
1439 (pos->row < 2) ||
1440 (pos->row > b_colsize(pos->col)))
1442 pos->col = 0;
1443 pos->row = 0;
1445 return;
1450 ** b_colour: return the number of available pieces for a colour
1452 ** parameters:
1453 ** oboard : pointer to gipf-board
1454 ** colour : o, O, x, X
1456 ** returns:
1457 ** nr of pieces
1459 int b_colour (board * oboard, char colour)
1461 if ((colour == 'o') || (colour == 'O'))
1463 return (oboard->white);
1465 else if ((colour == 'x') || (colour == 'X'))
1467 return (oboard->black);
1469 return (-1);
1474 ** b_colour_gipf: return the number of gipfpieces for a colour
1476 ** parameters:
1477 ** oboard : pointer to gipf-board
1478 ** colour : o, O, x, X
1480 ** returns:
1481 ** nr of pieces
1483 int b_colour_gipf (board * oboard, char colour)
1485 if ((colour == 'o') || (colour == 'O'))
1487 return (oboard->gipfwhite);
1489 else if ((colour == 'x') || (colour == 'X'))
1491 return (oboard->gipfblack);
1493 return (-1);
1498 ** b_colour_lost: return the number of lost pieces for a colour
1500 ** parameters:
1501 ** oboard : pointer to gipf-board
1502 ** colour : o, O, x, X
1504 ** returns:
1505 ** nr of pieces
1507 int b_colour_lost (board * oboard, char colour)
1509 if ((colour == 'o') || (colour == 'O'))
1511 return (oboard->lostwhite);
1513 else if ((colour == 'x') || (colour == 'X'))
1515 return (oboard->lostblack);
1517 return (-1);
1522 ** b_colour_type: return the type of pieces this colour can place
1524 ** parameters:
1525 ** oboard : pointer to gipf-board
1526 ** colour : o, O, x, X
1528 ** returns:
1529 ** n or g
1531 char b_colour_type (board * oboard, char colour)
1533 if ((colour == 'o') || (colour == 'O'))
1535 return (oboard->typewhite);
1537 else if ((colour == 'x') || (colour == 'X'))
1539 return (oboard->typeblack);
1541 return (' ');
1543 #endif
1546 ** b_piece: return piece at position
1548 ** parameters:
1549 ** oboard: pointer to gipf-board
1550 ** pos: position-string (ex. b4)
1552 ** returns:
1553 ** piece
1555 char b_piece (board * oboard, char * strpos)
1557 position * pos;
1558 char piece;
1560 pos = strtopos (strpos);
1561 piece = oboard->pieces[pos->col][pos->row];
1562 del_position (pos);
1564 return (piece);
1569 ** b_game_finished : check if game is finished
1571 ** parameters:
1572 ** oboard: gipf-board
1574 ** returns:
1575 ** 0: game not finished
1576 ** 1: game finished
1578 ** REMARK: only do this if no more rows can be removed from the board
1580 int b_game_finished (board * oboard)
1583 ** check if a player has no gipf-pieces left
1584 ** but only do this at the second move
1586 if ((oboard->movecounter > 0) &&
1587 (oboard->gipfwhite == 0))
1589 oboard->status = S_FINISHED;
1590 oboard->winner = 'x';
1591 return (1);
1594 if (((oboard->movecounter > 1) ||
1595 ((oboard->nextpiece == 'o') && (oboard->movecounter == 1))) &&
1596 (oboard->gipfblack == 0))
1598 oboard->status = S_FINISHED;
1599 oboard->winner = 'o';
1600 return (1);
1603 /* check if the next player has pieces left */
1604 if (b_colour (oboard, oboard->nextpiece) == 0)
1606 oboard->status = S_FINISHED;
1607 oboard->winner = b_opponent (oboard->nextpiece);
1608 return (1);
1611 return (0);
1616 ** b_compare: compare the contents of 2 gipf-boards
1618 ** parameters:
1619 ** board1
1620 ** board2
1622 ** returns:
1623 ** 0: equal
1624 ** 1: different
1626 int b_compare (board * board1, board * board2)
1628 int i,
1631 /* sanity check */
1632 if ((board1 == NULL) || (board2 == NULL))
1634 return (1);
1637 /* compare the different counters */
1638 if ((board1->nextpiece != board2->nextpiece) ||
1639 (board1->movecounter != board2->movecounter) ||
1640 (board1->white != board2->white) ||
1641 (board1->lostwhite != board2->lostwhite) ||
1642 (board1->gipfwhite != board2->gipfwhite) ||
1643 (board1->typewhite != board2->typewhite) ||
1644 (board1->black != board2->black) ||
1645 (board1->lostblack != board2->lostblack) ||
1646 (board1->gipfblack != board2->gipfblack) ||
1647 (board1->typeblack != board2->typeblack))
1649 return (1);
1652 #define MEMCMP 1
1653 #ifndef MEMCMP
1654 /* compare board-contents */
1655 for (i = 1; i < 8; i++)
1656 for (j = 2; j <= b_colsize (i); j++)
1657 if (board1->pieces[i][j] != board2->pieces[i][j])
1658 return (1);
1659 #else
1660 if (memcmp (&(board1->pieces), &(board2->pieces), 72) != 0)
1662 return (1);
1664 #endif
1666 return (0);
1670 listheader * b_row_extra (board * oboard)
1672 if ((oboard->rowextraw != NULL) &&
1673 ((oboard->nextpiece == 'x') || (oboard->rowextrab == NULL)))
1675 return (oboard->rowextraw);
1677 else
1679 return (oboard->rowextrab);
1685 ** replace the piece at position 'pos' with 'piece'
1686 ** try to adapt the counters
1688 ** returns:
1689 ** NULL: error
1691 board * b_edit_piece (board * oboard, position * pos, char piece)
1693 board * nboard;
1695 nboard = b_copy (oboard);
1697 if (nboard->pieces[pos->col][pos->row] == piece)
1699 return (nboard);
1702 /* remove piece */
1703 switch (nboard->pieces[pos->col][pos->row])
1705 case 'o':
1706 nboard->white += 1;
1707 break;
1708 case 'O':
1709 nboard->white += 2;
1710 nboard->gipfwhite -= 1;
1711 break;
1712 case 'x':
1713 nboard->black += 1;
1714 break;
1715 case 'X':
1716 nboard->black += 2;
1717 nboard->gipfblack -= 1;
1718 break;
1719 default:
1720 break;
1723 /* add piece */
1724 switch (piece)
1726 case 'o':
1727 if (nboard->white == 0)
1729 b_del (nboard);
1730 return (NULL);
1732 nboard->white -= 1;
1733 break;
1734 case 'O':
1735 if (nboard->white < 2)
1737 b_del (nboard);
1738 return (NULL);
1740 nboard->white -= 2;
1741 nboard->gipfwhite += 1;
1742 break;
1743 case 'x':
1744 if (nboard->black == 0)
1746 b_del (nboard);
1747 return (NULL);
1749 nboard->black -= 1;
1750 break;
1751 case 'X':
1752 if (nboard->black < 2)
1754 b_del (nboard);
1755 return (NULL);
1757 nboard->black -= 2;
1758 nboard->gipfblack += 1;
1759 break;
1760 default:
1761 break;
1764 nboard->pieces[pos->col][pos->row] = piece;
1766 return (nboard);
1770 board * b_edit_lostwhite (board * oboard, int newval)
1772 board * nboard;
1774 if ((oboard->white + oboard->lostwhite - newval) < 0)
1776 return (NULL);
1779 nboard = b_copy (oboard);
1780 nboard->white = nboard->white + nboard->lostwhite - newval;
1781 nboard->lostwhite = newval;
1783 return (nboard);
1787 board * b_edit_lostblack (board * oboard, int newval)
1789 board * nboard;
1791 if ((oboard->black + oboard->lostblack - newval) < 0)
1793 return (NULL);
1796 nboard = b_copy (oboard);
1797 nboard->black = nboard->black + nboard->lostblack - newval;
1798 nboard->lostblack = newval;
1800 return (nboard);
1805 ** write a boardsituation to a file
1806 ** use a format that can be read by b_from_file
1807 ** (should also be readable by gipfdraw, so you can easily
1808 ** make gif's from a board-position)
1810 ** returns -1 on failure, otherwise 0
1812 ** REMARK: the board must be in a stable state (S_NORMAL or S_FINISHED)
1813 ** otherwise the save will fail
1815 int b_to_file (board * oboard, FILE * fp)
1817 int i, j;
1818 position * temppos;
1819 char * tempstr;
1821 if (oboard == NULL)
1822 return (-1);
1824 if ((oboard->status != S_NORMAL) && (oboard->status != S_FINISHED))
1826 return (-1);
1829 fprintf (fp, "whitepieces:%d\n", oboard->white);
1830 fprintf (fp, "whitelost:%d\n", oboard->lostwhite);
1832 fprintf (fp, "blackpieces:%d\n", oboard->black);
1833 fprintf (fp, "blacklost:%d\n", oboard->lostblack);
1835 fprintf (fp, "nextplayer:%c\n", oboard->nextpiece);
1837 temppos = (position *) malloc (sizeof (position));
1838 for (i = 1; i < 8; i++)
1840 temppos->col = i;
1841 for (j = 2; j <= b_colsize (i); j++)
1843 temppos->row = j;
1844 if (b_ppiece (oboard, temppos) != '.')
1846 tempstr = postostr (temppos);
1847 fprintf (fp, "%c:%2s\n",
1848 b_ppiece (oboard, temppos), tempstr);
1849 free (tempstr);
1853 free (temppos);
1855 fprintf (fp, "# end of board\n");
1857 return (0);
1862 ** read a boardsituation from a file and store it in a
1863 ** board-structure.
1865 ** returns NULL on failure
1867 board * b_from_file (FILE * fp)
1869 char buffer[100]="",
1870 tempchar,
1871 tempstr[100];
1872 board * nboard;
1873 int tempnr;
1874 position * temppos;
1876 nboard = b_new (T_TOURNAMENT);
1877 nboard->typewhite = 'n';
1878 nboard->typeblack = 'n';
1880 while (strncmp (buffer, "# end of board", 14) != 0)
1882 if (fgets (buffer, 100, fp) == NULL)
1884 b_del (nboard);
1885 return (NULL);
1888 if (sscanf (buffer, "whitepieces:%d", &tempnr) == 1)
1890 nboard->white = tempnr;
1892 else if (sscanf (buffer, "whitelost:%d", &tempnr) == 1)
1894 nboard->lostwhite = tempnr;
1896 else if (sscanf (buffer, "blackpieces:%d", &tempnr) == 1)
1898 nboard->black = tempnr;
1900 else if (sscanf (buffer, "blacklost:%d", &tempnr) == 1)
1902 nboard->lostblack = tempnr;
1904 else if (sscanf (buffer, "nextplayer:%c", &tempchar) == 1)
1906 nboard->nextpiece = tempchar;
1908 else if (sscanf (buffer, "%c:%s", &tempchar, tempstr) == 2)
1910 temppos = strtopos (tempstr);
1911 nboard->pieces[temppos->col][temppos->row] = tempchar;
1912 switch (tempchar)
1914 case 'O':
1915 nboard->gipfwhite += 1;
1916 break;
1917 case 'X':
1918 nboard->gipfblack += 1;
1919 break;
1921 del_position (temppos);
1925 if ((nboard->gipfwhite == 0) && (nboard->gipfblack == 0))
1927 nboard->gipfwhite = -1;
1928 nboard->gipfblack = -1;
1931 return (nboard);