No longer send SIGINT to the engine before each command.
[cboard.git] / libchess / chess.h
blob2773d21c01d44b4852a0eb24a3ad276f923b053c
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2002-2007 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
19 #ifndef CHESS_H
20 #define CHESS_H
22 #define PGN_TIME_FORMAT "%Y.%m.%d"
23 #define MAX_PGN_LINE_LEN 255
24 #define MAX_SAN_MOVE_LEN 7
25 #define MAX_PGN_NAG 8
27 #define VALIDRANK VALIDFILE
28 #define VALIDFILE(f) (f >= 1 && f <= 8)
29 #define RANKTOBOARD(r) (8 - r)
30 #define FILETOBOARD(c) (c - 1)
31 #define RANKTOINT(r) (r - '0')
32 #define FILETOINT(c) (c - ('a' - 1))
33 #define VALIDROW(r) (r >= '1' && r <= '8')
34 #define VALIDCOL(c) (c >= 'a' && c <= 'h')
35 #define INTTORANK(r) (r + '0')
36 #define INTTOFILE(f) (f + ('a' - 1))
38 #define SET_FLAG(var, f) (var |= f)
39 #define CLEAR_FLAG(var, f) (var &= ~(f))
40 #define TOGGLE_FLAG(var, f) (var ^= (f))
41 #define TEST_FLAG(var, f) (var & f)
43 enum {
44 OPEN_SQUARE, PAWN, BISHOP, ROOK, KNIGHT, QUEEN, KING
47 enum {
48 WHITE, BLACK
51 /* Game flags. */
52 #define GF_PERROR 0x01 /* Parse error for this game. */
53 #define GF_ENPASSANT 0x02 /* For En Passant validation. */
54 #define GF_GAMEOVER 0x04 /* End of game. */
55 #define GF_WK_CASTLE 0x08
56 #define GF_WQ_CASTLE 0x010
57 #define GF_BK_CASTLE 0x020
58 #define GF_BQ_CASTLE 0x040
59 #define GF_BLACK_OPENING 0x080
62 * The chess board.
64 typedef struct {
65 unsigned char icon; // The piece.
66 unsigned char valid: 1, // != 0 if this square is a valid move for the
67 // selected piece.
68 enpassant: 1;
69 } BOARD[8][8];
72 * PGN Roster tags.
74 typedef struct tags {
75 char *name; // Tag name.
76 char *value; // Tag value.
77 } TAG;
80 * Move history.
82 * g.hp is the pointer to the current history which may be .rav for
83 * Recursive Annotated Variations. The depth of recursion is kept track of in
84 * g.ravlevel.
86 typedef struct history {
87 char *move; // The SAN move text.
88 char *comment; // Annotation for this move.
89 unsigned char nag[MAX_PGN_NAG]; // Numeric Annotation Glyph.
90 struct history **rav; // Variation of the current move.
91 } HISTORY;
94 * Keeps game state history for the root move.
96 typedef struct {
97 char *fen; // Game board state.
98 unsigned short flags;
99 unsigned short hindex;
100 HISTORY **hp; // Pointer to the root move.
101 } RAV;
104 * This is an array of 'games' structures. One for each game in a file, or
105 * the current game.
107 typedef struct game_s {
108 TAG **tag; // Roster tags.
109 HISTORY **history; // Move history for this game.
110 HISTORY **hp; // History pointer pointing to the location
111 // in *history used mainly for RAV.
112 RAV *rav; // Saved game states for the root move of RAV.
113 int ravlevel; // An index to *rav.
114 unsigned short hindex; // Current move in *hp.
115 unsigned short flags; // Game flags.
116 unsigned short oflags; // Game flags for the previous move.
117 unsigned char side: 1, // This playing side. BLACK or WHITE.
118 turn: 1; // BLACK or WHITE.
119 unsigned short ply; // Move count.
120 void *data; /* User data associated with this game. Must
121 * be freed by the user. */
122 } *GAME;
125 * Global GAME array. pgn_new_game() appends to this array.
127 GAME *game;
130 * 'gindex' and 'gtotal' are the current and total number of games in 'game'.
132 int gindex, gtotal;
135 * Library configuration flags. These will affect all games.
137 typedef enum {
139 * When pgn_write() is called to write a game, write reduced PGN format.
140 * This will only write the seven tag roster and move text skipping any
141 * annotation. The type for this flag is an int.
143 PGN_REDUCED,
146 * The number of full moves to write per line. If 0 then pgn_write() will
147 * write as many as possible within 80 columns. The type for this flag
148 * is an int.
150 PGN_MPL,
153 * Normally when a parse error occurs in a game the game is flagged with
154 * GF_PERROR and the rest of the game is discarded and processing of the
155 * next game is done. When set and a parse error occurs the rest of the
156 * entire file will be discarded. The type for this flag is an int.
158 PGN_STOP_ON_ERROR,
160 #ifdef DEBUG
162 * If the following is set to a value > 0 and DEBUG was defined
163 * at compile time then debugging output will be written to
164 * "libchess.debug" in the current directory.
166 PGN_DEBUG,
167 #endif
170 * After PGN_PROGRESS amount of bytes have been read from a file, call
171 * PGN_PROGRESS_FUNC. The type for PGN_PROGRESS is a long.
172 * PGN_PROGRESS_FUNC is of type pgn_progress.
174 PGN_PROGRESS,
175 PGN_PROGRESS_FUNC,
178 * If set to 1 and an opponent can attack a castling square the castling
179 * move will not be a valid one.
181 PGN_STRICT_CASTLING,
182 } pgn_config_flag;
185 * Errors returned from the following functions.
187 typedef enum {
188 E_PGN_ERR = -1,
189 E_PGN_OK,
190 E_PGN_PARSE,
191 E_PGN_AMBIGUOUS,
192 E_PGN_INVALID
193 } pgn_error_t;
195 typedef struct {
196 FILE *fp;
197 char *filename;
198 char *tmpfile; /* For appending. */
199 int pipe;
200 } PGN_FILE;
203 * The prototype of the PGN_PROGRESS_FUNC function pointer.
205 typedef void (pgn_progress)(long size, long offset);
208 * Sets config flag 'f' to the next argument. Returns E_PGN_OK on success or
209 * E_PGN_ERR if 'f' is an invalid flag or E_PGN_INVALID if 'val' is an invalid
210 * flag value.
212 pgn_error_t pgn_config_set(pgn_config_flag f, ...);
215 * Gets the value of config flag 'f'. The next argument should be a pointer of
216 * the config type which is set to the value of 'f'. Returns E_PGN_ERR if 'f'
217 * is an invalid flag or E_PGN_OK on success.
219 pgn_error_t pgn_config_get(pgn_config_flag f, ...);
222 * Returns E_PGN_OK if 'filename' is a recognized compressed filetype or
223 * E_PGN_ERR if not.
225 pgn_error_t pgn_is_compressed(const char *filename);
228 * Opens a file 'filename' with the given 'mode'. 'mode' should be "r" for
229 * reading, "w" for writing (will truncate if the file exists) or "a" for
230 * appending to an existing file or creating a new one. Returns E_PGN_OK on
231 * success and sets 'result' to a file handle for use will the other file
232 * functions or E_PGN_ERR if there is an error opening the file in which case
233 * errno will be set to the error or E_PGN_INVALID if 'mode' is an invalid
234 * mode or if 'filename' is not a regular file.
236 pgn_error_t pgn_open(const char *filename, const char *mode, PGN_FILE **result);
239 * Closes and free's a PGN file handle. Returns E_PGN_OK on success,
240 * E_PGN_INVALID if 'pgn' is NULL, or E_PGN_ERR if rename() failed.
242 pgn_error_t pgn_close(PGN_FILE *pgn);
245 * Parses a PGN_FILE which was opened with pgn_open(). If 'pgn' is NULL then a
246 * single empty game will be allocated. If there is a parsing error
247 * E_PGN_PARSE is returned, if there was a memory allocation error E_PGN_ERR
248 * is returned, otherwise E_PGN_OK is returned and the global 'gindex' is set
249 * to the last parsed game in the file and the global 'gtotal' is set to the
250 * total number of games in the file. The file should be closed with
251 * pgn_close() after processing.
253 pgn_error_t pgn_parse(PGN_FILE *pgn);
256 * Allocates a new game and increments 'gtotal'. 'gindex' is then set to the
257 * new game. Returns E_PGN_ERR if there was a memory allocation error or
258 * E_PGN_OK on success.
260 pgn_error_t pgn_new_game();
263 * Writes a PGN formatted game 'g' to a file which was opened with pgn_open().
264 * See 'pgn_config_flag' for output options. Returns E_PGN_ERR if there was a
265 * memory allocation or write error and E_PGN_OK on success.
267 pgn_error_t pgn_write(PGN_FILE *pgn, GAME g);
270 * Frees all games in the global 'game' array. Returns nothing.
272 void pgn_free_all(void);
275 * Frees a single game 'g'. Returns nothing.
277 void pgn_free(GAME g);
280 * Adds a tag 'name' with value 'value' to the pointer to array of TAG
281 * pointers 'dst'. If a duplicate tag 'name' was found then the existing tag
282 * is updated to the new 'value'. If 'value' is NULL, the tag is removed.
283 * Returns E_PGN_ERR if there was a memory allocation error or E_PGN_OK on
284 * success.
286 pgn_error_t pgn_tag_add(TAG ***dst, char *name, char *value);
289 * Returns the total number of tags in 't' or 0 if 't' is NULL.
291 int pgn_tag_total(TAG **t);
294 * Finds a tag 'name' in the structure array 't'. Returns the location in the
295 * array of the found tag or E_PGN_ERR if the tag could not be found.
297 pgn_error_t pgn_tag_find(TAG **t, const char *name);
300 * Sorts a tag array. The first seven tags are in order of the PGN standard so
301 * don't sort'em. Returns nothing.
303 void pgn_tag_sort(TAG **t);
306 * Frees a TAG array. Returns nothing.
308 void pgn_tag_free(TAG **);
311 * It initializes the board (b) to the FEN tag (if found) and sets the
312 * castling and enpassant info for the game 'g'. If 'fen' is set it should be
313 * a fen tag and will be parsed rather than the game 'g'.tag FEN tag. Returns
314 * E_PGN_OK on success or if there was both a FEN and SetUp tag with the SetUp
315 * tag set to 0. Returns E_PGN_PARSE if there was a FEN parse error, E_PGN_ERR
316 * if there was no FEN tag or there was a SetUp tag with a value of 0. Returns
317 * E_PGN_OK on success.
319 pgn_error_t pgn_board_init_fen(GAME g, BOARD b, char *fen);
322 * Creates a FEN tag from the current game 'g', history move (g.hindex) and
323 * board 'b'. Returns a FEN tag.
325 char *pgn_game_to_fen(GAME g, BOARD b);
328 * Resets or initializes a new game board 'b'. Returns nothing.
330 void pgn_board_init(BOARD b);
333 * Valididate move 'm' against the game state 'g' and game board 'b' and
334 * update board 'b'. 'm' is ensured to be in SAN format and 'frfr' will the
335 * file/rank representation of 'm'. Returns E_PGN_PARSE if there was a move
336 * text parsing error, E_PGN_INVALID if the move is invalid, E_PGN_AMBIGUOUS
337 * if the move is invalid with ambiguities or E_PGN_OK if successful.
339 pgn_error_t pgn_parse_move(GAME g, BOARD b, char **m, char **frfr);
342 * Like pgn_parse_move() but don't modify game flags in 'g' or board 'b'.
344 pgn_error_t pgn_validate_move(GAME g, BOARD b, char **m, char **frfr);
347 * Returns the total number of moves in 'h' or 0 if there are none.
349 int pgn_history_total(HISTORY **h);
352 * Returns the history ply 'n' from 'h'. If 'n' is out of range then NULL is
353 * returned.
355 HISTORY *pgn_history_by_n(HISTORY **h, int n);
358 * Appends move 'm' to game 'g' history pointer. The history pointer may be a
359 * in a RAV so g->rav.hp is also updated to the new (realloc()'ed) pointer. If
360 * not in a RAV then g->history will be updated. Returns E_PGN_ERR if
361 * realloc() failed or E_PGN_OK on success.
363 pgn_error_t pgn_history_add(GAME g, const char *m);
366 * Deallocates all of the history data from position 'start' in the array 'h'.
367 * Returns nothing.
369 void pgn_history_free(HISTORY **h, int start);
372 * Resets the game 'g' using board 'b' up to history move (g.hindex) 'n'.
373 * Returns E_PGN_OK on success or E_PGN_PARSE if there was a FEN tag but the
374 * parsing of it failed. Or returns E_PGN_INVALID if somehow the move failed
375 * validation while resetting.
377 pgn_error_t pgn_board_update(GAME g, BOARD b, int n);
380 * Updates the game 'g' using board 'b' to the next 'n'th history move.
381 * Returns nothing.
383 void pgn_history_prev(GAME g, BOARD b, int n);
386 * Updates the game 'g' using board 'b' to the previous 'n'th history move.
387 * Returns nothing.
389 void pgn_history_next(GAME g, BOARD b, int n);
392 * Converts the character piece 'p' to an integer. Returns the integer
393 * associated with 'p' or E_PGN_ERR if 'p' is invalid.
395 int pgn_piece_to_int(int p);
398 * Converts the integer piece 'n' to a character whose turn is 'turn'. WHITE
399 * piece are uppercase and BLACK pieces are lowercase. Returns the character
400 * associated with 'n' or E_PGN_ERR if 'n' is an invalid piece.
402 pgn_error_t pgn_int_to_piece(char turn, int n);
405 * Toggles g->turn. Returns nothing.
407 void pgn_switch_turn(GAME);
410 * Toggles g->side and switches the White and Black roster tags. Returns
411 * nothing.
413 void pgn_switch_side(GAME g);
416 * Clears the enpassant flag for all positions on board 'b'. Returns nothing.
418 void pgn_reset_enpassant(BOARD b);
421 * Clears the valid move flag for all positions on board 'b'. Returns nothing.
423 void pgn_reset_valid_moves(BOARD b);
426 * Sets valid moves (b.valid) from game 'g' using board 'b'. The valid moves
427 * are for the piece on the board 'b' at 'rank' and 'file'. Returns nothing.
429 void pgn_find_valid_moves(GAME g, BOARD b, int rank, int file);
432 * Returns the version string of the library.
434 char *pgn_version(void);
436 #endif