1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2006 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #define PGN_TIME_FORMAT "%Y.%m.%d"
24 #define VALIDRANK VALIDFILE
25 #define VALIDFILE(f) (f >= 1 && f <= 8)
26 #define ROWTOBOARD(r) (8 - r)
27 #define COLTOBOARD(c) (c - 1)
28 #define ROWTOINT(r) (r - '0')
29 #define COLTOINT(c) (c - ('a' - 1))
30 #define VALIDROW(r) (r >= '1' && r <= '8')
31 #define VALIDCOL(c) (c >= 'a' && c <= 'h')
33 #define SET_FLAG(var, f) (var |= f)
34 #define CLEAR_FLAG(var, f) (var &= ~(f))
35 #define TOGGLE_FLAG(var, f) (var ^= (f))
36 #define TEST_FLAG(var, f) (var & f)
39 OPEN_SQUARE
, PAWN
, BISHOP
, ROOK
, KNIGHT
, QUEEN
, KING
, MAX_PIECES
47 TAG_EVENT
, TAG_SITE
, TAG_DATE
, TAG_ROUND
, TAG_WHITE
, TAG_BLACK
, TAG_RESULT
51 #define GF_PERROR 0x01 /* Parse error for this game. */
52 #define GF_DELETE 0x02 /* Flagged for deletion ('x' command). */
53 #define GF_MODIFIED 0x04 /* Modified tags or history. */
54 #define GF_ENPASSANT 0x08 /* For En Passant validation. */
55 #define GF_GAMEOVER 0x010 /* End of game. */
56 #define GF_WK_CASTLE 0x020
57 #define GF_WQ_CASTLE 0x040
58 #define GF_BK_CASTLE 0x080
59 #define GF_BQ_CASTLE 0x0100
60 #define GF_BLACK_OPENING 0x0200
66 unsigned char icon
; // The piece.
67 unsigned char valid
: 1, // != 0 if this square is a valid move for the
69 enpassant
: 1; // This square is an en passant one.
76 char *name
; // Tag name.
77 char *value
; // Tag value.
83 * g.hp is the pointer to the current history which may be .rav for
84 * Recursive Annotated Variations. The depth of recursion is kept track of in
87 typedef struct history
{
88 char *move
; // The SAN move text.
89 char *comment
; // Annotation for this move.
90 unsigned char nag
[MAX_PGN_NAG
]; // Numeric Annotation Glyph. FIXME
91 struct history
**rav
; // Variation of the current move.
95 * Keeps game state history for the root move.
98 char *fen
; // Game board state.
100 unsigned char hindex
;
101 HISTORY
**hp
; // Pointer to the root move.
105 * This is an array of 'games' structures. One for each game in a file, or
108 typedef struct games
{
109 BOARD b
; // The board associated with this game.
110 TAG
**tag
; // Roster tags.
111 HISTORY
**history
; // Move history for this game.
112 HISTORY
**hp
; // History pointer pointing to the location
113 // in *history used mainly for RAV.
114 RAV
*rav
; // Saved game states for the root move of RAV.
115 int ravlevel
; // An index to *rav.
116 unsigned char hindex
; // Current move in *hp.
117 unsigned moveclock
; // Move clock. FIXME
118 unsigned short flags
; // Game flags.
119 unsigned char castle
: 2, // The current move is a castling move. FIXME
120 side
: 1, // This playing side. BLACK or WHITE.
121 turn
: 1, // BLACK or WHITE.
122 mode
: 2; // MODE_[HISTORY/EDIT/PLAY]
123 unsigned char ply
; // Move count.
124 void *data
; /* User data associated with this game. Must
125 * be freed by the user. */
133 * When pgn_write() is called to write a game, write reduced PGN format.
134 * This will only write the seven tag roster and move text skipping any
140 * The number of full moves to write per line. If 0 then pgn_write() will
141 * write as many as possible within 80 columns.
146 * Normally when a parse error occurs in a game the game is flagged with
147 * GF_PERROR and the rest of the game is discarded and processing of the
148 * next game is done. When set and a parse error occurs the rest of the
149 * entire file will be discarded.
155 * Set game flags. See chess.h for available flags.
157 int pgn_config_set(pgn_config_flag f
, int val
);
160 * Returns the value accociated with 'f' or -1 if 'f' is invalid.
162 int pgn_config_get(pgn_config_flag f
);
165 * Converts the character piece 'p' to an integer.
167 int pgn_piece_to_int(int p
);
170 * Converts the integer piece 'n' to a character whose turn is 'turn'. WHITE
171 * piece are uppercase and BLACK pieces are lowercase.
173 int pgn_int_to_piece(char turn
, int n
);
176 * Returns the total number of tags in 't' or 0 if 't' is NULL.
178 int pgn_tag_total(TAG
**t
);
181 * Finds a tag 'name' in the structure array 't'. Returns the location in the
182 * array of the found tag or -1 on failure.
184 int pgn_find_tag(TAG
**t
, const char *name
);
187 * Sorts a tag array. The first seven tags are in order of the PGN standard so
190 void pgn_sort_tags(TAG
**t
);
193 * Adds a tag 'name' with value 'value' to the pointer to array of TAG
194 * pointers 'dst'. If a duplicate tag 'name' was found then the existing tag
195 * is updated to the new 'value'. Returns 1 if a duplicate tag was found or 0
198 int pgn_add_tag(TAG
***dst
, char *name
, char *value
);
201 * Resets or initializes a new game board 'b'.
203 void pgn_init_board(BOARD b
);
206 * This is called at the EOG marker and the beginning of the move text
207 * section. So at least a move or EOG marker has to exist. It initializes the
208 * board (b) to the FEN tag (if found) and sets the castling and enpassant
209 * info for the game 'g'. If 'fen' is set it should be a fen tag and will be
210 * parsed rather than the game 'g'.tag FEN tag. Returns 0 on success or if
211 * there was both a FEN and SetUp tag with the SetUp tag set to 0. Returns 1
212 * if there was a FEN parse error or no FEN tag at all.
214 int pgn_init_fen_board(GAME
*g
, BOARD b
, char *fen
);
217 * Creates a FEN tag from the current game 'g' and board 'b'. Returns a FEN
220 char *pgn_game_to_fen(GAME g
, BOARD b
);
223 * Allocates a new game and increments gindex (the current game) and gtotal
224 * (the total number of games).
229 * Returns a file pointer associated with 'filename' or NULL on error with
230 * errno set to indicate the error. If compressed file support was enabled at
231 * compile time and the filetype is supported and the utility is installed
232 * then the file will be decompressed.
234 FILE *pgn_open(const char *filename
);
237 * Parses a file whose file pointer is 'fp'. 'fp' may have been returned by
238 * pgn_open(). If 'fp' is NULL then a single empty game will be allocated. If
239 * there is a parsing error 1 is returned otherwise 0 is returned and the
240 * global 'gindex' is set to the last parsed game in the file and the global
241 * 'gtotal' is set to the total number of games in the file. The file will be
242 * closed when the parsing is done.
244 int pgn_parse(FILE *fp
);
247 * Writes a PGN formatted game 'g' to the file pointed to by 'fp'. Returns 1
248 * if the written move count doesn't match the game's ply count (FEN tag) or 0
251 void pgn_write(FILE *fp
, GAME g
);
254 * Returns 1 if 'filename' is a recognized compressed filetype or 0 if not.
256 int pgn_is_compressed(const char *filename
);
259 * Returns the total number of moves in 'h' or 0 if none.
261 int history_total(HISTORY
**h
);
264 * Deallocates the all the data for 'h' from position 'start' in the array.
266 void history_free(HISTORY
**h
, int start
);
269 * Returns the history ply 'n' from 'h'. If 'n' is out of range then NULL is
272 HISTORY
*history_by_n(HISTORY
**h
, int n
);
275 * Appends move 'm' to game 'g' history pointer. The history pointer may be a
276 * in a RAV so g->rav.hp is also updated to the new (realloc()'ed) pointer. If
277 * not in a RAV then g->history will be updated. Returns 1 if realloc() failed
280 int history_add(GAME
*g
, const char *m
);
283 * Resets the game 'g' using board 'b' up to history move 'n'.
285 int history_update_board(GAME
*g
, BOARD b
, int n
);
288 * Updates the game 'g' using board 'b' to the next 'n'th history move.
290 void history_previous(GAME
*g
, BOARD b
, int n
);
293 * Updates the game 'g' using board 'b' to the previous 'n'th history move.
295 void history_next(GAME
*g
, BOARD b
, int n
);
297 int pgn_validate_move(GAME
*g
, BOARD b
, char *m
);
299 void pgn_switch_turn(GAME
*);
300 char *pgn_a2a4tosan(GAME
*g
, BOARD b
, char *m
);
301 void board_reset_valid_moves(BOARD b
);
302 void board_get_valid_moves(GAME
*g
, BOARD b
, int p
, int srow
, int scol
, int *minr
, int *maxr
, int *minc
, int *maxc
);
303 void pgn_free_all(void);
305 void pgn_tag_free(TAG
**);
306 void pgn_reset_enpassant(BOARD b
);