4 ** a lot of things for dealing with the log from a gipf-game
7 ** Copyright (C) 1998 Kurt Van den Branden
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License as published by
11 ** the Free Software Foundation; either version 2 of the License, or
12 ** (at your option) any later version.
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 ** create a new, empty log structure
35 ** type: gametype (string)
36 ** wname: name of the player with white
37 ** bname: name of the player with black
39 gamelog
* newlog (char * type
, char * wname
, char * bname
)
43 log
= (gamelog
*) malloc (sizeof (gamelog
));
44 log
->gametype
= strdup (type
);
45 log
->whitename
= strdup (wname
);
46 log
->blackname
= strdup (bname
);
48 log
->moves
= (listheader
*) malloc (sizeof (listheader
));
56 ** delete a complete gamelog structure
58 void deletelog (gamelog
* log
)
64 free (log
->whitename
);
65 free (log
->blackname
);
67 while ((item
= (logitem
*) llrembynr (log
->moves
, 1)) != NULL
)
69 if (item
->plist
!= NULL
)
71 while ((pos
= (char *) llrembynr (item
->plist
, 1)) != NULL
)
88 ** the contents of 'data' depend on 'type'
89 ** LOGMOVE: <piece>:<from>:<last moved piece>
90 ** LOGREMGIPF: <gipfowner>:<gipf position><piece>
91 ** LOGREMROW: <rowowner>:<rowstart>:<rowend>:[<piece position><piece>:]...
92 ** (remark: the data for LOGREMROW must end on ':')
94 int addtolog (gamelog
* log
, int type
, char * data
)
103 item
= (logitem
*) malloc (sizeof (logitem
));
110 if (sscanf (data
, "%c:%2s:%2s", &piece
, start
, end
) != 3)
117 if (sscanf (data
, "%c:%3s", &piece
, pos
) != 2)
122 item
->plist
= (listheader
*) malloc (sizeof (listheader
));
123 newlist (item
->plist
);
124 pushll (item
->plist
, (void *) strdup (pos
));
127 if (sscanf (data
, "%c:%2s:%2s:", &piece
, start
, end
) != 3)
132 item
->plist
= (listheader
*) malloc (sizeof (listheader
));
133 newlist (item
->plist
);
135 while (kar
[0] != '\0')
137 strncpy (pos
, kar
, 3);
138 pushll (item
->plist
, (void *) strdup (pos
));
143 item
->player
= piece
;
144 strcpy (item
->start
, start
);
145 strcpy (item
->end
, end
);
147 pushll (log
->moves
, (void *) item
);
153 ** write contents of a gamelog-structure to a file
156 ** log: gamelog structure
157 ** fp: pointer to an open file
159 int logtofile (gamelog
* log
, FILE * fp
)
171 fprintf (fp
, "game: %s\n", log
->gametype
);
172 fprintf (fp
, "white player: %s\n", log
->whitename
);
173 fprintf (fp
, "black player: %s\n", log
->blackname
);
174 fprintf (fp
, "\nmoves:\n");
176 while ((item
= (logitem
*) llitembynr (log
->moves
, counter
)) != NULL
)
183 fprintf (fp
, "%c: %s-%s\n", item
->player
, item
->start
, item
->end
);
186 pos
= (char *) llitembynr (item
->plist
, 1);
187 fprintf (fp
, " %c removegipf: %s\n", item
->player
, pos
);
190 fprintf (fp
, " %c removerow (%s-%s):", item
->player
,
191 item
->start
, item
->end
);
193 while ((pos
= (char *) llitembynr (item
->plist
, counter2
)) != NULL
)
196 fprintf (fp
, " %s", pos
);
204 fprintf (fp
, "end of gamelog\n");
211 ** read log from a file and put it in a gamelog-structure
212 ** (the layout must be the same as written by logtofile)
214 ** the inputfile must already be open and should be at the first
215 ** line from the gamelog
217 gamelog
* logfromfile (FILE * fp
)
231 if (fgets (buffer
, 100, fp
) == NULL
)
233 buffer
[strlen(buffer
)-1] = '\0';
234 if (strncmp (buffer
, "game: ", 6) != 0)
236 strcpy (type
, buffer
+6);
238 if (fgets (buffer
, 100, fp
) == NULL
)
240 buffer
[strlen(buffer
)-1] = '\0';
241 if (strncmp (buffer
, "white player: ", 14) != 0)
243 strcpy (wname
, buffer
+14);
245 if (fgets (buffer
, 100, fp
) == NULL
)
247 buffer
[strlen(buffer
)-1] = '\0';
248 if (strncmp (buffer
, "black player: ", 14) != 0)
250 strcpy (bname
, buffer
+14);
252 log
= newlog (type
, wname
, bname
);
254 fgets (buffer
, 100, fp
);
255 fgets (buffer
, 100, fp
);
259 if (fgets (buffer
, 100, fp
) == NULL
)
264 if (strncmp (buffer
, "end of gamelog", 14) == 0)
267 item
= (logitem
*) malloc (sizeof (logitem
));
270 if (sscanf (buffer
, "%c: %2s-%2s", &piece
, start
, end
) == 3)
272 item
->type
= LOGMOVE
;
274 else if (sscanf (buffer
, " %c removegipf: %3s", &piece
, pos
) == 2)
276 item
->type
= LOGREMGIPF
;
277 item
->plist
= (listheader
*) malloc (sizeof (listheader
));
278 newlist (item
->plist
);
279 pushll (item
->plist
, (void *) strdup (pos
));
281 else if (sscanf (buffer
, " %c removerow (%2s-%2s):",
282 &piece
, start
, end
) == 3)
284 item
->type
= LOGREMROW
;
285 item
->plist
= (listheader
*) malloc (sizeof (listheader
));
286 newlist (item
->plist
);
289 kar
= strchr (buffer
, ':');
293 while (isspace ((int) kar
[0]))
295 if (sscanf (kar
, "%3s", pos
) != 1)
297 pushll (item
->plist
, (void *) strdup (pos
));
301 item
->player
= piece
;
302 strcpy (item
->start
, start
);
303 strcpy (item
->end
, end
);
305 pushll (log
->moves
, (void *) item
);
313 ** take the contents of a gamelog-structure and format it in
314 ** a nice way to show in an fltk browser-widget
316 ** this function returs a list of lines that can be sent to the
317 ** widget without change
319 ** !! don't forget to cleanup the list !!
321 listheader
* logtobrowser (gamelog
* log
)
325 whitepieces
[50] = "",
326 blackpieces
[50] = "",
334 lines
= (listheader
*) malloc (sizeof (listheader
));
337 newline
= (char *) malloc (40); /* is 40 always enough ? */
338 sprintf (newline
, "@b%s", log
->gametype
);
339 pushll (lines
, newline
);
340 newline
= (char *) malloc (1);
342 pushll (lines
, newline
);
344 newline
= (char *) malloc (40); /* is 40 always enough ? */
345 sprintf (newline
, "@iwhite: %s", log
->whitename
);
346 pushll (lines
, newline
);
347 newline
= (char *) malloc (40); /* is 40 always enough ? */
348 sprintf (newline
, "@iblack: %s", log
->blackname
);
349 pushll (lines
, newline
);
350 newline
= (char *) malloc (1);
352 pushll (lines
, newline
);
354 while ((item
= (logitem
*) llitembynr (log
->moves
, count
)) != NULL
)
358 if ((owner
!= ' ') &&
359 ((item
->type
== LOGMOVE
) || (item
->type
== LOGREMROW
)))
361 newline
= (char *) malloc (50); /* is 50 enough ? */
363 sprintf (newline
, "@s w: %sx %s",
364 whitepieces
, blackpieces
);
366 sprintf (newline
, "@s b: %sx %s",
367 blackpieces
, whitepieces
);
369 pushll (lines
, newline
);
372 whitepieces
[0] = '\0';
373 blackpieces
[0] = '\0';
376 if (item
->type
== LOGMOVE
)
378 if ((movecounter
% 2) == 0)
379 { /* need to show the nr of the move here */
380 newline
= (char *) malloc (40); /* is 40 always enough ? */
381 sprintf (newline
, "@c@b%d", movecounter
/2 + 1);
382 pushll (lines
, newline
);
386 newline
= (char *) malloc (40); /* is 40 always enough ? */
387 if (tolower (item
->player
) == 'o')
388 sprintf (newline
, "white: ");
390 sprintf (newline
, "black: ");
392 if ((item
->player
== 'O') || (item
->player
== 'X'))
393 sprintf (newline
+ 7, "G");
395 sprintf (newline
+ strlen (newline
), "%2s-%2s",
396 item
->start
, item
->end
);
398 pushll (lines
, newline
);
400 else if (item
->type
== LOGREMGIPF
)
402 tempstr
= (char *) llitembynr (item
->plist
, 1);
403 if (tolower (tempstr
[2]) == 'o')
404 sprintf (whitepieces
+ strlen (whitepieces
), "G%2.2s ",
407 sprintf (blackpieces
+ strlen (blackpieces
), "G%2.2s ",
410 else /* must be LOGREMROW now */
413 owner
= tolower (item
->player
);
415 while ((tempstr
= (char *) llitembynr (item
->plist
, count2
))
419 if (tolower (tempstr
[2]) == 'o')
420 sprintf (whitepieces
+ strlen (whitepieces
), "%2.2s ",
423 sprintf (blackpieces
+ strlen (blackpieces
), "%2.2s ",
431 newline
= (char *) malloc (50); /* is 50 enough ? */
433 sprintf (newline
, "@s w: %sx %s",
434 whitepieces
, blackpieces
);
436 sprintf (newline
, "@s b: %sx %s",
437 blackpieces
, whitepieces
);
439 pushll (lines
, newline
);
447 ** return 1 if this logitem represents a move
449 int isamove (void * data
)
451 logitem
* item
= data
;
453 if (item
->type
== LOGMOVE
)
461 ** remove the last move from a gamelog
462 ** (include all the removerows and removegipfs)
466 ** number of items removed from the log
468 int remlastmove (gamelog
* log
)
475 if ((nr
= findlastll (log
->moves
, isamove
)) == 0)
480 /* delete everything from the last move to the end of the list */
481 while ((item
= (logitem
*) llrembynr (log
->moves
, nr
)) != NULL
)
483 if (item
->plist
!= NULL
)
485 while ((pos
= (char *) llrembynr (item
->plist
, 1)) != NULL
)